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