55 lines
1.4 KiB
TypeScript
55 lines
1.4 KiB
TypeScript
import { dirname } from "path"
|
|
import glob from "fast-glob"
|
|
import type { types } from "@babel/core"
|
|
import type { BabelPlugin } from "./esbuild-babel"
|
|
|
|
const skip = new WeakSet<types.CallExpression>()
|
|
|
|
export const dynamicImport =
|
|
(filePath: string): BabelPlugin =>
|
|
({ types: t }) => ({
|
|
name: "dynamic-import",
|
|
visitor: {
|
|
Import(path) {
|
|
if (
|
|
!t.isCallExpression(path.parent) ||
|
|
path.parent.arguments.length !== 1 ||
|
|
skip.has(path.parent)
|
|
) {
|
|
return
|
|
}
|
|
|
|
const [arg] = path.parent.arguments
|
|
if (!t.isTemplateLiteral(arg)) {
|
|
return
|
|
}
|
|
|
|
const key = path.scope.generateDeclaredUidIdentifier("key")
|
|
|
|
const globText = arg.quasis.map(x => x.value.raw).join("*")
|
|
const globCandidates = glob.sync(globText, {
|
|
cwd: dirname(filePath),
|
|
})
|
|
|
|
const clone = t.cloneNode(path.parent, true)
|
|
skip.add(clone)
|
|
|
|
const cond = globCandidates.reduceRight(
|
|
(accum: types.Expression, cur) =>
|
|
t.conditionalExpression(
|
|
t.binaryExpression("===", key, t.stringLiteral(cur)),
|
|
t.callExpression(t.import(), [t.stringLiteral(cur)]),
|
|
accum,
|
|
),
|
|
clone,
|
|
)
|
|
|
|
t.cloneNode(path.parent)
|
|
|
|
path.parentPath.replaceWith(
|
|
t.sequenceExpression([t.assignmentExpression("=", key, arg), cond]),
|
|
)
|
|
},
|
|
},
|
|
})
|