-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
process: add process.getBuiltinModule(id)
`process.getBuiltinModule(id)` provides a way to load built-in modules in a globally available function. ES Modules that need to support other environments can use it to conditionally load a Node.js built-in when it is run in Node.js, without having to deal with the resolution error that can be thrown by `import` in a non-Node.js environment or having to use dynamic `import()` which either turns the module into an asynchronous module, or turns a synchronous API into an asynchronous one. ```mjs if (globalThis.process.getBuiltinModule) { // Run in Node.js, use the Node.js fs module. const fs = globalThis.process.getBuiltinModule('fs'); // If `require()` is needed to load user-modules, use // createRequire() const module = globalThis.process.getBuiltinModule('module'); const require = module.createRequire(import.meta.url); const foo = require('foo'); } ``` If `id` specifies a built-in module available in the current Node.js process, `process.getBuiltinModule(id)` method returns the corresponding built-in module. If `id` does not correspond to any built-in module, `undefined` is returned. `process.getBuiltinModule(id)` accept built-in module IDs that are recognized by `module.isBuiltin(id)`. Some built-in modules must be loaded with the `node:` prefix. The built-in modules returned by `process.getBuiltinModule(id)` are always the original modules - that is, it's not affected by `require.cache`. PR-URL: #52762 Fixes: #52599 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Moshe Atlow <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]> Reviewed-By: Marco Ippolito <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Zijian Liu <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Mohammed Keyvanzadeh <[email protected]>
- Loading branch information
1 parent
e0b5dee
commit 1de215e
Showing
5 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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,55 @@ | ||
import { isMainThread, hasCrypto, hasIntl } from '../common/index.mjs'; | ||
import assert from 'node:assert'; | ||
import { builtinModules } from 'node:module'; | ||
|
||
for (const invalid of [1, undefined, null, false, [], {}, () => {}, Symbol('test')]) { | ||
assert.throws(() => process.getBuiltinModule(invalid), { code: 'ERR_INVALID_ARG_TYPE' }); | ||
} | ||
|
||
for (const invalid of [ | ||
'invalid', 'test', 'sea', 'test/reporter', 'internal/bootstrap/realm', | ||
'internal/deps/undici/undici', 'internal/util', | ||
]) { | ||
assert.strictEqual(process.getBuiltinModule(invalid), undefined); | ||
} | ||
|
||
// Check that createRequire()(id) returns the same thing as process.getBuiltinModule(id). | ||
const require = process.getBuiltinModule('module').createRequire(import.meta.url); | ||
const publicBuiltins = new Set(builtinModules); | ||
|
||
// Remove built-ins not available in the current setup. | ||
if (!isMainThread) { | ||
publicBuiltins.delete('trace_events'); | ||
} | ||
if (!hasCrypto) { | ||
publicBuiltins.delete('crypto'); | ||
publicBuiltins.delete('tls'); | ||
publicBuiltins.delete('_tls_common'); | ||
publicBuiltins.delete('_tls_wrap'); | ||
publicBuiltins.delete('http2'); | ||
publicBuiltins.delete('https'); | ||
publicBuiltins.delete('inspector'); | ||
publicBuiltins.delete('inspector/promises'); | ||
} | ||
if (!hasIntl) { | ||
publicBuiltins.delete('inspector'); | ||
publicBuiltins.delete('trace_events'); | ||
} | ||
|
||
for (const id of publicBuiltins) { | ||
assert.strictEqual(process.getBuiltinModule(id), require(id)); | ||
} | ||
// Check that import(id).default returns the same thing as process.getBuiltinModule(id). | ||
for (const id of publicBuiltins) { | ||
const imported = await import(`node:${id}`); | ||
assert.strictEqual(process.getBuiltinModule(id), imported.default); | ||
} | ||
|
||
// publicBuiltins does not include 'test' which requires the node: prefix. | ||
const ids = publicBuiltins.add('test'); | ||
// Check that import(id).default returns the same thing as process.getBuiltinModule(id). | ||
for (const id of ids) { | ||
const prefixed = `node:${id}`; | ||
const imported = await import(prefixed); | ||
assert.strictEqual(process.getBuiltinModule(prefixed), imported.default); | ||
} |