Skip to content

Sort entry modules to make chunk hash names deterministic#6391

Merged
lukastaegert merged 2 commits into
masterfrom
fix/sort-entry-modules
May 31, 2026
Merged

Sort entry modules to make chunk hash names deterministic#6391
lukastaegert merged 2 commits into
masterfrom
fix/sort-entry-modules

Conversation

@TrickyPi

Copy link
Copy Markdown
Member

This PR contains:

  • bugfix
  • feature
  • refactor
  • documentation
  • other

Are tests included?

  • yes (bugfixes and features will not be merged without tests)
  • no

Breaking Changes?

  • yes (breaking changes will not be merged unless absolutely necessary)
  • no

List any relevant issue numbers:

Description

This PR makes the order of entry modules deterministic by sorting loaded entry modules by their resolved module IDs instead of preserving the order in which they were emitted. As a result, hash names for manual chunks that are dependencies of those entry modules also become deterministic in specific scenarios. This PR also sorts chunk name candidates by name. Since this PR also fixes #5902, we can remove the logic for sorting export names introduced in PR #6362.

Copilot AI review requested due to automatic review settings May 23, 2026 15:09
@vercel

vercel Bot commented May 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rollup Ready Ready Preview, Comment May 24, 2026 9:35am

Request Review

@github-actions

github-actions Bot commented May 23, 2026

Copy link
Copy Markdown

Thank you for your contribution! ❤️

You can try out this pull request locally by installing Rollup via

npm install rollup/rollup#fix/sort-entry-modules

Notice: Ensure you have installed the latest nightly Rust toolchain. If you haven't installed it yet, please see https://www.rust-lang.org/tools/install to learn how to download Rustup and install Rust.

or load it into the REPL:
https://rollup-nox0en9cn-rollup-js.vercel.app/repl/?pr=6391

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to make Rollup’s chunk naming/hashing deterministic by sorting entry modules (and chunk name candidates) rather than relying on emission order, reducing nondeterminism when parallel operations change resolution timing.

Changes:

  • Sort loaded entry modules by resolved module ID to stabilize chunk naming/hashing across runs.
  • Adjust chunk name candidate ordering and remove export-name sorting logic previously used for determinism.
  • Update and add tests/fixtures to reflect the new deterministic ordering.

Reviewed changes

Copilot reviewed 63 out of 63 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/misc/misc.js Updates determinism tests; adds a new scenario for shared dependency chunk name stability.
test/misc/bundle-information.js Updates assertions to reflect new deterministic output ordering.
test/cli/samples/code-splitting-named-inputs/_config.js Updates expected output order for deterministic entry ordering.
test/cli/samples/code-splitting-named-default-inputs/_config.js Updates expected output order for deterministic entry ordering.
test/chunking-form/samples/resolve-file-url/_expected/system/nested/chunk2.js Updates expected SystemJS output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/system/nested/chunk.js Updates expected SystemJS output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/system/main.js Updates expected SystemJS output URLs/import targets based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/es/nested/chunk2.js Updates expected ES output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/es/nested/chunk.js Updates expected ES output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/es/main.js Updates expected ES output URLs/import targets based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/cjs/nested/chunk2.js Updates expected CJS output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/cjs/nested/chunk.js Updates expected CJS output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/cjs/main.js Updates expected CJS output URLs/import targets based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/amd/nested/chunk2.js Updates expected AMD output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/amd/nested/chunk.js Updates expected AMD output based on new deterministic chunk assignment/order.
test/chunking-form/samples/resolve-file-url/_expected/amd/main.js Updates expected AMD output URLs/import targets based on new deterministic chunk assignment/order.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-not-specified.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-main.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-false.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-dynamic4.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-dynamic3.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-dynamic2.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-dynamic.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/system/generated-allow-extension.js Updates expected SystemJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-not-specified.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-main.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-false.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-dynamic4.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-dynamic3.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-dynamic2.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-dynamic.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/es/generated-allow-extension.js Updates expected ES fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-not-specified.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-main.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-false.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-dynamic4.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-dynamic3.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-dynamic2.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-dynamic.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/cjs/generated-allow-extension.js Updates expected CJS fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-not-specified.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-main.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-false.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-dynamic4.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-dynamic3.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-dynamic2.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-dynamic.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/preserve-entry-signatures/override-via-plugin/_expected/amd/generated-allow-extension.js Updates expected AMD fixture due to deterministic chunk ordering changes.
test/chunking-form/samples/entry-aliases/_expected/system/main2.js Updates expected SystemJS fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/system/main1.js Updates expected SystemJS fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/system/main1-alias.js Updates expected SystemJS fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/es/main2.js Updates expected ES fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/es/main1.js Updates expected ES fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/es/main1-alias.js Updates expected ES fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/cjs/main2.js Updates expected CJS fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/cjs/main1.js Updates expected CJS fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/cjs/main1-alias.js Updates expected CJS fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/amd/main2.js Updates expected AMD fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/amd/main1.js Updates expected AMD fixture due to deterministic entry ordering changes.
test/chunking-form/samples/entry-aliases/_expected/amd/main1-alias.js Updates expected AMD fixture due to deterministic entry ordering changes.
src/utils/exportNames.ts Removes export sorting in mangled export assignment.
src/ModuleLoader.ts Switches to sorting entry modules by resolved ID; changes chunk-name candidate ordering logic.
src/Module.ts Removes priority field from chunkNames metadata.

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

Comment thread src/ModuleLoader.ts Outdated
Comment thread src/ModuleLoader.ts
Comment thread test/misc/misc.js
Comment thread src/ModuleLoader.ts Outdated
@github-actions

github-actions Bot commented May 23, 2026

Copy link
Copy Markdown

Performance report

  • BUILD: 6352ms, 830 MB
    • initialize: 0ms, 23.9 MB
    • generate module graph: 2283ms, 630 MB
      • generate ast: 1269ms (+34ms, +2.8%), 628 MB
    • sort and bind modules: 350ms, 682 MB
    • mark included statements: 3705ms, 830 MB
      • treeshaking pass 1: 2180ms, 822 MB
      • treeshaking pass 2: 433ms, 853 MB
      • treeshaking pass 3: 368ms, 828 MB
      • treeshaking pass 4: 355ms, 854 MB
      • treeshaking pass 5: 353ms, 830 MB
  • GENERATE: 617ms (+12ms, +2.1%), 925 MB
    • initialize render: 0ms, 831 MB
    • generate chunks: 36ms, 852 MB
      • optimize chunks: 0ms, 845 MB
    • render chunks: 566ms, 899 MB
    • transform chunks: 14ms, 925 MB
    • generate bundle: 0ms, 925 MB

@codecov

codecov Bot commented May 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.78%. Comparing base (c16e493) to head (917713e).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6391      +/-   ##
==========================================
- Coverage   98.78%   98.78%   -0.01%     
==========================================
  Files         274      274              
  Lines       10795    10785      -10     
  Branches     2883     2882       -1     
==========================================
- Hits        10664    10654      -10     
  Misses         89       89              
  Partials       42       42              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@lukastaegert lukastaegert left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah sorry, please ignore my comment, AI is running wild. I have another look myself first.

@lukastaegert lukastaegert left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice one, looks good to me!

@lukastaegert lukastaegert added this pull request to the merge queue May 31, 2026
Merged via the queue into master with commit 0f547eb May 31, 2026
48 checks passed
@lukastaegert lukastaegert deleted the fix/sort-entry-modules branch May 31, 2026 15:44
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

This PR has been released as part of rollup@4.61.0. You can test it via npm install rollup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chunk hashes are unstable when maxParallelFileOps != 1

3 participants