|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | | -const { ModuleWrap } = internalBinding('module_wrap'); |
| 3 | +const { ModuleWrap, callbackMap } = internalBinding('module_wrap'); |
4 | 4 | const debug = require('util').debuglog('esm'); |
5 | 5 | const ArrayJoin = Function.call.bind(Array.prototype.join); |
6 | 6 | const ArrayMap = Function.call.bind(Array.prototype.map); |
7 | 7 |
|
| 8 | +const defaultName = '\u5343\u4e07\u4e0d\u8981\u7528\u8fd9\u4e2a\u53d8\u91cf' + |
| 9 | + '\u5426\u5219\u4f60\u4f1a\u88ab\u5f00\u9664'; |
| 10 | + |
8 | 11 | const createDynamicModule = (exports, url = '', evaluate) => { |
9 | 12 | debug( |
10 | 13 | `creating ESM facade for ${url} with exports: ${ArrayJoin(exports, ', ')}` |
11 | 14 | ); |
12 | 15 | const names = ArrayMap(exports, (name) => `${name}`); |
13 | | - // Create two modules: One whose exports are get- and set-able ('reflective'), |
14 | | - // and one which re-exports all of these but additionally may |
15 | | - // run an executor function once everything is set up. |
16 | | - const src = ` |
17 | | - export let executor; |
18 | | - ${ArrayJoin(ArrayMap(names, (name) => `export let $${name};`), '\n')} |
19 | | - /* This function is implicitly returned as the module's completion value */ |
20 | | - (() => ({ |
21 | | - setExecutor: fn => executor = fn, |
22 | | - reflect: { |
23 | | - exports: { ${ |
24 | | - ArrayJoin(ArrayMap(names, (name) => ` |
25 | | - ${name}: { |
26 | | - get: () => $${name}, |
27 | | - set: v => $${name} = v |
28 | | - }`), ', \n')} |
29 | | - } |
| 16 | + |
| 17 | + const source = ` |
| 18 | +${ArrayJoin(ArrayMap(names, (name) => { |
| 19 | + if (name === 'default') { |
| 20 | + return `let ${defaultName}; |
| 21 | +export { ${defaultName} as default }; |
| 22 | +import.meta.exports.default = { |
| 23 | + get: () => ${defaultName}, |
| 24 | + set: ($${defaultName}) => ${defaultName} = $${defaultName}, |
| 25 | +}; |
| 26 | +`; |
| 27 | + } else { |
| 28 | + return `export let ${name}; |
| 29 | +import.meta.exports.${name} = { |
| 30 | + get: () => ${name}, |
| 31 | + set: ($${name}) => ${name} = $${name}, |
| 32 | +};`; |
30 | 33 | } |
31 | | - }));`; |
32 | | - const reflectiveModule = new ModuleWrap(src, `cjs-facade:${url}`); |
33 | | - reflectiveModule.instantiate(); |
34 | | - const { setExecutor, reflect } = reflectiveModule.evaluate(-1, false)(); |
35 | | - // public exposed ESM |
36 | | - const reexports = ` |
37 | | - import { |
38 | | - executor, |
39 | | - ${ArrayMap(names, (name) => `$${name}`)} |
40 | | - } from ""; |
41 | | - export { |
42 | | - ${ArrayJoin(ArrayMap(names, (name) => `$${name} as ${name}`), ', ')} |
43 | | - } |
44 | | - if (typeof executor === "function") { |
45 | | - // add await to this later if top level await comes along |
46 | | - executor() |
47 | | - }`; |
48 | | - if (typeof evaluate === 'function') { |
49 | | - setExecutor(() => evaluate(reflect)); |
50 | | - } |
51 | | - const module = new ModuleWrap(reexports, `${url}`); |
52 | | - module.link(async () => reflectiveModule); |
53 | | - module.instantiate(); |
54 | | - reflect.namespace = module.namespace(); |
| 34 | + }), '\n')} |
| 35 | +
|
| 36 | +import.meta.done(); |
| 37 | +`; |
| 38 | + |
| 39 | + const m = new ModuleWrap(source, `${url}`); |
| 40 | + m.link(() => 0); |
| 41 | + m.instantiate(); |
| 42 | + |
| 43 | + const reflect = { |
| 44 | + namespace: m.namespace, |
| 45 | + exports: {}, |
| 46 | + }; |
| 47 | + |
| 48 | + callbackMap.set(m, { |
| 49 | + initializeImportMeta: (meta, wrap) => { |
| 50 | + meta.exports = reflect.exports; |
| 51 | + meta.done = () => evaluate(reflect); |
| 52 | + }, |
| 53 | + }); |
| 54 | + |
55 | 55 | return { |
56 | | - module, |
| 56 | + module: m, |
57 | 57 | reflect, |
58 | 58 | }; |
59 | 59 | }; |
|
0 commit comments