fix: hoist import.meta as module-level variable with complete properties#20658
fix: hoist import.meta as module-level variable with complete properties#20658alexander-akait merged 11 commits intomainfrom
Conversation
🦋 Changeset detectedLatest commit: 269ad30 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This PR is packaged and the instant preview is available (f757352). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@f757352
yarn add -D webpack@https://pkg.pr.new/webpack@f757352
pnpm add -D webpack@https://pkg.pr.new/webpack@f757352 |
alexander-akait
left a comment
There was a problem hiding this comment.
Let's remove from skipping tests from test262 which now we are passed
Merging this PR will degrade performance by 25.39%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Simulation | benchmark "devtool-source-map", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
40.1 ms | 33.2 ms | +20.65% |
| ⚡ | Memory | benchmark "many-modules-commonjs", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
534.3 KB | 387.1 KB | +38.05% |
| ❌ | Memory | benchmark "context-esm", scenario '{"name":"mode-production","mode":"production"}' |
8 MB | 10.1 MB | -20.42% |
| ⚡ | Memory | benchmark "devtool-eval-source-map", scenario '{"name":"mode-production","mode":"production"}' |
7.8 MB | 6.3 MB | +24.32% |
| ❌ | Memory | benchmark "react", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
645 KB | 864.4 KB | -25.39% |
Comparing fix/import-meta-standalone-expression (269ad30) with main (8e6aed2)
| "webpack": patch | ||
| --- | ||
|
|
||
| fix: `import.meta` as standalone expression now returns a complete object with known properties (`url`, `webpack`, `main`, `env`) instead of an empty object `({})`, and hoists it as a module-level variable to ensure `import.meta === import.meta` identity. In `preserve-unknown` mode (ESM output), the hoisted object merges runtime `import.meta` properties via `Object.assign`. |
There was a problem hiding this comment.
Let's remove fix: from here too, it will be in the patch section already
|
Ignore:
it is already fixed in the main, it is due a new fix in |
|
@xiaoxiaojx looks like we still have some problems with test262 |
eda4b30 to
4678f05
Compare
|
@alexander-akait Yeah, the latest failure in import-attributes (text) doesn’t seem related to my changes — pulling the latest submodule on the main branch also fails. I'll continue looking into it tomorrow. |
|
@xiaoxiaojx Yeah, let's add them to skip test and fix in other PR, I think they will be easy to fix |
Previously, standalone `import.meta` expressions (e.g., `return import.meta`,
`const meta = import.meta`) were replaced with an empty object `({})`, losing
all known properties and creating a new object on each reference.
Now uses ModuleInitFragmentDependency to hoist a `__webpack_import_meta__`
variable at module scope with url, webpack, main, and env properties. All
standalone `import.meta` references resolve to this single variable, ensuring
object identity (`import.meta === import.meta`) and property preservation.
In `preserve-unknown` mode (ESM output), the hoisted variable uses
`Object.assign(import.meta, {...})` to retain runtime-assigned properties.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Move comprehensive standalone import.meta tests (variable assignment, return value, argument passing, object identity, runtime properties) from test/cases/ to test/configCases/parsing/import-meta-standalone/ with ESM output config to avoid SyntaxError in non-module test suites. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Remove 5 import.meta test262 cases from the known bugs list:
- same-object-returned.js
- import-meta-is-an-ordinary-object.js
- distinct-for-each-module.js
- syntax/goal-module-nested-function.js
- syntax/goal-module.js
These now pass because standalone import.meta is hoisted as a
module-level variable with Object.assign(import.meta, {...}).
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Use parser.state.module.moduleArgument instead of RuntimeGlobals.module in both standalone and destructuring paths. ModuleInitFragmentDependency uses raw strings, so RuntimeGlobals.module resolves to literal "module" but in ESM output the parameter is named __webpack_module__. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Bundler limitation: all modules in the bundle share a single
bundle-level import.meta object, so distinct-per-module identity
cannot be satisfied when using Object.assign(import.meta, {...}).
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
aac0c28 to
269ad30
Compare
| /Critical dependency: 'import\.meta' cannot be used as a standalone expression\. For static analysis, its properties must be accessed directly \(e\.g\., 'import\.meta\.url'\) or through destructuring\./ | ||
| ] | ||
| ]; | ||
| module.exports = []; |
There was a problem hiding this comment.
Pedantic: because this warnings.js file (and, similarly, import-meta/warnings.js) now exports an empty list of expected warnings: can it be removed entirely?
(I wonder whether eslint could have detected this if warnings.js files were not in the ignore-list?)
Summary
Previously, standalone
import.metaexpressions (e.g.,return import.meta,const meta = import.meta) were replaced with an empty object({}), losing all known properties and creating a new object on each reference.Now uses ModuleInitFragmentDependency to hoist a
__webpack_import_meta__variable at module scope with url, webpack, main, and env properties. All standaloneimport.metareferences resolve to this single variable, ensuring object identity (import.meta === import.meta) and property preservation.In
preserve-unknownmode (ESM output), the hoisted variable usesObject.assign(import.meta, {...})to retain runtime-assigned properties.What kind of change does this PR introduce?
fix
Did you add tests for your changes?
Yes
Does this PR introduce a breaking change?
No
If relevant, what needs to be documented once your changes are merged or what have you already documented?
Nothing