-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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 <matteo.collina@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Zijian Liu <lxxyxzj@gmail.com> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
- Loading branch information
1 parent
1eb55f3
commit 374743c
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); | ||
} |