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');
154155const { safeGetenv } = internalBinding('credentials');
155156const {
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 */
659661function resolveExports(nmPath, request, conditions) {
@@ -1068,17 +1070,30 @@ function resolveForCJSWithHooks(specifier, parent, isMain) {
10681070function 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+}
10711086defaultResolvedFilename = defaultResolveImpl(specifier, parent, isMain, {
10721087__proto__: null,
1073-conditions: context.conditions,
1088+conditions: conditionSet,
10741089});
1075109010761091defaultResolvedURL = convertCJSFilenameToURL(defaultResolvedFilename);
10771092return { __proto__: null, url: defaultResolvedURL };
10781093}
1079109410801095const resolveResult = resolveWithHooks(specifier, parentURL, /* importAttributes */ undefined,
1081-getCjsConditions(), defaultResolve);
1096+getCjsConditionsArray(), defaultResolve);
10821097const { url } = resolveResult;
10831098format = resolveResult.format;
10841099@@ -1154,7 +1169,7 @@ function loadBuiltinWithHooks(id, url, format) {
11541169url ??= `node:${id}`;
11551170// TODO(joyeecheung): do we really want to invoke the load hook for the builtins?
11561171const loadResult = loadWithHooks(url, format || 'builtin', /* importAttributes */ undefined,
1157-getCjsConditions(), getDefaultLoad(url, id));
1172+getCjsConditionsArray(), getDefaultLoad(url, id));
11581173if (loadResult.format && loadResult.format !== 'builtin') {
11591174return 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 */
13121327Module._resolveFilename = function(request, parent, isMain, options) {
@@ -1755,7 +1770,8 @@ function loadSource(mod, filename, formatFromNode) {
17551770mod[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(),
17591775getDefaultLoad(mod[kURL], filename));
1760177617611777// Reset the module properties with load hook results.