Skip to content
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

process: add process.getBuiltinModule(id) #52762

Closed
wants to merge 7 commits into from

Conversation

joyeecheung
Copy link
Member

@joyeecheung joyeecheung commented Apr 30, 2024

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.

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) accepts built-in module IDs that are recognized
by module.isBuiltin(id).

The references returned by process.getBuiltinModule(id) always point to
the built-in module corresponding to id even if users modify
require.cache so that require(id) returns something else.

Fixes: #52599

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/loaders
  • @nodejs/startup

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Apr 30, 2024
doc/api/process.md Outdated Show resolved Hide resolved
doc/api/process.md Outdated Show resolved Hide resolved
lib/internal/modules/helpers.js Outdated Show resolved Hide resolved
Copy link
Member

@JakobJingleheimer JakobJingleheimer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, quite simple :)

doc/api/process.md Outdated Show resolved Hide resolved
doc/api/process.md Outdated Show resolved Hide resolved
doc/api/process.md Outdated Show resolved Hide resolved
lib/internal/modules/helpers.js Outdated Show resolved Hide resolved
doc/api/process.md Outdated Show resolved Hide resolved
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@jakebailey
Copy link

This is obviously exactly what I asked for (😄) and gets it "done" the quickest, but I'm curious if there are any other opinions about this in general.

Is it possible that import.now or "weak/optional" imports come to fruition, such that those are more usable and processed by downstream tools? I'd hate to accidentally open the door to "breaking" node polyfills (node-polyfill-webpack-plugin, vite-plugin-node-polyfills, etc) and so on, just because it's not require or import, but some other expression.

@joyeecheung
Copy link
Member Author

joyeecheung commented May 1, 2024

I'd hate to accidentally open the door to "breaking" node polyfills (node-polyfill-webpack-plugin, vite-plugin-node-polyfills

Not quite sure if I am following this but I think process.getBuiltin(id) should be polyfill-able by these kind of bundler plugins - just patch the its polyfilled process object to load its own polyfilled libraries by id? (In general plugins like this already polyfill the process object). For code that uses the polyfill/gets transformed to use the polyfills, if the polyfill doesn't support this yet, using this would not be too different than "using a new API that the polyfill doesn't support yet" which happens all the time.

@jakebailey
Copy link

Yeah, I guess it's no different than detecting calls to require and error/warn on ones which cannot be statically determined. It's just not quite as injectable as require.

Just poking holes in my own idea.

@joyeecheung
Copy link
Member Author

joyeecheung commented May 1, 2024

We can also suggest in the documentation that users should only consider using this for code paths that can only be run in Node.js (the code example is basically already suggesting that but we can make it clearer). If they want the code depending on the built-ins to be polyfill-able in the browser, they should still use require or import.

@nicolo-ribaudo
Copy link
Contributor

nicolo-ribaudo commented May 1, 2024

There is a TC39 proposal to get original built-in functions, through a new getIntrinsic global (https://github.com/tc39/proposal-get-intrinsic). getBuiltin is similar enough that could cause confusion — what do you think about something like process.getBuiltinModule to be more clear about what it does?

@jakebailey
Copy link

Just to prove this out to its full extent (and to procrastinate other work I didn't want to do), I polyfilled this API using --require and was able to get TypeScript's CLI, API, and test suite all working: microsoft/TypeScript#58419

doc/api/process.md Outdated Show resolved Hide resolved
`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`.
@joyeecheung joyeecheung changed the title process: add process.getBuiltin(id) process: add process.getBuiltinModule(id) May 7, 2024
@joyeecheung
Copy link
Member Author

Updated the PR a bit:

@nodejs-github-bot
Copy link
Collaborator

@GeoffreyBooth
Copy link
Member

Changed it to process.getBuiltinModule() as requested in process: add process.getBuiltinModule(id)

Now it mismatches isBuiltin. Personally I don't see the confusion between getIntrinsic and getBuiltin; I think getBuiltin is fine, and there's more potential for confusion with this not corresponding with isBuiltin.

Alternatively we can add isBuiltinModule as an alias for isBuiltin.

doc/api/process.md Outdated Show resolved Hide resolved
@legendecas
Copy link
Member

Now it mismatches isBuiltin. Personally I don't see the confusion between getIntrinsic and getBuiltin; I think getBuiltin is fine, and there's more potential for confusion with this not corresponding with isBuiltin.

Alternatively we can add isBuiltinModule as an alias for isBuiltin.

isBuiltin is scoped in node:module. It is not a function available from the global scope, like global.process.getBuiltinModule.

@GeoffreyBooth
Copy link
Member

isBuiltin is scoped in node:module. It is not a function available from the global scope, like global.process.getBuiltinModule.

Fair enough. I still think we should create an alias on node:module isBuiltinModule, but that can come later.

RafaelGSS added a commit that referenced this pull request Jun 7, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
cli:
  * (SEMVER-MINOR) add `NODE_RUN_PACKAGE_JSON_PATH` env (Yagiz Nizipli) #53058
  * (SEMVER-MINOR) add `NODE_RUN_SCRIPT_NAME` env to `node --run` (Yagiz Nizipli) #53032
doc:
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
fs:
  * mark recursive cp methods as stable (Théo LUDWIG) #53127
lib:
  * (SEMVER-MINOR) add EventSource Client (Aras Abbasi) #51575
  * (SEMVER-MINOR) replace MessageEvent with undici's (Matthew Aitken) #52370
module:
  * (SEMVER-MINOR) print amount of load time of a cjs module (Vinicius Lourenço) #52213
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add snapshot testing (Colin Ihrig) #53169
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
  * (SEMVER-MINOR) support module mocking (Colin Ihrig) #52848

PR-URL: TODO
@RafaelGSS RafaelGSS mentioned this pull request Jun 7, 2024
RafaelGSS added a commit that referenced this pull request Jun 7, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
cli:
  * (SEMVER-MINOR) add `NODE_RUN_PACKAGE_JSON_PATH` env (Yagiz Nizipli) #53058
  * (SEMVER-MINOR) add `NODE_RUN_SCRIPT_NAME` env to `node --run` (Yagiz Nizipli) #53032
doc:
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
fs:
  * mark recursive cp methods as stable (Théo LUDWIG) #53127
lib:
  * (SEMVER-MINOR) add EventSource Client (Aras Abbasi) #51575
  * (SEMVER-MINOR) replace MessageEvent with undici's (Matthew Aitken) #52370
module:
  * (SEMVER-MINOR) print amount of load time of a cjs module (Vinicius Lourenço) #52213
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add snapshot testing (Colin Ihrig) #53169
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
  * (SEMVER-MINOR) support module mocking (Colin Ihrig) #52848

PR-URL: #53379
RafaelGSS added a commit that referenced this pull request Jun 10, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
cli:
  * (SEMVER-MINOR) add `NODE_RUN_PACKAGE_JSON_PATH` env (Yagiz Nizipli) #53058
  * (SEMVER-MINOR) add `NODE_RUN_SCRIPT_NAME` env to `node --run` (Yagiz Nizipli) #53032
doc:
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
fs:
  * mark recursive cp methods as stable (Théo LUDWIG) #53127
lib:
  * (SEMVER-MINOR) add EventSource Client (Aras Abbasi) #51575
  * (SEMVER-MINOR) replace MessageEvent with undici's (Matthew Aitken) #52370
module:
  * (SEMVER-MINOR) print amount of load time of a cjs module (Vinicius Lourenço) #52213
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src:
  * (SEMVER-MINOR) traverse parent folders while running `--run` (Yagiz Nizipli) #53154
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add snapshot testing (Colin Ihrig) #53169
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
  * (SEMVER-MINOR) support module mocking (Colin Ihrig) #52848

PR-URL: #53379
RafaelGSS added a commit that referenced this pull request Jun 10, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
cli:
  * (SEMVER-MINOR) add `NODE_RUN_PACKAGE_JSON_PATH` env (Yagiz Nizipli) #53058
  * (SEMVER-MINOR) add `NODE_RUN_SCRIPT_NAME` env to `node --run` (Yagiz Nizipli) #53032
doc:
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
fs:
  * mark recursive cp methods as stable (Théo LUDWIG) #53127
lib:
  * (SEMVER-MINOR) add EventSource Client (Aras Abbasi) #51575
  * (SEMVER-MINOR) replace MessageEvent with undici's (Matthew Aitken) #52370
module:
  * (SEMVER-MINOR) print amount of load time of a cjs module (Vinicius Lourenço) #52213
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src:
  * (SEMVER-MINOR) traverse parent folders while running `--run` (Yagiz Nizipli) #53154
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add snapshot testing (Colin Ihrig) #53169
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
  * (SEMVER-MINOR) support module mocking (Colin Ihrig) #52848

PR-URL: #53379
RafaelGSS added a commit that referenced this pull request Jun 11, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
cli:
  * (SEMVER-MINOR) add `NODE_RUN_PACKAGE_JSON_PATH` env (Yagiz Nizipli) #53058
  * (SEMVER-MINOR) add `NODE_RUN_SCRIPT_NAME` env to `node --run` (Yagiz Nizipli) #53032
doc:
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
fs:
  * mark recursive cp methods as stable (Théo LUDWIG) #53127
lib:
  * (SEMVER-MINOR) add EventSource Client (Aras Abbasi) #51575
  * (SEMVER-MINOR) replace MessageEvent with undici's (Matthew Aitken) #52370
module:
  * (SEMVER-MINOR) print amount of load time of a cjs module (Vinicius Lourenço) #52213
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src:
  * (SEMVER-MINOR) traverse parent folders while running `--run` (Yagiz Nizipli) #53154
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add snapshot testing (Colin Ihrig) #53169
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
  * (SEMVER-MINOR) support module mocking (Colin Ihrig) #52848

PR-URL: #53379
@nicolo-ribaudo
Copy link
Contributor

Would you be open to a PR backporting this to v20?

@joyeecheung
Copy link
Member Author

joyeecheung commented Jun 18, 2024

This has only been in the current release (22) for a week. We will need to bake it for another week before backporting it to LTS per the policy.

sophoniie pushed a commit to sophoniie/node that referenced this pull request Jun 20, 2024
PR-URL: nodejs#52762
Fixes: nodejs#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>
sophoniie pushed a commit to sophoniie/node that referenced this pull request Jun 20, 2024
`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: nodejs#52762
Fixes: nodejs#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>
sophoniie pushed a commit to sophoniie/node that referenced this pull request Jun 20, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) nodejs#53221
cli:
  * (SEMVER-MINOR) add `NODE_RUN_PACKAGE_JSON_PATH` env (Yagiz Nizipli) nodejs#53058
  * (SEMVER-MINOR) add `NODE_RUN_SCRIPT_NAME` env to `node --run` (Yagiz Nizipli) nodejs#53032
doc:
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) nodejs#53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) nodejs#52762
  * add StefanStojanovic to collaborators (StefanStojanovic) nodejs#53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) nodejs#53008
fs:
  * mark recursive cp methods as stable (Théo LUDWIG) nodejs#53127
lib:
  * (SEMVER-MINOR) add EventSource Client (Aras Abbasi) nodejs#51575
  * (SEMVER-MINOR) replace MessageEvent with undici's (Matthew Aitken) nodejs#52370
module:
  * (SEMVER-MINOR) print amount of load time of a cjs module (Vinicius Lourenço) nodejs#52213
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) nodejs#53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) nodejs#52762
src:
  * (SEMVER-MINOR) traverse parent folders while running `--run` (Yagiz Nizipli) nodejs#53154
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) nodejs#53124
test_runner:
  * (SEMVER-MINOR) add snapshot testing (Colin Ihrig) nodejs#53169
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) nodejs#53169
  * (SEMVER-MINOR) support module mocking (Colin Ihrig) nodejs#52848

PR-URL: nodejs#53379
bmeck pushed a commit to bmeck/node that referenced this pull request Jun 22, 2024
PR-URL: nodejs#52762
Fixes: nodejs#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>
bmeck pushed a commit to bmeck/node that referenced this pull request Jun 22, 2024
`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: nodejs#52762
Fixes: nodejs#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>
bmeck pushed a commit to bmeck/node that referenced this pull request Jun 22, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) nodejs#53221
cli:
  * (SEMVER-MINOR) add `NODE_RUN_PACKAGE_JSON_PATH` env (Yagiz Nizipli) nodejs#53058
  * (SEMVER-MINOR) add `NODE_RUN_SCRIPT_NAME` env to `node --run` (Yagiz Nizipli) nodejs#53032
doc:
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) nodejs#53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) nodejs#52762
  * add StefanStojanovic to collaborators (StefanStojanovic) nodejs#53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) nodejs#53008
fs:
  * mark recursive cp methods as stable (Théo LUDWIG) nodejs#53127
lib:
  * (SEMVER-MINOR) add EventSource Client (Aras Abbasi) nodejs#51575
  * (SEMVER-MINOR) replace MessageEvent with undici's (Matthew Aitken) nodejs#52370
module:
  * (SEMVER-MINOR) print amount of load time of a cjs module (Vinicius Lourenço) nodejs#52213
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) nodejs#53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) nodejs#52762
src:
  * (SEMVER-MINOR) traverse parent folders while running `--run` (Yagiz Nizipli) nodejs#53154
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) nodejs#53124
test_runner:
  * (SEMVER-MINOR) add snapshot testing (Colin Ihrig) nodejs#53169
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) nodejs#53169
  * (SEMVER-MINOR) support module mocking (Colin Ihrig) nodejs#52848

PR-URL: nodejs#53379
marco-ippolito pushed a commit that referenced this pull request Jul 19, 2024
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>
marco-ippolito pushed a commit that referenced this pull request Jul 19, 2024
`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>
marco-ippolito pushed a commit that referenced this pull request Jul 19, 2024
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>
marco-ippolito pushed a commit that referenced this pull request Jul 19, 2024
`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>
marco-ippolito added a commit that referenced this pull request Jul 19, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
doc:
  * doc-only deprecate OpenSSL engine-based APIs (Richard Lau) #53329
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
inspector:
  * fix disable async hooks on Debugger.setAsyncCallStackDepth (Joyee Cheung) #53473
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
util:
  * (SEMVER-MINOR) support `--no-` for argument with boolean type for parseArgs (Zhenwei Jin) #53107

PR-URL: TODO
marco-ippolito added a commit that referenced this pull request Jul 19, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
doc:
  * doc-only deprecate OpenSSL engine-based APIs (Richard Lau) #53329
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
inspector:
  * fix disable async hooks on Debugger.setAsyncCallStackDepth (Joyee Cheung) #53473
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
util:
  * (SEMVER-MINOR) support `--no-` for argument with boolean type for parseArgs (Zhenwei Jin) #53107

PR-URL: #53945
marco-ippolito added a commit that referenced this pull request Jul 21, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
doc:
  * doc-only deprecate OpenSSL engine-based APIs (Richard Lau) #53329
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
inspector:
  * fix disable async hooks on Debugger.setAsyncCallStackDepth (Joyee Cheung) #53473
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
util:
  * (SEMVER-MINOR) support `--no-` for argument with boolean type for parseArgs (Zhenwei Jin) #53107

PR-URL: #53945
marco-ippolito added a commit that referenced this pull request Jul 21, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
doc:
  * doc-only deprecate OpenSSL engine-based APIs (Richard Lau) #53329
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
inspector:
  * fix disable async hooks on Debugger.setAsyncCallStackDepth (Joyee Cheung) #53473
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
util:
  * (SEMVER-MINOR) support `--no-` for argument with boolean type for parseArgs (Zhenwei Jin) #53107

PR-URL: #53945
marco-ippolito added a commit that referenced this pull request Jul 24, 2024
Notable changes:

buffer:
  * (SEMVER-MINOR) add .bytes() method to Blob (Matthew Aitken) #53221
doc:
  * doc-only deprecate OpenSSL engine-based APIs (Richard Lau) #53329
  * (SEMVER-MINOR) add context.assert docs (Colin Ihrig) #53169
  * (SEMVER-MINOR) improve explanation about built-in modules (Joyee Cheung) #52762
  * add StefanStojanovic to collaborators (StefanStojanovic) #53118
  * add Marco Ippolito to TSC (Rafael Gonzaga) #53008
inspector:
  * fix disable async hooks on Debugger.setAsyncCallStackDepth (Joyee Cheung) #53473
net:
  * (SEMVER-MINOR) add new net.server.listen tracing channel (Paolo Insogna) #53136
process:
  * (SEMVER-MINOR) add process.getBuiltinModule(id) (Joyee Cheung) #52762
src,permission:
  * (SEMVER-MINOR) --allow-wasi & prevent WASI exec (Rafael Gonzaga) #53124
test_runner:
  * (SEMVER-MINOR) add context.fullName (Colin Ihrig) #53169
util:
  * (SEMVER-MINOR) support `--no-` for argument with boolean type for parseArgs (Zhenwei Jin) #53107

PR-URL: #53945
codebytere added a commit to electron/electron that referenced this pull request Jul 25, 2024
codebytere added a commit to electron/electron that referenced this pull request Jul 26, 2024
jkleinsc pushed a commit to electron/electron that referenced this pull request Jul 26, 2024
* chore: bump node in DEPS to v20.16.0

* test: skip unstable shadow realm gc tests

nodejs/node#52855

* test: extend env for `test-node-output-errors`

nodejs/node#53535

* src: fix typo in env.cc

nodejs/node#53418

* src: reset `process.versions` during pre-execution

nodejs/node#53444

* chore: fixup patch indices

* src,permission: --allow-wasi & prevent WASI exec

nodejs/node#53124

* tls: use SSL_get_peer_tmp_key

nodejs/node#53366

* deps: update c-ares to 1.29.0

nodejs/node#53155

* src: account for OpenSSL unexpected version

* crypto: fix propagation of "memory limit exceeded"

nodejs/node#53300

* process: add process.getBuiltinModule(id)

nodejs/node#52762

* windows 32bit: config change callback needs to be stdcall

c-ares/c-ares@8f265c9

* fix: building with UNICODE

c-ares/c-ares#802

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs. semver-minor PRs that contain new features and should be released in the next minor version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide some mechanism to conditionally and synchronously import modules (or just builtins) from ESM