module: fix conditions override in synchronous resolve hooks · nodejs/node@fe0195f

@@ -51,6 +51,7 @@ const {

5151

ReflectSet,

5252

RegExpPrototypeExec,

5353

SafeMap,

54+

SafeSet,

5455

String,

5556

StringPrototypeCharAt,

5657

StringPrototypeCharCodeAt,

@@ -154,6 +155,7 @@ const internalFsBinding = internalBinding('fs');

154155

const { safeGetenv } = internalBinding('credentials');

155156

const {

156157

getCjsConditions,

158+

getCjsConditionsArray,

157159

initializeCjsConditions,

158160

loadBuiltinModule,

159161

makeRequireFunction,

@@ -653,7 +655,7 @@ const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/;

653655

* Resolves the exports for a given module path and request.

654656

* @param {string} nmPath The path to the module.

655657

* @param {string} request The request for the module.

656-

* @param {unknown} conditions

658+

* @param {Set<string>} conditions The conditions to use for resolution.

657659

* @returns {undefined|string}

658660

*/

659661

function resolveExports(nmPath, request, conditions) {

@@ -1068,17 +1070,30 @@ function resolveForCJSWithHooks(specifier, parent, isMain) {

10681070

function defaultResolve(specifier, context) {

10691071

// TODO(joyeecheung): parent and isMain should be part of context, then we

10701072

// no longer need to use a different defaultResolve for every resolution.

1073+

// In the hooks, context.conditions is passed around as an array, but internally

1074+

// the resolution helpers expect a SafeSet. Do the conversion here.

1075+

let conditionSet;

1076+

const conditions = context.conditions;

1077+

if (conditions !== undefined && conditions !== getCjsConditionsArray()) {

1078+

if (!ArrayIsArray(conditions)) {

1079+

throw new ERR_INVALID_ARG_VALUE('context.conditions', conditions,

1080+

'expected an array');

1081+

}

1082+

conditionSet = new SafeSet(conditions);

1083+

} else {

1084+

conditionSet = getCjsConditions();

1085+

}

10711086

defaultResolvedFilename = defaultResolveImpl(specifier, parent, isMain, {

10721087

__proto__: null,

1073-

conditions: context.conditions,

1088+

conditions: conditionSet,

10741089

});

1075109010761091

defaultResolvedURL = convertCJSFilenameToURL(defaultResolvedFilename);

10771092

return { __proto__: null, url: defaultResolvedURL };

10781093

}

1079109410801095

const resolveResult = resolveWithHooks(specifier, parentURL, /* importAttributes */ undefined,

1081-

getCjsConditions(), defaultResolve);

1096+

getCjsConditionsArray(), defaultResolve);

10821097

const { url } = resolveResult;

10831098

format = resolveResult.format;

10841099

@@ -1154,7 +1169,7 @@ function loadBuiltinWithHooks(id, url, format) {

11541169

url ??= `node:${id}`;

11551170

// TODO(joyeecheung): do we really want to invoke the load hook for the builtins?

11561171

const loadResult = loadWithHooks(url, format || 'builtin', /* importAttributes */ undefined,

1157-

getCjsConditions(), getDefaultLoad(url, id));

1172+

getCjsConditionsArray(), getDefaultLoad(url, id));

11581173

if (loadResult.format && loadResult.format !== 'builtin') {

11591174

return undefined; // Format has been overridden, return undefined for the caller to continue loading.

11601175

}

@@ -1306,7 +1321,7 @@ Module._load = function(request, parent, isMain) {

13061321

* @param {ResolveFilenameOptions} options Options object

13071322

* @typedef {object} ResolveFilenameOptions

13081323

* @property {string[]} paths Paths to search for modules in

1309-

* @property {string[]} conditions Conditions used for resolution.

1324+

* @property {Set<string>?} conditions The conditions to use for resolution.

13101325

* @returns {void|string}

13111326

*/

13121327

Module._resolveFilename = function(request, parent, isMain, options) {

@@ -1755,7 +1770,8 @@ function loadSource(mod, filename, formatFromNode) {

17551770

mod[kURL] = convertCJSFilenameToURL(filename);

17561771

}

175717721758-

const loadResult = loadWithHooks(mod[kURL], mod[kFormat], /* importAttributes */ undefined, getCjsConditions(),

1773+

const loadResult = loadWithHooks(mod[kURL], mod[kFormat], /* importAttributes */ undefined,

1774+

getCjsConditionsArray(),

17591775

getDefaultLoad(mod[kURL], filename));

1760177617611777

// Reset the module properties with load hook results.