-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
module: fix sync resolve hooks for require with node: prefixes #61088
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export const url = import.meta.url; |
37 changes: 37 additions & 0 deletions
37
test/module-hooks/test-module-hooks-load-builtin-override-commonjs.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| 'use strict'; | ||
|
|
||
| // This tests that load hooks can override the format of builtin modules | ||
| // to 'commonjs' format. | ||
| const common = require('../common'); | ||
| const assert = require('assert'); | ||
| const { registerHooks } = require('module'); | ||
|
|
||
| // Pick a builtin that's unlikely to be loaded already - like zlib. | ||
| assert(!process.moduleLoadList.includes('NativeModule zlib')); | ||
|
|
||
| const hook = registerHooks({ | ||
| load: common.mustCall(function load(url, context, nextLoad) { | ||
| // Only intercept zlib builtin | ||
| if (url === 'node:zlib') { | ||
| // Return a different format to override the builtin | ||
| return { | ||
| source: 'exports.custom_zlib = "overridden by load hook";', | ||
| format: 'commonjs', | ||
| shortCircuit: true, | ||
| }; | ||
| } | ||
| return nextLoad(url, context); | ||
| }, 2), // Called twice: once for 'zlib', once for 'node:zlib' | ||
| }); | ||
|
|
||
| // Test: Load hook overrides builtin format to commonjs | ||
| const zlib = require('zlib'); | ||
| assert.strictEqual(zlib.custom_zlib, 'overridden by load hook'); | ||
| assert.strictEqual(typeof zlib.createGzip, 'undefined'); // Original zlib API should not be available | ||
|
|
||
| // Test with node: prefix | ||
| const zlib2 = require('node:zlib'); | ||
| assert.strictEqual(zlib2.custom_zlib, 'overridden by load hook'); | ||
| assert.strictEqual(typeof zlib2.createGzip, 'undefined'); | ||
|
|
||
| hook.deregister(); |
37 changes: 37 additions & 0 deletions
37
test/module-hooks/test-module-hooks-load-builtin-override-json.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| 'use strict'; | ||
|
|
||
| // This tests that load hooks can override the format of builtin modules | ||
| // to 'json' format. | ||
| const common = require('../common'); | ||
| const assert = require('assert'); | ||
| const { registerHooks } = require('module'); | ||
|
|
||
| // Pick a builtin that's unlikely to be loaded already - like zlib. | ||
| assert(!process.moduleLoadList.includes('NativeModule zlib')); | ||
|
|
||
| const hook = registerHooks({ | ||
| load: common.mustCall(function load(url, context, nextLoad) { | ||
| // Only intercept zlib builtin | ||
| if (url === 'node:zlib') { | ||
| // Return JSON format to override the builtin | ||
| return { | ||
| source: JSON.stringify({ custom_zlib: 'JSON overridden zlib' }), | ||
| format: 'json', | ||
| shortCircuit: true, | ||
| }; | ||
| } | ||
| return nextLoad(url, context); | ||
| }, 2), // Called twice: once for 'zlib', once for 'node:zlib' | ||
| }); | ||
|
|
||
| // Test: Load hook overrides builtin format to json | ||
| const zlib = require('zlib'); | ||
| assert.strictEqual(zlib.custom_zlib, 'JSON overridden zlib'); | ||
| assert.strictEqual(typeof zlib.createGzip, 'undefined'); // Original zlib API should not be available | ||
|
|
||
| // Test with node: prefix | ||
| const zlib2 = require('node:zlib'); | ||
| assert.strictEqual(zlib2.custom_zlib, 'JSON overridden zlib'); | ||
| assert.strictEqual(typeof zlib2.createGzip, 'undefined'); | ||
|
|
||
| hook.deregister(); |
41 changes: 41 additions & 0 deletions
41
test/module-hooks/test-module-hooks-load-builtin-override-module.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| 'use strict'; | ||
|
|
||
| // This tests that load hooks can override the format of builtin modules | ||
| // to 'module', and require() can load them. | ||
| const common = require('../common'); | ||
| const assert = require('assert'); | ||
| const { registerHooks } = require('module'); | ||
|
|
||
| // Pick a builtin that's unlikely to be loaded already - like zlib. | ||
| assert(!process.moduleLoadList.includes('NativeModule zlib')); | ||
|
|
||
| const hook = registerHooks({ | ||
| load: common.mustCall(function load(url, context, nextLoad) { | ||
| // Only intercept zlib builtin | ||
| if (url === 'node:zlib') { | ||
| // Return ES module format to override the builtin | ||
| // Note: For require() to work with ESM, we need to export 'module.exports' | ||
| return { | ||
| source: `const exports = { custom_zlib: "ESM overridden zlib" }; | ||
| export default exports; | ||
| export { exports as 'module.exports' };`, | ||
| format: 'module', | ||
| shortCircuit: true, | ||
| }; | ||
| } | ||
| return nextLoad(url, context); | ||
| }, 2), // Called twice: once for 'zlib', once for 'node:zlib' | ||
| }); | ||
|
|
||
| // Test: Load hook overrides builtin format to module. | ||
| // With the 'module.exports' export, require() should work | ||
| const zlib = require('zlib'); | ||
| assert.strictEqual(zlib.custom_zlib, 'ESM overridden zlib'); | ||
| assert.strictEqual(typeof zlib.createGzip, 'undefined'); // Original zlib API should not be available | ||
|
|
||
| // Test with node: prefix | ||
| const zlib2 = require('node:zlib'); | ||
| assert.strictEqual(zlib2.custom_zlib, 'ESM overridden zlib'); | ||
| assert.strictEqual(typeof zlib2.createGzip, 'undefined'); | ||
|
|
||
| hook.deregister(); |
33 changes: 33 additions & 0 deletions
33
test/module-hooks/test-module-hooks-resolve-builtin-on-disk-require-with-prefix.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| 'use strict'; | ||
|
|
||
| // This tests that builtins can be redirected to a local file when they are prefixed | ||
| // with `node:`. | ||
| require('../common'); | ||
|
|
||
| const assert = require('assert'); | ||
| const { registerHooks } = require('module'); | ||
| const fixtures = require('../common/fixtures'); | ||
|
|
||
| // This tests that builtins can be redirected to a local file. | ||
| // Pick a builtin that's unlikely to be loaded already - like zlib. | ||
| assert(!process.moduleLoadList.includes('NativeModule zlib')); | ||
|
|
||
| const hook = registerHooks({ | ||
| resolve(specifier, context, nextLoad) { | ||
| specifier = specifier.replaceAll('node:', ''); | ||
| return { | ||
| url: fixtures.fileURL('module-hooks', `redirected-${specifier}.js`).href, | ||
| shortCircuit: true, | ||
| }; | ||
| }, | ||
| }); | ||
|
|
||
| // Check assert, which is already loaded. | ||
| // eslint-disable-next-line node-core/must-call-assert | ||
| assert.strictEqual(require('node:assert').exports_for_test, 'redirected assert'); | ||
| // Check zlib, which is not yet loaded. | ||
| assert.strictEqual(require('node:zlib').exports_for_test, 'redirected zlib'); | ||
| // Check fs, which is redirected to an ESM | ||
| assert.strictEqual(require('node:fs').exports_for_test, 'redirected fs'); | ||
|
|
||
| hook.deregister(); |
36 changes: 36 additions & 0 deletions
36
test/module-hooks/test-module-hooks-resolve-load-builtin-override-both-prefix.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| 'use strict'; | ||
|
|
||
| // This tests the interaction between resolve and load hooks for builtins with the | ||
| // `node:` prefix. | ||
| const common = require('../common'); | ||
| const assert = require('assert'); | ||
| const { registerHooks } = require('module'); | ||
| const fixtures = require('../common/fixtures'); | ||
|
|
||
| // Pick a builtin that's unlikely to be loaded already - like zlib. | ||
| assert(!process.moduleLoadList.includes('NativeModule zlib')); | ||
|
|
||
| const redirectedURL = fixtures.fileURL('module-hooks/redirected-zlib.js').href; | ||
|
|
||
| registerHooks({ | ||
| resolve: common.mustCall(function resolve(specifier, context, nextResolve) { | ||
| assert.strictEqual(specifier, 'node:zlib'); | ||
| return { | ||
| url: redirectedURL, | ||
| format: 'module', | ||
| shortCircuit: true, | ||
| }; | ||
| }), | ||
|
|
||
| load: common.mustCall(function load(url, context, nextLoad) { | ||
| assert.strictEqual(url, redirectedURL); | ||
| return { | ||
| source: 'export const loadURL = import.meta.url;', | ||
| format: 'module', | ||
| shortCircuit: true, | ||
| }; | ||
| }), | ||
| }); | ||
|
|
||
| const zlib = require('node:zlib'); | ||
| assert.strictEqual(zlib.loadURL, redirectedURL); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.