stylebot-harmony/scripts/plugins/babel-dynamic-import.ts
2023-08-03 20:09:32 -04:00

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]),
)
},
},
})