Created
November 9, 2025 08:21
-
-
Save mk-pmb/c3d4ef29c120687c984f7ced05ea0957 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* For browsers that don't understand import statements, the | |
| `preferDynamicImport` transform replaces them with dynamic import. | |
| The pseudo-code transpiler rule below explains the strategy. | |
| It's unrealistic to aim for that level of correctness with regexps, | |
| and in this project, simplicity wins over perfect accuracy. (If you | |
| want correctness, use babel.) | |
| Nonetheless, it' still useful to have a clear concept of what the | |
| theoretically ideal goal would be, to ensure a clear understanding | |
| of tbe trade-offs we make. | |
| * Example use case: You can feed the pseudo-code to an AI and let it | |
| explain why we can simply transplant the `ObjectBindingPattern` | |
| (destructuring expression, stored as "unpack") verbatim. (Always | |
| fact-check AI though! DO NOT report any AI counter-examples as bug | |
| unless you have verified them in node.js or Firefox!) | |
| Caveats inherent in the strategy, i.e. that would be unavoidable even | |
| with all the complexity of the rule below: | |
| * Only available for AMD output, because the module factory needs to | |
| await the loader's promise. | |
| * Mixed import statements are out of project scope. Just avoid them. | |
| * If your imported module does not have the exports you want, the original | |
| code would fail immediately, but the transpiled code may silently import | |
| undefined instead. Use a linter to verify your imports. | |
| * If an imported module uses its exported identifiers in strange ways | |
| (e.g. export a getter, or reassign the exported identifiers at runtime), | |
| the imported thing may become outdated, because an destructuring | |
| assignment is not a real name binding. Just avoid such unstable modules. | |
| * Don't use computed property names in your `ObjectBindingPattern`. | |
| */ | |
| export default { | |
| name: 'preferDynamicImport', | |
| supportedOutputFormats: ['amd_iife_define'], | |
| applicable: a => ( | |
| (a.inputSourceType === 'esmodule') | |
| && (a.outputScope === 'asyncModuleFactory') | |
| ), | |
| match: m => [ | |
| m.state('inputSourceScope')['===']('toplevel'), | |
| m.literalToken('import'), | |
| m.tokenBorder(), | |
| m.or([ | |
| m.identifier().storeAs('name'), | |
| m.opportunisticLookahead().greedy().failAt( | |
| m.endOfStatement(), // abort early if there was no "from" | |
| ).storeAs('unpack'), | |
| ]), | |
| m.tokenBorder(), | |
| m.literalToken('from'), | |
| m.tokenBorder(), | |
| m.stringLiteral().storeAs('url'), | |
| m.endOfStatement(), | |
| ], | |
| replace: r => [ | |
| r.verbatim('const '), | |
| () => (r.stored('name') || r.stored('unpack')), | |
| r.verbatim(' = await import('), | |
| r.resolveUrl(r.stored('url')), | |
| r.verbatim(')'), | |
| () => (r.stored('name') && r.verbatim('.default')), | |
| r.verbatim(';\n'), | |
| ], | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment