Skip to content

Commit a03b5d3

Browse files
joyeecheungaduh95
authored andcommitted
lib: reduce cycles in esm loader and load it in snapshot
PR-URL: #61769 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Jacob Smith <jacob@frende.me>
1 parent 1017bf5 commit a03b5d3

File tree

5 files changed

+22
-50
lines changed

5 files changed

+22
-50
lines changed

lib/internal/bootstrap/switches/is_main_thread.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ require('util');
296296
require('url'); // eslint-disable-line no-restricted-modules
297297
internalBinding('module_wrap');
298298
require('internal/modules/cjs/loader');
299+
require('internal/modules/esm/loader');
299300
require('internal/modules/esm/utils');
300301

301302
// Needed to refresh the time origin.

lib/internal/modules/esm/loader.js

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const {
6262
loadWithHooks: loadWithSyncHooks,
6363
validateLoadSloppy,
6464
} = require('internal/modules/customization_hooks');
65-
let defaultResolve, defaultLoadSync, importMetaInitializer;
65+
let importMetaInitializer;
6666

6767
const { tracingChannel } = require('diagnostics_channel');
6868
const onImport = tracingChannel('module.import');
@@ -97,19 +97,9 @@ function newLoadCache() {
9797
return new LoadCache();
9898
}
9999

100-
let _translators;
101-
function lazyLoadTranslators() {
102-
_translators ??= require('internal/modules/esm/translators');
103-
return _translators;
104-
}
105-
106-
/**
107-
* Lazy-load translators to avoid potentially unnecessary work at startup (ex if ESM is not used).
108-
* @returns {import('./translators.js').Translators}
109-
*/
110-
function getTranslators() {
111-
return lazyLoadTranslators().translators;
112-
}
100+
const { translators } = require('internal/modules/esm/translators');
101+
const { defaultResolve } = require('internal/modules/esm/resolve');
102+
const { defaultLoadSync, throwUnknownModuleFormat } = require('internal/modules/esm/load');
113103

114104
/**
115105
* Generate message about potential race condition caused by requiring a cached module that has started
@@ -178,18 +168,6 @@ class ModuleLoader {
178168
*/
179169
loadCache = newLoadCache();
180170

181-
/**
182-
* Methods which translate input code or other information into ES modules
183-
*/
184-
translators = getTranslators();
185-
186-
/**
187-
* Truthy to allow the use of `import.meta.resolve`. This is needed
188-
* currently because the `Hooks` class does not have `resolveSync`
189-
* implemented and `import.meta.resolve` requires it.
190-
*/
191-
allowImportMetaResolve;
192-
193171
/**
194172
* @see {AsyncLoaderHooks.isForAsyncLoaderHookWorker}
195173
* Shortcut to this.#asyncLoaderHooks.isForAsyncLoaderHookWorker.
@@ -464,7 +442,7 @@ class ModuleLoader {
464442
#translate(url, translateContext, parentURL) {
465443
const { translatorKey, format } = translateContext;
466444
this.validateLoadResult(url, format);
467-
const translator = getTranslators().get(translatorKey);
445+
const translator = translators.get(translatorKey);
468446

469447
if (!translator) {
470448
throw new ERR_UNKNOWN_MODULE_FORMAT(translatorKey, url);
@@ -715,7 +693,7 @@ class ModuleLoader {
715693
if (cachedResult != null) {
716694
return cachedResult;
717695
}
718-
defaultResolve ??= require('internal/modules/esm/resolve').defaultResolve;
696+
719697
const result = defaultResolve(specifier, context);
720698
this.#resolveCache.set(requestKey, parentURL, result);
721699
return result;
@@ -792,7 +770,6 @@ class ModuleLoader {
792770
if (this.#asyncLoaderHooks?.loadSync) {
793771
return this.#asyncLoaderHooks.loadSync(url, context);
794772
}
795-
defaultLoadSync ??= require('internal/modules/esm/load').defaultLoadSync;
796773
return defaultLoadSync(url, context);
797774
}
798775

@@ -818,7 +795,7 @@ class ModuleLoader {
818795

819796
validateLoadResult(url, format) {
820797
if (format == null) {
821-
require('internal/modules/esm/load').throwUnknownModuleFormat(url, format);
798+
throwUnknownModuleFormat(url, format);
822799
}
823800
}
824801

lib/internal/modules/esm/resolve.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ const {
4646
ERR_UNSUPPORTED_DIR_IMPORT,
4747
ERR_UNSUPPORTED_RESOLVE_REQUEST,
4848
} = require('internal/errors').codes;
49-
50-
const { Module: CJSModule } = require('internal/modules/cjs/loader');
49+
const { defaultGetFormatWithoutErrors } = require('internal/modules/esm/get_format');
5150
const { getConditionsSet } = require('internal/modules/esm/utils');
5251
const packageJsonReader = require('internal/modules/package_json_reader');
5352
const internalFsBinding = internalBinding('fs');
@@ -870,6 +869,7 @@ function moduleResolve(specifier, base, conditions, preserveSymlinks) {
870869
*/
871870
function resolveAsCommonJS(specifier, parentURL) {
872871
try {
872+
const { Module: CJSModule } = require('internal/modules/cjs/loader');
873873
const parent = fileURLToPath(parentURL);
874874
const tmpModule = new CJSModule(parent, null);
875875
tmpModule.paths = CJSModule._nodeModulePaths(parent);
@@ -1043,8 +1043,3 @@ module.exports = {
10431043
packageResolve,
10441044
throwIfInvalidParentURL,
10451045
};
1046-
1047-
// cycle
1048-
const {
1049-
defaultGetFormatWithoutErrors,
1050-
} = require('internal/modules/esm/get_format');

lib/internal/modules/esm/translators.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const {
1414
StringPrototypeReplaceAll,
1515
StringPrototypeSlice,
1616
StringPrototypeStartsWith,
17-
globalThis: { WebAssembly },
17+
globalThis,
1818
} = primordials;
1919

2020
const {
@@ -58,16 +58,7 @@ const { maybeCacheSourceMap } = require('internal/source_map/source_map_cache');
5858
const moduleWrap = internalBinding('module_wrap');
5959
const { ModuleWrap, kEvaluationPhase } = moduleWrap;
6060

61-
// Lazy-loading to avoid circular dependencies.
62-
let getSourceSync;
63-
/**
64-
* @param {Parameters<typeof import('./load').getSourceSync>[0]} url
65-
* @returns {ReturnType<typeof import('./load').getSourceSync>}
66-
*/
67-
function getSource(url) {
68-
getSourceSync ??= require('internal/modules/esm/load').getSourceSync;
69-
return getSourceSync(url);
70-
}
61+
const { getSourceSync } = require('internal/modules/esm/load');
7162

7263
const { parse: cjsParse } = internalBinding('cjs_lexer');
7364

@@ -209,7 +200,7 @@ function createCJSModuleWrap(url, translateContext, parentURL, loadCJS = loadCJS
209200
const isMain = (parentURL === undefined);
210201
const filename = urlToFilename(url);
211202
// In case the source was not provided by the `load` step, we need fetch it now.
212-
source = stringify(source ?? getSource(new URL(url)).source);
203+
source = stringify(source ?? getSourceSync(new URL(url)).source);
213204

214205
const { exportNames, module } = cjsPreparseModuleExports(filename, source, sourceFormat);
215206
cjsCache.set(url, module);
@@ -515,6 +506,8 @@ translators.set('json', function jsonStrategy(url, translateContext) {
515506
const wasmInstances = new SafeWeakMap();
516507
translators.set('wasm', function(url, translateContext) {
517508
const { source } = translateContext;
509+
// WebAssembly global is not available during snapshot building, so we need to get it lazily.
510+
const { WebAssembly } = globalThis;
518511
assertBufferSource(source, false, 'load');
519512

520513
debug(`Translating WASMModule ${url}`, translateContext);

test/parallel/test-bootstrap-modules.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,23 @@ expected.beforePreExec = new Set([
115115
'NativeModule internal/modules/run_main',
116116
'NativeModule internal/net',
117117
'NativeModule internal/dns/utils',
118+
'NativeModule internal/modules/esm/get_format',
118119
]);
119120

120121
expected.atRunTime = new Set([
121-
'NativeModule internal/modules/esm/get_format',
122122
'NativeModule internal/process/pre_execution',
123123
]);
124124

125125
const { isMainThread } = require('worker_threads');
126126

127127
if (isMainThread) {
128128
[
129+
'Internal Binding cjs_lexer',
130+
'NativeModule internal/modules/esm/assert',
131+
'NativeModule internal/modules/esm/loader',
132+
'NativeModule internal/modules/esm/load',
133+
'NativeModule internal/modules/esm/resolve',
134+
'NativeModule internal/modules/esm/translators',
129135
'NativeModule url',
130136
].forEach(expected.beforePreExec.add.bind(expected.beforePreExec));
131137
} else { // Worker.

0 commit comments

Comments
 (0)