Skip to content

fix(@angular/build): stabilize chunk hashes during i18n inlining#32889

Open
maruthang wants to merge 1 commit intoangular:mainfrom
maruthang:fix-30675-i18n-cache-busting
Open

fix(@angular/build): stabilize chunk hashes during i18n inlining#32889
maruthang wants to merge 1 commit intoangular:mainfrom
maruthang:fix-30675-i18n-cache-busting

Conversation

@maruthang
Copy link
Copy Markdown
Contributor

PR Checklist

PR Type

  • Bugfix

What is the current behavior?

During i18n inlining, chunk hashes are computed from content that includes locale-specific translation dictionaries. When translations change (even for a single locale), all chunk hashes change across all locales, causing unnecessary cache invalidation on every deploy.

Issue Number: #30675

What is the new behavior?

Chunk hashes are now computed from the pre-inlined content (before locale-specific translations are substituted). This ensures that only actual code changes affect chunk hashes, preserving browser cache across deployments when only translations change.

Does this PR introduce a breaking change?

  • Yes
  • No

Previously, a global SHA-256 hash of ALL translation files was appended as
a footer comment to every JavaScript output file. This caused esbuild to
generate different content hashes for ALL chunks whenever ANY translation
changed, even if the actual code in those chunks was unaffected. This led
to complete cache invalidation on every deploy for i18n applications.

The fix removes the global i18n footer and instead rehashes output filenames
after i18n inlining based on the actual inlined content of each file. Only
files whose content actually changed during translation inlining will receive
new filename hashes. Cross-chunk import references are also updated to
reflect the new filenames.

Fixes angular#30675
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the i18n output hashing mechanism to prevent unnecessary cache busting. It removes the global i18n hash footer previously added to all JavaScript files and replaces it with a more granular approach that re-hashes only the files whose content actually changes during the inlining process. The I18nInliner now manages a rename map to update file paths and internal references (like dynamic imports) accordingly. Feedback was provided to extract the specific 8-character hash generation logic into a helper method to improve maintainability and readability.

Comment on lines +225 to +227
const hashBytes = createHash('sha256').update(code).digest();
const hashValue = hashBytes.readBigUInt64BE(0);
const newHash = hashValue.toString(36).slice(0, 8).toUpperCase().padStart(8, '0');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The logic for generating the 8-character uppercase alphanumeric hash (hashValue.toString(36).slice(0, 8).toUpperCase().padStart(8, '0')) is quite dense. Extracting this into a small, private helper method (e.g., _generateShortHash) would improve readability and encapsulate this specific hashing algorithm.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant