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

[v22.x] backport unflagging of --experimental-require-module and related fixes/refactorings #55217

Open
wants to merge 10 commits into
base: v22.x-staging
Choose a base branch
from

Conversation

joyeecheung
Copy link
Member

@joyeecheung joyeecheung commented Oct 1, 2024

This backports the following PRs that are related to the unflagging of --experimental-require-module:

Note that I don't think this backport PR is strictly required - the PRs seem to land cleanly on v22.x except the unflagging commit has a small conflict in the YAML changelog description. This PR is mostly opened to look for regressions in v22 with CITGM.

Refs: #52697

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/loaders

@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. v22.x v22.x Issues that can be reproduced on v22.x or PRs targeting the v22.x-staging branch. labels Oct 1, 2024
@RedYetiDev RedYetiDev added module Issues and PRs related to the module subsystem. commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. labels Oct 1, 2024
@joyeecheung
Copy link
Member Author

@RedYetiDev RedYetiDev added the needs-citgm PRs that need a CITGM CI run. label Oct 1, 2024
@joyeecheung
Copy link
Member Author

joyeecheung commented Oct 2, 2024

Some regressions found:

  1. yarn is expecting ERR_REQUIRE_ESM in its tests, probably to check that they didn't do anything to alter Node.js module loading https://github.com/yarnpkg/berry/blob/33f249b6cc06db1803f03eb5f17306a23d11115c/packages/acceptance-tests/pkg-tests-specs/sources/pnp-esm.test.ts#L617
  2. Gulp tests are breaking because they don't expect the experimental warning coming out of Node.js https://github.com/gulpjs/gulp/blob/2fa4981a910d7bdedb758bd09868620c9bb21d54/test/index.test.js#L90 (I am not sure how they load the .mjs configs, though it seems they are also doing a try-catch of require(config) somewhere)
  3. 2 also happened to Jest.
  4. In local testing, I also noticed that the debug package (used by npm, etc.) has a try { require(esm) } catch { /* fallback */ } pattern here, which only gets improvements out of require(esm) support after the unflagging, but then the experimental warning would also break the output.

I think for backporting to v22.x we should probably do some changes:

a. Provides process.features.require_module for feature detection
b. Do not emit the experimental warning if it's coming out of node_modules

b would not fix the test regressions 2-4, the packages still need to update their tests which is to be expected. But at least it would not break the CLIs for end users.

@joyeecheung
Copy link
Member Author

joyeecheung commented Oct 2, 2024

As for esm, from what I can tell in standard-things/esm#883 it seems to have been broken in different ways since many major releases of Node.js ago. The regression that predated unflagging of require(esm) I found in #55085 (comment) also seem to come from some TDZ issue in the way the package is written (it relies on access to Node.js internals and seem to expect certain internals to be invoked in certain order). It doesn't seem to be very cost-effective to do anything about it on v22.

@richardlau
Copy link
Member

I think for backporting to v22.x we should probably do some changes:

a. Provides process.features.require_module for feature detection
b. Do not emit the experimental warning if it's coming out of node_modules

b would not fix the test regressions 2-4, the packages still need to update their tests which is to be expected. But at least it would not break the CLIs for end users.

These SGTM

@joyeecheung
Copy link
Member Author

Opened #55241 for feature detection.

@joyeecheung
Copy link
Member Author

Added a commit from #55243 and a commit for v22.x specifically (and maybe v20.x in the future) to disable the warning when require() comes from node_modules.

@targos
Copy link
Member

targos commented Oct 4, 2024

I just updated v22.x-staging so this now has conflicts because of duplicated commits I guess.

@joyeecheung
Copy link
Member Author

Rebased to drop the duplicate commits. Also cherry-picked #55243 and #55241 from the main branch. I think for backport to v22.x it is ready, note that the last commit (silence the experimental warning when it comes from node_modules) is only targeting v22.x, as proposed in #55217 (comment) and agreed in the last TSC meeting.

@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label Oct 7, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Oct 7, 2024
@nodejs-github-bot
Copy link
Collaborator

@aduh95
Copy link
Contributor

aduh95 commented Oct 8, 2024

Can you rebase please?

@joyeecheung joyeecheung force-pushed the backport-require-esm-2 branch 2 times, most recently from 5ed6462 to 898396a Compare October 8, 2024 19:00
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

@nicolo-ribaudo
Copy link
Contributor

nicolo-ribaudo commented Nov 7, 2024

Backporting the unflagging without backporting #55502 and #55520 at the same time would break everybody using a Babel version that is more than a few weeks old and released in 2024.

joyeecheung added a commit to joyeecheung/node that referenced this pull request Nov 7, 2024
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: nodejs#55085
Backport-PR-URL: nodejs#55217
Refs: nodejs#52697
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Rafael Gonzaga <[email protected]>
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: LiviaMedeiros <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
Reviewed-By: Richard Lau <[email protected]>
joyeecheung added a commit to joyeecheung/node that referenced this pull request Nov 7, 2024
This is faster and more consistent with other places using the
regular expression to detect node_modules.

PR-URL: nodejs#55243
Backport-PR-URL: nodejs#55217
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Richard Lau <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Refs: nodejs#52697
joyeecheung added a commit to joyeecheung/node that referenced this pull request Nov 7, 2024
Some packages have been using try-catch to load require(esm)
in environments that are available. In 23, where require(esm)
is unflagged, we emit an experimental warning when require()
is used to load ESM. To backport require(esm) to older LTS
releases, however, this could break existing CLI output.
To reduce the disruption for LTS, on older release lines,
this commit is applied to skip the warning if require(esm)
comes from node_modules. This warning will be eventually
removed when require(esm) becomes stable.

PR-URL: nodejs#55217
Refs: nodejs#52697
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
@joyeecheung
Copy link
Member Author

@nicolo-ribaudo Thanks for pointing that out. I think we should wait for those patches to qualify to unflag require(esm). If it misses the next semver-minor train, then we can wait for the next one.

joyeecheung and others added 2 commits November 12, 2024 08:53
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: nodejs#55085
Backport-PR-URL: nodejs#55217
Refs: nodejs#52697
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Rafael Gonzaga <[email protected]>
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: LiviaMedeiros <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
Reviewed-By: Richard Lau <[email protected]>
PR-URL: nodejs#54563
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
joyeecheung added a commit to joyeecheung/node that referenced this pull request Nov 12, 2024
This is faster and more consistent with other places using the
regular expression to detect node_modules.

PR-URL: nodejs#55243
Backport-PR-URL: nodejs#55217
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Richard Lau <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Refs: nodejs#52697
joyeecheung added a commit to joyeecheung/node that referenced this pull request Nov 12, 2024
Some packages have been using try-catch to load require(esm)
in environments that are available. In 23, where require(esm)
is unflagged, we emit an experimental warning when require()
is used to load ESM. To backport require(esm) to older LTS
releases, however, this could break existing CLI output.
To reduce the disruption for LTS, on older release lines,
this commit is applied to skip the warning if require(esm)
comes from node_modules. This warning will be eventually
removed when require(esm) becomes stable.

PR-URL: nodejs#55217
Refs: nodejs#52697
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
@joyeecheung
Copy link
Member Author

Updated the branch a bit and included the following commits:

module: unflag --experimental-require-module
module: support 'module.exports' interop export in require(esm)
doc: update `require(ESM)` history and stability status
module: use kNodeModulesRE to detect node_modules
module: check --experimental-require-module separately from detection
src: implement IsInsideNodeModules() in C++
module: include module information in require(esm) warning
module: do not warn when require(esm) comes from node_modules
module: allow ESM that failed to be required to be re-imported
module: trim off internal stack frames for require(esm) warnings

@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label Nov 12, 2024
aduh95 and others added 8 commits November 12, 2024 09:31
PR-URL: nodejs#55199
Reviewed-By: Moshe Atlow <[email protected]>
Reviewed-By: Guy Bedford <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
This is faster and more consistent with other places using the
regular expression to detect node_modules.

PR-URL: nodejs#55243
Backport-PR-URL: nodejs#55217
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Richard Lau <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Refs: nodejs#52697
Previously we assumed if `--experimental-detect-module` is true, then
`--experimental-require-module` is true, which isn't the case, as
the two can be enabled/disabled separately. This patch fixes the
checks so `--no-experimental-require-module` is still effective when
`--experimental-detect-module` is enabled.

Drive-by: make the assertion messages more informative and remove
obsolete TODO about allowing TLA in entrypoints handled by
require(esm).

PR-URL: nodejs#55250
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Jacob Smith <[email protected]>
Reviewed-By: Rafael Gonzaga <[email protected]>
This previously compiles a script and run it in a new context
to avoid global pollution, which is more complex than necessary
and can be too slow for it to be reused in other cases. The
new implementation just checks the frames in C++ which is safe
from global pollution, faster and simpler.

The previous implementation also had a bug when the call site
is in a ESM, because ESM have URLs as their script names,
which don't start with '/' or '\' and will be skipped. The new
implementation removes the skipping to fix it for ESM.

PR-URL: nodejs#55286
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
When emitting the experimental warning for `require(esm)`, include
information about the parent module and the module being require()-d
to help users locate and update them.

PR-URL: nodejs#55397
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Stephen Belanger <[email protected]>
Reviewed-By: Chemi Atlow <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Chengzhong Wu <[email protected]>
Some packages have been using try-catch to load require(esm)
in environments that are available. In 23, where require(esm)
is unflagged, we emit an experimental warning when require()
is used to load ESM. To backport require(esm) to older LTS
releases, however, this could break existing CLI output.
To reduce the disruption for LTS, on older release lines,
this commit is applied to skip the warning if require(esm)
comes from node_modules. This warning will be eventually
removed when require(esm) becomes stable.

PR-URL: nodejs#55217
Refs: nodejs#52697
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
When a ESM module cannot be loaded by require due to the presence
of TLA, its module status would be stopped at kInstantiated. In
this case, when it's imported again, we should allow it to be
evaluated asynchronously, as it's also a common pattern for users
to retry with dynamic import when require fails.

PR-URL: nodejs#55502
Fixes: nodejs#55500
Refs: nodejs#52697
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Chemi Atlow <[email protected]>
Trim off irrelevant internal stack frames for require(esm) warnings
so it's easier to locate where the call comes from when
--trace-warnings is used.

PR-URL: nodejs#55496
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Paolo Insogna <[email protected]>
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Nov 12, 2024
Copy link
Contributor

Failed to start CI
   ⚠  Something was pushed to the Pull Request branch since the last approving review.
   ✘  Refusing to run CI on potentially unsafe PR
https://github.com/nodejs/node/actions/runs/11789132997

@github-actions github-actions bot added the request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. label Nov 12, 2024
@panva panva removed the request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. label Nov 14, 2024
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

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. module Issues and PRs related to the module subsystem. needs-ci PRs that need a full CI run. needs-citgm PRs that need a CITGM CI run. v22.x v22.x Issues that can be reproduced on v22.x or PRs targeting the v22.x-staging branch.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants