Skip to content

issueset/astro_build_order_issue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Astro Non-Deterministic Build Output Reproduction

Identical source code produces different dist/_astro/*.js filenames across consecutive astro build runs. This breaks CDN caching because the same unchanged code gets different URLs on each deploy.

Reproduce

pnpm install
pnpm test           # runs 10 builds and compares output

Expected: all 10 builds produce identical output. Actual: ~60% of consecutive build pairs produce different JS filenames.

Example output:

Build 1: 8bc47ea55d5d13a6359f0d39b2461712
Build 2: 8bc47ea55d5d13a6359f0d39b2461712
Build 3: 7c17b92b2df44911065cc8e19abf7622
  ^^^ DIFFERS from build 2:
    Only in build3/_astro: SvelteWidget0.CHZtD1E3.js
    Only in build2/_astro: SvelteWidget0.DNGJBpKz.js
    Only in build3/_astro: SvelteWidget1.C_-Zw1cq.js
    Only in build2/_astro: SvelteWidget1.Ch6lmidG.js
    (4 total differences)

RESULT: Non-deterministic! 6 of 9 consecutive comparisons differed.

Root Cause

In packages/astro/src/core/build/static-build.ts, the client build entry points are passed to Rollup via Array.from(internals.clientInput). clientInput is a Set whose iteration order depends on the order components were discovered during the prerender phase.

The discovery order is non-deterministic because:

  1. The plugin-analyzer iterates this.getModuleIds() in the generateBundle hook
  2. getModuleIds() returns modules in Map insertion order
  3. Insertion order depends on async module resolution timing in Rollup's fetchStaticDependencies (which uses Promise.all)

When Rollup receives entry points in different order, chunk assignment and hash collision resolution produce different output filenames.

Suggested Fix

Sort the client input array before passing it to Rollup:

--- a/packages/astro/src/core/build/static-build.ts
+++ b/packages/astro/src/core/build/static-build.ts
   builder.environments.client.config.build.rollupOptions.input = Array.from(
     internals.clientInput
-  );
+  ).sort();

Verify the fix

Apply it manually to the installed Astro package:

# Find and patch the file
ASTRO_BUILD=$(find node_modules -path "*/astro/dist/core/build/static-build.js" | head -1)

# On macOS:
sed -i '' 's/Array\.from(\n*\s*internals\.clientInput\n*\s*)/Array.from(internals.clientInput).sort()/g' "$ASTRO_BUILD"

# Or manually: find the line that says
#   builder2.environments.client.config.build.rollupOptions.input = Array.from(
#     internals.clientInput
#   );
# and add .sort() after the closing parenthesis of Array.from().

# Then re-run the test:
pnpm test

After the fix, all 10 builds produce identical output.

Environment

  • astro: 6.1.7
  • vite: 7.3.2
  • rollup: 4.60.1
  • Node.js: v24
  • OS: macOS (Darwin)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors