mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 00:20:08 +01:00
esm: link modules synchronously when no async loader hooks are used
When no async loader hooks are registered, perform the linking as synchronously as possible to reduce the chance of races from the the shared module loading cache. PR-URL: https://github.com/nodejs/node/pull/59519 Fixes: https://github.com/nodejs/node/issues/59366 Refs: https://github.com/abejfehr/node-22.18-issue-repro Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
parent
db70ceb49f
commit
7535aa1f72
|
|
@ -65,6 +65,8 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
|
|||
debug = fn;
|
||||
});
|
||||
|
||||
const { isPromise } = require('internal/util/types');
|
||||
|
||||
/**
|
||||
* @typedef {import('./hooks.js').HooksProxy} HooksProxy
|
||||
* @typedef {import('./module_job.js').ModuleJobBase} ModuleJobBase
|
||||
|
|
@ -592,15 +594,21 @@ class ModuleLoader {
|
|||
|
||||
/**
|
||||
* Load a module and translate it into a ModuleWrap for ordinary imported ESM.
|
||||
* This is run asynchronously.
|
||||
* This may be run asynchronously if there are asynchronous module loader hooks registered.
|
||||
* @param {string} url URL of the module to be translated.
|
||||
* @param {object} loadContext See {@link load}
|
||||
* @param {boolean} isMain Whether the module to be translated is the entry point.
|
||||
* @returns {Promise<ModuleWrap>}
|
||||
* @returns {Promise<ModuleWrap>|ModuleWrap}
|
||||
*/
|
||||
async loadAndTranslate(url, loadContext, isMain) {
|
||||
const { format, source } = await this.load(url, loadContext);
|
||||
return this.#translate(url, format, source, isMain);
|
||||
loadAndTranslate(url, loadContext, isMain) {
|
||||
const maybePromise = this.load(url, loadContext);
|
||||
const afterLoad = ({ format, source }) => {
|
||||
return this.#translate(url, format, source, isMain);
|
||||
};
|
||||
if (isPromise(maybePromise)) {
|
||||
return maybePromise.then(afterLoad);
|
||||
}
|
||||
return afterLoad(maybePromise);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ const {
|
|||
},
|
||||
} = internalBinding('util');
|
||||
const { decorateErrorStack, kEmptyObject } = require('internal/util');
|
||||
const { isPromise } = require('internal/util/types');
|
||||
const {
|
||||
getSourceMapsSupport,
|
||||
} = require('internal/source_map/source_map_cache');
|
||||
|
|
@ -138,12 +139,11 @@ class ModuleJob extends ModuleJobBase {
|
|||
this.#loader = loader;
|
||||
|
||||
// Expose the promise to the ModuleWrap directly for linking below.
|
||||
if (isForRequireInImportedCJS) {
|
||||
this.module = moduleOrModulePromise;
|
||||
assert(this.module instanceof ModuleWrap);
|
||||
this.modulePromise = PromiseResolve(this.module);
|
||||
} else {
|
||||
if (isPromise(moduleOrModulePromise)) {
|
||||
this.modulePromise = moduleOrModulePromise;
|
||||
} else {
|
||||
this.module = moduleOrModulePromise;
|
||||
this.modulePromise = PromiseResolve(moduleOrModulePromise);
|
||||
}
|
||||
|
||||
if (this.phase === kEvaluationPhase) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ let error;
|
|||
await assert.rejects(
|
||||
() => import(file),
|
||||
(e) => {
|
||||
assert.strictEqual(error, e);
|
||||
// The module may be compiled again and a new SyntaxError would be thrown but
|
||||
// with the same content.
|
||||
assert.deepStrictEqual(error, e);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ async function test() {
|
|||
|
||||
await rejects(
|
||||
import(jsModuleDataUrl, { with: { type: 'json', other: 'unsupported' } }),
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_TYPE_INCOMPATIBLE' }
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
|
|
@ -48,7 +48,7 @@ async function test() {
|
|||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { with: { foo: 'bar' } }),
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_MISSING' }
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ await rejects(
|
|||
|
||||
await rejects(
|
||||
import(jsModuleDataUrl, { with: { type: 'json', other: 'unsupported' } }),
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_TYPE_INCOMPATIBLE' }
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
|
|
@ -43,7 +43,7 @@ await rejects(
|
|||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { with: { foo: 'bar' } }),
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_MISSING' }
|
||||
{ code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user