node/lib/internal/modules/esm/create_dynamic_module.js
Joyee Cheung 80c0b89bbb
module: initialize module_wrap.callbackMap during pre-execution
Since the bootstrap does not actually use ESM at all, there
is no need to create this map so early. This patch moves
the initialization of the map to pre-execution,
so that the only binding loaded in loaders is native_module.
In addition, switch to SafeWeakMap.

PR-URL: https://github.com/nodejs/node/pull/27323
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
2019-04-25 12:11:10 +08:00

56 lines
1.3 KiB
JavaScript

'use strict';
const { ArrayPrototype } = primordials;
const debug = require('internal/util/debuglog').debuglog('esm');
const createDynamicModule = (exports, url = '', evaluate) => {
debug('creating ESM facade for %s with exports: %j', url, exports);
const names = ArrayPrototype.map(exports, (name) => `${name}`);
const source = `
${ArrayPrototype.join(ArrayPrototype.map(names, (name) =>
`let $${name};
export { $${name} as ${name} };
import.meta.exports.${name} = {
get: () => $${name},
set: (v) => $${name} = v,
};`), '\n')
}
import.meta.done();
`;
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const m = new ModuleWrap(source, `${url}`);
m.link(() => 0);
m.instantiate();
const readyfns = new Set();
const reflect = {
namespace: m.namespace(),
exports: {},
onReady: (cb) => { readyfns.add(cb); },
};
callbackMap.set(m, {
initializeImportMeta: (meta, wrap) => {
meta.exports = reflect.exports;
meta.done = () => {
evaluate(reflect);
reflect.onReady = (cb) => cb(reflect);
for (const fn of readyfns) {
readyfns.delete(fn);
fn(reflect);
}
};
},
});
return {
module: m,
reflect,
};
};
module.exports = createDynamicModule;