refactor: export lexical runtime globals for esm chunks#14741
refactor: export lexical runtime globals for esm chunks#14741LingyuCoder wants to merge 9 commits into
Conversation
📦 Binary Size-limit
❌ Size increased by 73.25KB from 66.58MB to 66.65MB (⬆️0.11%) |
Rsdoctor Bundle Diff AnalysisFound 5 projects in monorepo, 5 projects with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 popular-libsPath:
📁 react-10kPath:
📁 react-5kPath:
📁 react-1kPath:
📁 ui-componentsPath:
Generated by Rsdoctor GitHub Action |
aa258ea to
0af5acb
Compare
2dbde1d to
40f063b
Compare
Merging this PR will not alter performance
Comparing Footnotes
|
40f063b to
afc24cb
Compare
…runtime-globals # Conflicts: # tests/rspack-test/esmOutputCases/create-require/import-meta-url-resolve/__snapshots__/runtimeModeSnapshot/esm.snap.txt
There was a problem hiding this comment.
Pull request overview
This PR refactors Rspack “runtime mode” ESM output to export/import runtime globals as lexical bindings from the runtime chunk (instead of mounting them on __rspack_context), enabling better tree-shaking for downstream consumers when using split modern-module runtime chunks. It also introduces a systematic way to pre-reserve runtime-module-local variable names (derived from EJS templates) to prevent name collisions with user modules, and refreshes runtime-mode ESM snapshots accordingly.
Changes:
- Switch runtime-mode ESM output from
__rspack_context.*access to direct lexical imports/exports (e.g.rspackRequire,moduleFactories,definePropertyGetters,makeNamespaceObject, etc.). - Add “runtime module variable” extraction/registration (via EJS
var()/fn()helpers +inventoryregistration) to reserve identifiers before runtime module instantiation and avoid userland naming conflicts. - Update runtime EJS templates and a large set of runtime-mode ESM output snapshots; add/adjust targeted test cases for collision and runtimeChunk=false scenarios.
Reviewed changes
Copilot reviewed 200 out of 202 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| crates/rspack_plugin_runtime/src/runtime_module/utils.rs | Allow HMR runtime-state rendering in the new export-based render mode. |
| crates/rspack_plugin_runtime/src/runtime_module/startup_chunk_dependencies.rs | Add runtime-module-variable extraction and stable template reuse for startup-chunk dependencies runtime module. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/startup_chunk_dependencies.ejs | Convert top-level declaration to EJS var() to support identifier reservation/deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/require_chunk_loading.ejs | Convert top-level var declaration to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/require_chunk_loading_with_hmr.ejs | Convert top-level function declaration to EJS fn() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/readfile_chunk_loading.ejs | Convert top-level var declaration to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/readfile_chunk_loading_with_hmr.ejs | Convert top-level function declaration to EJS fn() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/on_chunk_loaded.ejs | Convert top-level var declaration to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/module_chunk_loading.ejs | Convert top-level var declaration to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/module_chunk_loading_with_hmr.ejs | Convert top-level function declaration to EJS fn() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/load_script.ejs | Convert top-level var declaration to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/jsonp_chunk_loading_with_hmr.ejs | Convert top-level vars/functions to EJS var() / fn() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/jsonp_chunk_loading_with_callback.ejs | Convert top-level vars to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/javascript_hot_module_replacement.ejs | Convert top-level vars/functions to EJS var() / fn() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/import_scripts_chunk_loading.ejs | Convert top-level vars to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/import_scripts_chunk_loading_with_hmr.ejs | Convert top-level function to EJS fn() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/get_trusted_types_policy.ejs | Convert top-level var to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/create_fake_namespace_object.ejs | Convert top-level vars to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/chunk_preload_trigger.ejs | Convert top-level var to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/chunk_prefetch_trigger.ejs | Convert top-level var to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/runtime/auto_public_path.ejs | Convert top-level vars to EJS var() for deconfliction. |
| crates/rspack_plugin_runtime/src/runtime_module/require_js_chunk_loading.rs | Register runtime-module variables extracted from templates; reserve additional internal vars. |
| crates/rspack_plugin_runtime/src/runtime_module/readfile_chunk_loading.rs | Register runtime-module variables extracted from templates; reserve additional internal vars. |
| crates/rspack_plugin_runtime/src/runtime_module/on_chunk_loaded.rs | Register runtime-module variables and reuse template string constant. |
| crates/rspack_plugin_runtime/src/runtime_module/load_script.rs | Register runtime-module variables; reserve additional internal vars. |
| crates/rspack_plugin_runtime/src/runtime_module/jsonp_chunk_loading.rs | Register runtime-module variables; reserve additional internal vars. |
| crates/rspack_plugin_runtime/src/runtime_module/get_trusted_types_policy.rs | Register runtime-module variables and reuse template string constant. |
| crates/rspack_plugin_runtime/src/runtime_module/export_require.rs | Register runtime-module variables for temp export names used by the module. |
| crates/rspack_plugin_runtime/src/runtime_module/create_fake_namespace_object.rs | Register runtime-module variables extracted from the EJS template. |
| crates/rspack_plugin_runtime/src/runtime_module/chunk_preload_trigger.rs | Register runtime-module variables extracted from the EJS template. |
| crates/rspack_plugin_runtime/src/runtime_module/chunk_prefetch_trigger.rs | Register runtime-module variables extracted from the EJS template. |
| crates/rspack_plugin_runtime/src/runtime_module/auto_public_path.rs | Register runtime-module variables extracted from the EJS template. |
| crates/rspack_plugin_runtime/src/runtime_module/async_module.rs | Register runtime-module variables and treat export render mode as lexical-capable. |
| crates/rspack_plugin_runtime/src/helpers.rs | Add extraction of runtime-module variable names from EJS var()/fn() usage + unit test. |
| crates/rspack_plugin_mf/src/sharing/share_runtime_module.rs | Register runtime-module variables extracted from sharing EJS template. |
| crates/rspack_plugin_mf/src/sharing/initializeSharing.ejs | Convert top-level var declarations to EJS var() for deconfliction. |
| crates/rspack_plugin_mf/src/sharing/consume_shared_runtime_module.rs | Register runtime-module variables extracted from multiple consume-sharing templates. |
| crates/rspack_plugin_mf/src/container/embed_federation_runtime_module.rs | Register runtime-module variables extracted from federation embed templates; reuse template constants. |
| crates/rspack_plugin_mf/src/container/embed_federation_runtime_sync.ejs | Convert top-level var declarations to EJS var() for deconfliction. |
| crates/rspack_plugin_mf/src/container/embed_federation_runtime_async.ejs | Convert top-level var declarations to EJS var() for deconfliction. |
| crates/rspack_plugin_hmr/src/hot_module_replacement.rs | Register runtime-module variables extracted from HMR EJS template. |
| crates/rspack_plugin_extract_css/src/runtime/css_loading.ejs | Convert top-level declarations to EJS var(); adjust to use _get_chunk_css_filename helper variable. |
| crates/rspack_plugin_extract_css/src/runtime/css_loading_with_preload_link.ejs | Switch to _get_chunk_css_filename for CSS href generation. |
| crates/rspack_plugin_extract_css/src/runtime/css_loading_with_prefetch_link.ejs | Switch to _get_chunk_css_filename for CSS href generation. |
| crates/rspack_plugin_extract_css/src/runtime/css_loading_with_loading.ejs | Convert installedCssChunks to EJS var() for deconfliction. |
| crates/rspack_plugin_extract_css/src/runtime/css_loading_with_hmr.ejs | Convert top-level vars to EJS var(); switch to _get_chunk_css_filename. |
| crates/rspack_plugin_extract_css/src/plugin.rs | Use a custom export-global name for mini-css chunk filename under export render mode. |
| crates/rspack_plugin_esm_library/src/runtime.rs | Register runtime-module variables for ESM chunk loading runtime module. |
| crates/rspack_plugin_esm_library/src/render/runtime_mode/webpack.rs | Add a dedicated webpack-mode runtime renderer for ESM library runtime-mode output. |
| crates/rspack_plugin_css/src/runtime/mod.rs | Register runtime-module variables extracted from CSS runtime templates; reserve internal var. |
| crates/rspack_plugin_css/src/runtime/css_loading.ejs | Convert top-level declarations to EJS var()/fn() for deconfliction. |
| crates/rspack_plugin_css/src/runtime/css_loading_with_style.ejs | Convert top-level functions/vars to EJS fn()/var() for deconfliction. |
| crates/rspack_plugin_css/src/runtime/css_loading_with_hmr.ejs | Convert top-level vars to EJS var() for deconfliction. |
| crates/rspack_macros/src/runtime_module.rs | Extend #[impl_runtime_module] macro to optionally register runtime-module-variable providers via inventory. |
| crates/rspack_core/src/runtime_module.rs | Add runtime-module-variable provider plumbing (inventory collection + iterator). |
| crates/rspack_core/src/runtime_globals.rs | Add Rspack-export runtime variable naming and setter-name helper generation. |
| crates/rspack_core/src/lib.rs | Re-export inventory for macro-generated registrations. |
| crates/rspack_core/src/dependency/mod.rs | Export write-operation type used by runtime requirements dependency templates. |
| crates/rspack_core/src/compilation/build_module_graph/graph_updater/repair/context.rs | Ensure runtime_template is initialized during compilation repair context setup. |
| crates/rspack_core/src/artifacts/runtime_proxy_metadata_artifact.rs | Generalize lexical declaration rendering to allow name-mapping injection. |
| crates/rspack_core/Cargo.toml | Add inventory dependency for runtime-module-variable registration. |
| Cargo.lock | Lockfile update for new inventory dependency usage. |
| crates/rspack_plugin_javascript/src/runtime.rs | Export should_export_rspack_runtime_globals from runtime context. |
| crates/rspack_plugin_javascript/src/parser_plugin/import_meta_plugin.rs | Adjust import-meta assignment handling to propagate assignment op + rhs span into helper. |
| tests/rspack-test/esmOutputCases/**/snapshots/runtimeModeSnapshot/esm.snap.txt | Refresh runtime-mode ESM output snapshots to reflect lexical runtime-global exports/imports. |
| tests/rspack-test/esmOutputCases/basic/split-runtime-chunk/index.js | Add assertion around publicPath mutation behavior when splitting runtime chunk. |
| tests/rspack-test/esmOutputCases/basic/split-runtime-chunk/snapshots/esm.snap.txt | Refresh baseline (non-runtime-mode) snapshot to include publicPath mutation expectations. |
| tests/rspack-test/esmOutputCases/interop/runtime-module-variable-conflict/rspack.config.js | New test config to exercise runtime module variable name deconfliction. |
| tests/rspack-test/esmOutputCases/interop/runtime-module-variable-conflict/index.js | New test asserting userland bindings don’t conflict with runtime module variables. |
| tests/rspack-test/esmOutputCases/interop/runtime-module-variable-conflict/foo.mjs | New fixture module for the conflict test case. |
| tests/rspack-test/esmOutputCases/dynamic-import/import-cjs-runtime-chunk-false-entry-export/test.config.js | New test assertions ensuring runtimeChunk=false output doesn’t export rspack runtime globals. |
| tests/rspack-test/esmOutputCases/dynamic-import/import-cjs-runtime-chunk-false-async-chunk/test.config.js | Update expectations for runtime-mode ESM output to use lexical imports/exports and avoid re-exporting runtime bindings. |
| tests/rspack-test/esmOutputCases/basic/runtime-chunk-false/test.config.js | New test assertions ensuring runtimeChunk=false runtime-mode output avoids exporting __rspack_* globals. |
| tests/rspack-test/configCases/**/snapshot/runtimeModeSnapshot/*.txt | Refresh runtime-mode snapshots for config cases impacted by the new lexical runtime-global rendering. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a7c1f74a4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| sources.add(RawStringSource::from(render_rspack_runtime_exports( | ||
| context_fields, | ||
| context_fields.intersection(setters), |
There was a problem hiding this comment.
Emit setters for module-only runtime writes
In RspackExport mode, render_runtime_global_specifiers imports setter helpers for every module write recorded in CodeGenerationRuntimeRequirementsWrite, but this call only emits a setter when the same runtime global is also present in a runtime module's define/force_context fields. For globals such as SCRIPT_NONCE (e.g. import.meta.rspackNonce = "n" or __webpack_require__.nc = "n") there is no defining runtime module, so a split modern-module runtime chunk declares no setScriptNonce export while the entry chunk imports/calls it, causing the ESM module to fail during linking.
Useful? React with 👍 / 👎.
Summary
__rspack_*bindings from the runtime chunk instead of mounting them on__rspack_context__rspack_set_*Context
This is stacked on #14740. The base PR only enables the RuntimeModeEsmOutput context import coverage and fixes modern ESM chunk loading. This PR contains the lexical runtime-global export/import behavior needed for tree shaking when downstream consumers depend on the ESM output runtime chunk.
The behavior is scoped to output module builds using Rspack runtime mode with a split modern-module runtime chunk.
Checks
pnpm run build:binding:devpnpm run test:unit