Skip to content

fix(esm-lib): avoid exporting __webpack_require__ and useless runtime when runtimeChunk is false#13374

Merged
JSerFeng merged 4 commits intomainfrom
vk/fix-esm-lib-runtime-chunk-false
Mar 18, 2026
Merged

fix(esm-lib): avoid exporting __webpack_require__ and useless runtime when runtimeChunk is false#13374
JSerFeng merged 4 commits intomainfrom
vk/fix-esm-lib-runtime-chunk-false

Conversation

@JSerFeng
Copy link
Copy Markdown
Contributor

Summary

When runtimeChunk is set to false, the entry chunk serves as both the entry and the runtime chunk. Three issues existed in this scenario:

  • __webpack_require__ was exported from the entry chunk even though no other chunk imports it. Only pure runtime chunks (created by optimize_runtime_chunks) should export it.
  • An empty var __webpack_require__ = {}; scope was generated when REQUIRE_SCOPE was triggered by STARTUP_NO_DEFAULT without any actual REQUIRE usage.
  • REQUIRE was unconditionally added to chunk runtime requirements whenever any requirement was present, even for unrelated module codegen requirements that have nothing to do with __webpack_require__.

Changes

render.rs:

  • Check whether the chunk has entry modules before exporting __webpack_require__. Entry-with-runtime chunks (i.e. runtimeChunk: false, not split) must not export it, since nothing imports from them.
  • Remove the else if require_scope_used branch that generated var __webpack_require__ = {};. In the ESM library context, REQUIRE_SCOPE without REQUIRE is only triggered by STARTUP_NO_DEFAULT and produces dead code.

plugin.rs:

  • Track whether any ESM-library-specific feature (external modules, interop helpers) actually needs __webpack_require__, and only insert REQUIRE when that is the case.

Test plan

  • Added esmOutputCases/basic/runtime-chunk-false test case that verifies a simple ESM entry with runtimeChunk: false produces clean output with no __webpack_require__ artifacts.
  • All 89 existing ESM output tests continue to pass.

Copilot AI review requested due to automatic review settings March 16, 2026 11:23
@github-actions github-actions Bot added the release: bug fix release: bug related release(mr only) label Mar 16, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes ESM library output when optimization.runtimeChunk: false so entry chunks that also act as the runtime chunk don’t emit/export unnecessary __webpack_require__ scaffolding.

Changes:

  • Adjust ESM library rendering to only export __webpack_require__ from pure runtime chunks (no entry modules).
  • Stop generating an empty var __webpack_require__ = {}; when only REQUIRE_SCOPE is present without real REQUIRE usage.
  • Add an ESM output test case covering runtimeChunk: false and snapshotting the cleaned output.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/rspack_plugin_esm_library/src/render.rs Tightens __webpack_require__ export conditions; removes empty require-scope emission.
crates/rspack_plugin_esm_library/src/plugin.rs Attempts to gate adding RuntimeGlobals::REQUIRE behind an ESM-library-specific “needs require” signal.
tests/rspack-test/esmOutputCases/basic/runtime-chunk-false/rspack.config.js New test config setting optimization.runtimeChunk: false.
tests/rspack-test/esmOutputCases/basic/runtime-chunk-false/index.js New test asserting runtime behavior.
tests/rspack-test/esmOutputCases/basic/runtime-chunk-false/lib.js Simple exported value used by the test.
tests/rspack-test/esmOutputCases/basic/runtime-chunk-false/__snapshots__/esm.snap.txt Snapshot ensuring no __webpack_require__ artifacts in output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/rspack_plugin_esm_library/src/render.rs Outdated
Comment thread crates/rspack_plugin_esm_library/src/plugin.rs Outdated
… when runtimeChunk is false

When runtimeChunk is false, the entry chunk serves as both the entry and
runtime chunk. Previously this caused two issues:

1. __webpack_require__ was exported from the entry even though no other
   chunk imports it (only pure runtime chunks should export it).

2. An empty `var __webpack_require__ = {};` scope was generated when
   REQUIRE_SCOPE was triggered by STARTUP_NO_DEFAULT without actual
   REQUIRE usage.

3. REQUIRE was added to chunk requirements whenever any requirement
   existed, even if unrelated to __webpack_require__ usage.

Fix by: checking for entry modules before exporting __webpack_require__,
removing the useless require scope generation, and only adding REQUIRE
when ESM library features (external modules, interop) actually need it.
@JSerFeng JSerFeng force-pushed the vk/fix-esm-lib-runtime-chunk-false branch from 5832dc6 to 8ce82f9 Compare March 16, 2026 11:46
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 16, 2026

Rsdoctor Bundle Diff Analysis

Found 5 projects in monorepo, 5 projects with changes.

📊 Quick Summary
Project Total Size Change
react-10k 5.7 MB -
react-1k 826.2 KB -
react-5k 2.7 MB -
rome 984.2 KB -
ui-components 2.3 MB -
📋 Detailed Reports (Click to expand)

📁 react-10k

Path: ../build-tools-performance/cases/react-10k/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 5.7 MB - -
📄 JavaScript 5.7 MB - -
🎨 CSS 21.0 B - -
🌐 HTML 0 B - -
📁 Other Assets 0 B - -

📁 react-1k

Path: ../build-tools-performance/cases/react-1k/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 826.2 KB - -
📄 JavaScript 826.2 KB - -
🎨 CSS 0 B - -
🌐 HTML 0 B - -
📁 Other Assets 0 B - -

📁 react-5k

Path: ../build-tools-performance/cases/react-5k/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 2.7 MB - -
📄 JavaScript 2.7 MB - -
🎨 CSS 21.0 B - -
🌐 HTML 0 B - -
📁 Other Assets 0 B - -

📁 rome

Path: ../build-tools-performance/cases/rome/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 984.2 KB - -
📄 JavaScript 984.2 KB - -
🎨 CSS 0 B - -
🌐 HTML 0 B - -
📁 Other Assets 0 B - -

📁 ui-components

Path: ../build-tools-performance/cases/ui-components/dist/rsdoctor-data.json

⚠️ No baseline data found - Unable to perform comparison analysis

Metric Current Baseline Change
📊 Total Size 2.3 MB - -
📄 JavaScript 2.0 MB - -
🎨 CSS 271.6 KB - -
🌐 HTML 0 B - -
📁 Other Assets 0 B - -

Generated by Rsdoctor GitHub Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 16, 2026

📦 Binary Size-limit

Comparing a4da84e to feat(swc-loader)!: move rspackExperiments.import to top-level transformImport (#13345) by Fy

❌ Size increased by 896bytes from 49.00MB to 49.00MB (⬆️0.00%)

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 16, 2026

Merging this PR will not alter performance

✅ 16 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing vk/fix-esm-lib-runtime-chunk-false (a4da84e) with main (74775a8)2

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (96dda87) during the generation of this report, so 74775a8 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

…_SCOPE guard

- Rename `is_entry_chunk` to `is_pure_runtime_chunk` and flip the
  condition so the export guard reads positively: only pure runtime
  chunks export `__webpack_require__`.

- Replace the blanket `needs_require` flag with a REQUIRE_SCOPE_GLOBALS
  intersection check (same logic the runtime plugin uses in
  handle_scope_globals). This ensures REQUIRE_SCOPE is only added when
  the chunk actually contains globals that live on the __webpack_require__
  object, rather than for any non-empty requirement set.
@JSerFeng JSerFeng enabled auto-merge (squash) March 18, 2026 03:37
@JSerFeng JSerFeng merged commit d1e0c18 into main Mar 18, 2026
45 checks passed
@JSerFeng JSerFeng deleted the vk/fix-esm-lib-runtime-chunk-false branch March 18, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: bug fix release: bug related release(mr only)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants