Skip to content

Commit 0881496

Browse files
authored
fix(commonjs): handle node: builtins with strictRequires: auto (#1930)
fix(commonjs): handle `node:` builtins correctly with `strictRequires: auto`
1 parent 46ba661 commit 0881496

File tree

5 files changed

+57
-7
lines changed

5 files changed

+57
-7
lines changed

β€Žpackages/commonjs/src/resolve-require-sources.jsβ€Ž

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,21 @@ export function getRequireResolver(extensions, detectCyclesAndConditional, curre
196196
// Special-case external Node built-ins to be handled via a lazy __require
197197
// helper instead of hoisted ESM imports when strict wrapping is used.
198198
const isExternalWrapped = isWrappedId(dependencyId, EXTERNAL_SUFFIX);
199-
if (
200-
parentMeta.initialCommonJSType === IS_WRAPPED_COMMONJS &&
201-
!allowProxy &&
202-
isExternalWrapped
203-
) {
199+
let resolvedDependencyId = dependencyId;
200+
if (parentMeta.isCommonJS === IS_WRAPPED_COMMONJS && !allowProxy && isExternalWrapped) {
204201
const actualExternalId = unwrapId(dependencyId, EXTERNAL_SUFFIX);
205202
if (actualExternalId.startsWith('node:')) {
206203
isCommonJS = IS_WRAPPED_COMMONJS;
207204
parentMeta.isRequiredCommonJS[dependencyId] = isCommonJS;
208205
}
206+
} else if (isExternalWrapped && !allowProxy) {
207+
// If the parent is not wrapped but the dependency is a node: builtin external,
208+
// unwrap the EXTERNAL_SUFFIX so it's treated as a normal external.
209+
// This avoids trying to load the lazy __require proxy for non-wrapped contexts.
210+
const actualExternalId = unwrapId(dependencyId, EXTERNAL_SUFFIX);
211+
if (actualExternalId.startsWith('node:')) {
212+
resolvedDependencyId = actualExternalId;
213+
}
209214
}
210215
const isWrappedCommonJS = isCommonJS === IS_WRAPPED_COMMONJS;
211216
fullyAnalyzedModules[dependencyId] = true;
@@ -226,8 +231,8 @@ export function getRequireResolver(extensions, detectCyclesAndConditional, curre
226231
wrappedModuleSideEffects,
227232
source: sources[index].source,
228233
id: allowProxy
229-
? wrapId(dependencyId, isWrappedCommonJS ? WRAPPED_SUFFIX : PROXY_SUFFIX)
230-
: dependencyId,
234+
? wrapId(resolvedDependencyId, isWrappedCommonJS ? WRAPPED_SUFFIX : PROXY_SUFFIX)
235+
: resolvedDependencyId,
231236
isCommonJS
232237
};
233238
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
description: 'handles node: builtins correctly with strictRequires: auto',
3+
pluginOptions: {
4+
strictRequires: 'auto'
5+
},
6+
exports: (exports, t) => {
7+
// Should be able to access properties of node:stream
8+
t.truthy(exports.Readable);
9+
t.is(typeof exports.Readable, 'function');
10+
// Should be able to instantiate
11+
t.truthy(exports.readable);
12+
}
13+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const stream = require('node:stream');
2+
const readable = new stream.Readable({});
3+
4+
module.exports = { Readable: stream.Readable, readable };

β€Žpackages/commonjs/test/snapshots/function.js.mdβ€Ž

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8715,6 +8715,34 @@ Generated by [AVA](https://avajs.dev).
87158715
`,
87168716
}
87178717

8718+
## strict-requires-auto-external-node-builtin
8719+
8720+
> Snapshot 1
8721+
8722+
{
8723+
'main.js': `'use strict';␊
8724+
␊
8725+
var require$$0 = require('node:stream');␊
8726+
␊
8727+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }␊
8728+
␊
8729+
var require$$0__default = /*#__PURE__*/_interopDefaultCompat(require$$0);␊
8730+
␊
8731+
function getDefaultExportFromCjs (x) {␊
8732+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;␊
8733+
}␊
8734+
␊
8735+
const stream = require$$0__default.default;␊
8736+
const readable = new stream.Readable({});␊
8737+
␊
8738+
var main = { Readable: stream.Readable, readable };␊
8739+
␊
8740+
var main$1 = /*@__PURE__*/getDefaultExportFromCjs(main);␊
8741+
␊
8742+
module.exports = main$1;␊
8743+
`,
8744+
}
8745+
87188746
## strict-requires-circular
87198747

87208748
> Snapshot 1
82 Bytes
Binary file not shown.

0 commit comments

Comments
Β (0)