Commit graph

139 commits

Author SHA1 Message Date
Joyee Cheung
af5d1c93ce
esm: sync-ify module translation
Some checks failed
Coverage Windows / coverage-windows (push) Waiting to run
Coverage Linux (without intl) / coverage-linux-without-intl (push) Failing after 1m30s
Test and upload documentation to artifacts / build-docs (push) Failing after 5m28s
Linters / format-cpp (push) Has been skipped
Linters / lint-cpp (push) Successful in 3m56s
Linters / lint-py (push) Successful in 3m3s
Linters / lint-sh (push) Failing after 1m52s
Linters / lint-pr-url (push) Has been skipped
Linters / lint-readme (push) Successful in 1m27s
Notify on Push / Notify on Force Push on `main` (push) Has been skipped
Notify on Push / Notify on Push on `main` that lacks metadata (push) Has been skipped
Scorecard supply-chain security / Scorecard analysis (push) Failing after 52s
Coverage Linux / coverage-linux (push) Failing after 57s
Linters / lint-addon-docs (push) Successful in 2m6s
Linters / lint-yaml (push) Successful in 2m42s
Linters / lint-codeowners (push) Failing after 59s
Linters / lint-js-and-md (push) Successful in 13m14s
This completes the TODO to compile WASM synchronously and thus
making translation (i.e. compilation + instantiation) synchronous.

PR-URL: https://github.com/nodejs/node/pull/59453
Refs: https://github.com/nodejs/node/issues/55782
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2025-08-14 14:28:40 +00:00
Joyee Cheung
6ea421a3d3
module: fix conditions override in synchronous resolve hooks
1. Make sure that the conditions are converted into arrays when
  being passed into user hooks.
2. Pass the conditions from user hooks into the ESM resolution
  so that it takes effect.

PR-URL: https://github.com/nodejs/node/pull/59011
Fixes: https://github.com/nodejs/node/issues/59003
Reviewed-By: Zeyu "Alex" Yang <himself65@outlook.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
2025-07-26 09:13:11 +00:00
Yagiz Nizipli
0fd1ecded6
meta: enable jsdoc/check-tag-names rule
PR-URL: https://github.com/nodejs/node/pull/58521
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2025-07-18 09:28:21 +00:00
Joyee Cheung
793a2792d5
module: throw error when re-runing errored module jobs
Re-evaluating an errored ESM should lead to rejecting
the rejection again - this is also the case when importing
it twice. In the case of retrying with
require after import, just throw the cached error.

Drive-by: add some debug logs.
PR-URL: https://github.com/nodejs/node/pull/58957
Fixes: https://github.com/nodejs/node/issues/58945
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2025-07-09 16:39:29 +00:00
Jacob Smith
5e1537c30b
esm: syncify default path of ModuleLoader.load
PR-URL: https://github.com/nodejs/node/pull/57419
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2025-06-11 21:53:56 +00:00
Joe
bbc059378b
esm: implement import.meta.main
Boolean value to check if an ES Module is the entrypoint of the
current process.

Implements: #57226

Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/57804
Fixes: https://github.com/nodejs/node/issues/57226
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
2025-05-26 22:31:54 +00:00
Joyee Cheung
e0766f9a73
module: handle instantiated async module jobs in require(esm)
When require(esm) encounters a cached module job that is instantiated
but not yet evaluated, run the evaluation. This catches an edge case
previously missed in https://github.com/nodejs/node/pull/57187.

PR-URL: https://github.com/nodejs/node/pull/58067
Fixes: https://github.com/nodejs/node/issues/58061
Reviewed-By: Jacob Smith <jacob@frende.me>
2025-05-08 20:10:32 +00:00
haykam821
bc09144aa6
module: fix incorrect formatting in require(esm) cycle error message
Fixes: https://github.com/nodejs/node/issues/57451
PR-URL: https://github.com/nodejs/node/pull/57453
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Jake Yuesong Li <jake.yuesong@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-04-09 11:47:58 +00:00
Joyee Cheung
0aa3dddfeb
module: handle cached linked async jobs in require(esm)
This handles two cases caused by using Promise.all() with
multiple dynamic import() that can make an asynchronously
linked module job that has finished/failed linking but
has not yet started actual evaluation appear in the load
cache when another require request is in turn to handle
it.

- When the cached async job has finished linking but has not
  started its evaluation because the async run() task would be
  later in line, start the evaluation from require() with
  runSync().
- When the cached async job have already encountered a linking
  error that gets wrapped into a rejection, but is still later
  in line to throw on it, just unwrap and throw the linking error
  from require().

PR-URL: https://github.com/nodejs/node/pull/57187
Fixes: https://github.com/nodejs/node/issues/57172
Refs: https://github.com/shufo/prettier-plugin-blade/issues/311
Refs: https://github.com/fisker/prettier-plugin-blade-311
Refs: https://github.com/mochajs/mocha/issues/5290
Refs: https://github.com/JoshuaKGoldberg/repros/tree/mocha-missing-module-cyclic
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2025-03-04 07:34:34 +00:00
Guy Bedford
db4dcc05ac esm: support source phase imports for WebAssembly
PR-URL: https://github.com/nodejs/node/pull/56919
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2025-02-28 09:52:47 -08:00
Chengzhong Wu
90ab559f4d
typings: fix ImportModuleDynamicallyCallback return type
PR-URL: https://github.com/nodejs/node/pull/57160
Refs: https://github.com/nodejs/node/pull/56919/files#r1955336054
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-02-21 18:06:34 +01:00
Joyee Cheung
8d10bc7b09 module: improve error message from asynchronicity in require(esm)
- Improve the error message that shows up when there is a race
  from doing require(esm) and import(esm) at the same time.
- Improve error message of ERR_REQUIRE_ASYNC_MODULE by showing
  parent and target file names, if available.

Drive-by: split the require(tla) tests since we are modifying
the tests already.

PR-URL: https://github.com/nodejs/node/pull/57126
Refs: https://github.com/fisker/prettier-issue-17139
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2025-02-20 17:22:08 +00:00
Jacob Smith
ba6800d1d6
esm: fix jsdoc type refs to ModuleJobBase in esm/loader
Co-Authored-By: Carlos Espa <43477095+Ceres6@users.noreply.github.com>
PR-URL: https://github.com/nodejs/node/pull/56499
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2025-01-10 14:44:43 +01:00
Marco Ippolito
da3f388c14
module: support eval with ts syntax detection
PR-URL: https://github.com/nodejs/node/pull/56285
Refs: https://github.com/nodejs/typescript/issues/17
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
2024-12-24 16:48:02 +00:00
Joyee Cheung
e85964610c module: implement module.registerHooks()
PR-URL: https://github.com/nodejs/node/pull/55698
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
2024-12-09 23:27:08 +00:00
Joyee Cheung
8aac7da7d6
module: fix error thrown from require(esm) hitting TLA repeatedly
This tracks the asynchronicity in the ModuleWraps when they turn out to
contain TLA after instantiation, and throw the right error
(ERR_REQUIRE_ASYNC_MODULE) when it's required again. It removes
the freezing of ModuleWraps since it's not meaningful to freeze
this when the rest of the module loader is mutable, and we
can record the asynchronicity in the ModuleWrap right after
compilation after we get a V8 upgrade that contains
v8::Module::HasTopLevelAwait() instead of searching through
the module graph repeatedly which can be slow.

PR-URL: https://github.com/nodejs/node/pull/55520
Fixes: https://github.com/nodejs/node/issues/55516
Refs: https://github.com/nodejs/node/issues/52697
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
2024-10-29 21:15:19 +00:00
Joyee Cheung
06206af181
module: unflag --experimental-require-module
This unflags --experimental-require-module so require(esm) can be
used without the flag. For now, when require() actually encounters
an ESM, it will still emit an experimental warning. To opt out
of the feature, --no-experimental-require-module can be used.

There are some tests specifically testing ERR_REQUIRE_ESM. Some
of them are repurposed to test --no-experimental-require-module.
Some of them are modified to just expect loading require(esm) to
work, when it's appropriate.

PR-URL: https://github.com/nodejs/node/pull/55085
Refs: https://github.com/nodejs/node/issues/52697
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
2024-09-26 14:21:37 +00:00
Nathan Baulch
4c045351c1
lib: fix typos
PR-URL: https://github.com/nodejs/node/pull/55065
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2024-09-25 14:35:18 +00:00
Aviv Keller
5c22d19f44
lib, tools: remove duplicate requires
PR-URL: https://github.com/nodejs/node/pull/54987
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2024-09-25 08:51:28 +00:00
Aviv Keller
574f2dd517
lib: prefer optional chaining
PR-URL: https://github.com/nodejs/node/pull/55045
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2024-09-24 19:48:15 +00:00
Joyee Cheung
3ac5b49d85
module: refator ESM loader for adding future synchronous hooks
This lays the foundation for supporting synchronous hooks proposed
in https://github.com/nodejs/loaders/pull/198 for ESM.

- Corrects and adds several JSDoc comments for internal functions
  of the ESM loader, as well as explaining how require() for
  import CJS work in the special resolve/load paths. This doesn't
  consolidate it with import in require(esm) yet due to caching
  differences, which is left as a TODO.
- The moduleProvider passed into ModuleJob is replaced as
  moduleOrModulePromise, we call the translators directly in the
  ESM loader and verify it right after loading for clarity.
- Reuse a few refactored out helpers for require(esm) in
  getModuleJobForRequire().

PR-URL: https://github.com/nodejs/node/pull/54769
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2024-09-17 18:38:33 +00:00
Antoine du Hamel
53cdffea20
esm: throw ERR_REQUIRE_ESM instead of ERR_INTERNAL_ASSERTION
PR-URL: https://github.com/nodejs/node/pull/54868
Fixes: https://github.com/nodejs/node/issues/54773
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
2024-09-11 21:48:02 +00:00
Antoine du Hamel
2ef33af16e
esm: fix support for URL instances in import.meta.resolve
PR-URL: https://github.com/nodejs/node/pull/54690
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: James M Snell <jasnell@gmail.com>
2024-09-10 01:00:33 +02:00
Antoine du Hamel
d0f5943363
test_runner: do not expose internal loader
PR-URL: https://github.com/nodejs/node/pull/54106
Fixes: https://github.com/nodejs/node/issues/54071
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2024-08-13 15:17:50 +02:00
Rafael Gonzaga
5ac969fdca
lib,src: drop --experimental-network-imports
PR-URL: https://github.com/nodejs/node/pull/53822
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2024-07-28 16:33:05 +00:00
Marco Ippolito
35f92d953c
module: add --experimental-strip-types
PR-URL: https://github.com/nodejs/node/pull/53725
Refs: https://github.com/nodejs/loaders/issues/217
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruy Adorno <ruy@vlt.sh>
2024-07-24 16:30:06 +00:00
Joyee Cheung
e77aac2a5f module: add __esModule to require()'d ESM
Tooling in the ecosystem have been using the __esModule property to
recognize transpiled ESM in consuming code. For example, a 'log'
package written in ESM:

export function log(val) { console.log(val); }

Can be transpiled as:

exports.__esModule = true;
exports.default = function log(val) { console.log(val); }

The consuming code may be written like this in ESM:

import log from 'log'

Which gets transpiled to:

const _mod = require('log');
const log = _mod.__esModule ? _mod.default : _mod;

So to allow transpiled consuming code to recognize require()'d real ESM
as ESM and pick up the default exports, we add a __esModule property by
building a source text module facade for any module that has a default
export and add .__esModule = true to the exports. We don't do this to
modules that don't have default exports to avoid the unnecessary
overhead. This maintains the enumerability of the re-exported names
and the live binding of the exports.

The source of the facade is defined as a constant per-isolate property
required_module_facade_source_string, which looks like this

export * from 'original';
export { default } from 'original';
export const __esModule = true;

And the 'original' module request is always resolved by
createRequiredModuleFacade() to wrap which is a ModuleWrap wrapping
over the original module.

PR-URL: https://github.com/nodejs/node/pull/52166
Refs: https://github.com/nodejs/node/issues/52134
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
2024-07-11 18:59:31 +00:00
RafaelGSS
fbdfe9399c lib: add diagnostics_channel events to module loading
This commit adds a tracing channel for module loading
through `import()` and `require()`.

Co-Authored-By: Stephen Belanger <admin@stephenbelanger.com>
PR-URL: https://github.com/nodejs/node/pull/44340
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
2024-06-20 21:25:04 -03:00
Yagiz Nizipli
852fa55813
lib: reduce amount of caught URL errors
PR-URL: https://github.com/nodejs/node/pull/52658
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Lemire <daniel@lemire.me>
2024-06-13 18:32:59 +00:00
Matteo Collina
8c5c2c18b6
Revert "module: have a single hooks thread for all workers"
This reverts commit 22cb99d073.

PR-URL: https://github.com/nodejs/node/pull/53183
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
2024-06-02 22:10:34 +00:00
Michaël Zasso
fac55e3ef9
lib,doc: replace references to import assertions
Use "import attributes" and "type attribute" instead.

PR-URL: https://github.com/nodejs/node/pull/52998
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
2024-05-17 08:07:48 +00:00
Gabriel Bota
22cb99d073
module: have a single hooks thread for all workers
PR-URL: https://github.com/nodejs/node/pull/52706
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
2024-05-08 02:20:48 +00:00
Chengzhong Wu
d5c7ffd7b6
lib,src: iterate module requests of a module wrap in JS
Avoid repetitively calling into JS callback from C++ in
`ModuleWrap::Link`. This removes the convoluted callback style of the
internal `ModuleWrap` link step.

PR-URL: https://github.com/nodejs/node/pull/52058
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2024-04-25 10:33:15 +00:00
Yagiz Nizipli
1df52e60eb
typings: fix invalid JSDoc declarations
PR-URL: https://github.com/nodejs/node/pull/52659
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2024-04-24 18:07:22 +02:00
Antoine du Hamel
a596af0819
tools: add lint rule to keep primordials in ASCII order
PR-URL: https://github.com/nodejs/node/pull/52592
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
2024-04-21 16:53:08 +00:00
Joyee Cheung
468fe9eb08
module: fix submodules loaded by require() and import()
Previously there is an edge case where submodules loaded by require()
may not be loaded by import() again from different intermediate
edges in the graph. This patch fixes that, added tests, and added
debug logs.

Drive-by: make loader a private field so it doesn't show up in logs.
PR-URL: https://github.com/nodejs/node/pull/52487
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
2024-04-16 14:07:44 +00:00
Jacob Smith
e0ed09d519
module: tidy code and comments
PR-URL: https://github.com/nodejs/node/pull/52437
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Feng Yu <F3n67u@outlook.com>
2024-04-13 19:41:20 +00:00
Joyee Cheung
db1746182b
module: disallow CJS <-> ESM edges in a cycle from require(esm)
This patch disallows CJS <-> ESM edges when they come from
require(esm) requested in ESM evalaution.

Drive-by: don't reuse the cache for imported CJS modules to stash
source code of required ESM because the former is also used for
cycle detection.

PR-URL: https://github.com/nodejs/node/pull/52264
Fixes: https://github.com/nodejs/node/issues/52145
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
2024-04-08 14:45:55 +00:00
Joyee Cheung
d6b57f6629
module: centralize SourceTextModule compilation for builtin loader
This refactors the code that compiles SourceTextModule for the
built-in ESM loader to use a common routine so that it's easier
to customize cache handling for the ESM loader. In addition
this introduces a common symbol for import.meta and import()
so that we don't need to create additional closures as handlers,
since we can get all the information we need from the V8 callback
already. This should reduce the memory footprint of ESM as well.

PR-URL: https://github.com/nodejs/node/pull/52291
Refs: https://github.com/nodejs/node/issues/47472
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2024-04-03 23:31:48 +00:00
Joyee Cheung
5f7fad2605
module: support require()ing synchronous ESM graphs
This patch adds `require()` support for synchronous ESM graphs under
the flag `--experimental-require-module`

This is based on the the following design aspect of ESM:

- The resolution can be synchronous (up to the host)
- The evaluation of a synchronous graph (without top-level await) is
  also synchronous, and, by the time the module graph is instantiated
  (before evaluation starts), this is is already known.

If `--experimental-require-module` is enabled, and the ECMAScript
module being loaded by `require()` meets the following requirements:

- Explicitly marked as an ES module with a `"type": "module"` field in
  the closest package.json or a `.mjs` extension.
- Fully synchronous (contains no top-level `await`).

`require()` will load the requested module as an ES Module, and return
the module name space object. In this case it is similar to dynamic
`import()` but is run synchronously and returns the name space object
directly.

```mjs
// point.mjs
export function distance(a, b) {
  return (b.x - a.x) ** 2 + (b.y - a.y) ** 2;
}
class Point {
  constructor(x, y) { this.x = x; this.y = y; }
}
export default Point;
```

```cjs
const required = require('./point.mjs');
// [Module: null prototype] {
//   default: [class Point],
//   distance: [Function: distance]
// }
console.log(required);

(async () => {
  const imported = await import('./point.mjs');
  console.log(imported === required);  // true
})();
```

If the module being `require()`'d contains top-level `await`, or the
module graph it `import`s contains top-level `await`,
[`ERR_REQUIRE_ASYNC_MODULE`][] will be thrown. In this case, users
should load the asynchronous module using `import()`.

If `--experimental-print-required-tla` is enabled, instead of throwing
`ERR_REQUIRE_ASYNC_MODULE` before evaluation, Node.js will evaluate the
module, try to locate the top-level awaits, and print their location to
help users fix them.

PR-URL: https://github.com/nodejs/node/pull/51977
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
2024-03-18 18:10:06 +08:00
Joyee Cheung
575ced8139
module: print location of unsettled top-level await in entry points
When the entry point is a module and the graph it imports still
contains unsettled top-level await when the Node.js instance
finishes the event loop, search from the entry point module
for unsettled top-level await and print their location.

To avoid unnecessary overhead, we register a promise that only
gets settled when the entry point graph evaluation returns
from await, and only search the module graph if it's still
unsettled by the time the instance is exiting.

This patch only handles this for entry point modules. Other kinds of
modules are more complicated so will be left for the future.

Drive-by: update the terminology "unfinished promise" to the
more correct one "unsettled promise" in the codebase.

PR-URL: https://github.com/nodejs/node/pull/51999
Fixes: https://github.com/nodejs/node/issues/42868
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
2024-03-10 08:21:22 +08:00
Joyee Cheung
075c95f61f
module: refactor ESM loader initialization and entry point handling
Split the `internal/process/esm_loader` file which contains the
singleton cascaded loader:

- The the singleton cascaded loader now directly resides in
  `internal/modules/esm/loader`, where the constructor also lives.
  This file is the root of most circular dependency of ESM code,
  (because components of the loader need the singleton itself),
  so this makes the dependency more obvious. Added comments about
  loading it lazily to avoid circular dependency.
- The getter to the cascaded loader is also turned into a method
  to make the side effect explicit.
- The sequence of `loadESM()` and `handleMainPromise` is now merged
  together into `runEntryPointWithESMLoader()` in
  `internal/modules/run_main` because this is intended to run entry
  points with the ESM loader and not just any module.
- Documents how top-level await is handled.

PR-URL: https://github.com/nodejs/node/pull/51999
Fixes: https://github.com/nodejs/node/issues/42868
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
2024-03-10 08:21:18 +08:00
Joyee Cheung
9c5ef11026 module: move the CJS exports cache to internal/modules/cjs/loader
This puts it together with the cjsParseCache and reduces the
circular dependency on the singleton loader, which is the
only place where this cache is stored.

Drive-by: remove always-false module status check because there's
no longer a local module variable after
https://github.com/nodejs/node/pull/34605 which is now invalid
leftover code at this point and only doesn't throw because
we happen to have a top-level variable called module.

PR-URL: https://github.com/nodejs/node/pull/51157
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2023-12-21 17:17:31 -08:00
Chengzhong Wu
fc2862b7f5
module: bootstrap module loaders in shadow realm
This bootstraps ESM loaders in the ShadowRealm with
`ShadowRealm.prototype.importValue` as its entry point and enables
loading ESM and CJS modules in the ShadowRealm. The module is imported
without a parent URL and resolved with the current process's working
directory.

PR-URL: https://github.com/nodejs/node/pull/48655
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2023-11-13 22:09:47 +08:00
legendecas
6b7197cb2b
module: remove useCustomLoadersIfPresent flag
The flag is always true and can be determined by isLoaderWorker solely.

PR-URL: https://github.com/nodejs/node/pull/48655
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2023-11-13 22:09:32 +08:00
Antoine du Hamel
d1ef6aa2db
esm: use import attributes instead of import assertions
The old import assertions proposal has been
renamed to "import attributes" with the follwing major changes:

1. The keyword is now `with` instead of `assert`.
2. Unknown assertions cause an error rather than being ignored,

This commit updates the documentation to encourage folks to use the new
syntax, and add aliases for module customization hooks.

PR-URL: https://github.com/nodejs/node/pull/50140
Fixes: https://github.com/nodejs/node/issues/50134
Refs: 159c82c5e6
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
2023-10-14 03:52:38 +00:00
Geoffrey Booth
f91b4e2bf0
esm: update loaders warning
PR-URL: https://github.com/nodejs/node/pull/49633
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
2023-09-19 03:59:50 +00:00
Geoffrey Booth
7517c9f95b
module, esm: jsdoc for modules files
PR-URL: https://github.com/nodejs/node/pull/49523
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2023-09-19 02:48:24 +00:00
Antoine du Hamel
56ecf29283
esm: fix support for URL instances in register
PR-URL: https://github.com/nodejs/node/pull/49655
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2023-09-17 00:48:48 +00:00
Joyee Cheung
bc9a875c99 module: use symbol in WeakMap to manage host defined options
Previously when managing the importModuleDynamically callback of
vm.compileFunction(), we use an ID number as the host defined option
and maintain a per-Environment ID -> CompiledFnEntry map to retain
the top-level referrer function returned by vm.compileFunction() in
order to pass it back to the callback, but it would leak because with
how we used v8::Persistent to maintain this reference, V8 would not
be able to understand the cycle and would just think that the
CompiledFnEntry was supposed to live forever. We made an attempt
to make that reference known to V8 by making the CompiledFnEntry weak
and using a private symbol to make CompiledFnEntry strongly
references the top-level referrer function in
https://github.com/nodejs/node/pull/46785, but that turned out to be
unsound, because the there's no guarantee that the top-level function
must be alive while import() can still be initiated from that
function, since V8 could discard the top-level function and only keep
inner functions alive, so relying on the top-level function to keep
the CompiledFnEntry alive could result in use-after-free which caused
a revert of that fix.

With this patch we use a symbol in the host defined options instead of
a number, because with the stage-3 symbol-as-weakmap-keys proposal
we could directly use that symbol to keep the referrer alive using a
WeakMap. As a bonus this also keeps the other kinds of referrers
alive as long as import() can still be initiated from that
Script/Module, so this also fixes the long-standing crash caused by
vm.Script being GC'ed too early when its importModuleDynamically
callback still needs it.

PR-URL: https://github.com/nodejs/node/pull/48510
Refs: https://github.com/nodejs/node/issues/44211
Refs: https://github.com/nodejs/node/issues/42080
Refs: https://github.com/nodejs/node/issues/47096
Refs: https://github.com/nodejs/node/issues/43205
Refs: https://github.com/nodejs/node/issues/38695
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
2023-09-14 15:42:24 +00:00