Skip to content

feat(@angular/build): emit debug ids for stable subresource integrity hashes#33110

Open
IchordeDionysos wants to merge 2 commits intoangular:mainfrom
simpleclub-extended:feat/sub-resource-integrity-with-debug-id
Open

feat(@angular/build): emit debug ids for stable subresource integrity hashes#33110
IchordeDionysos wants to merge 2 commits intoangular:mainfrom
simpleclub-extended:feat/sub-resource-integrity-with-debug-id

Conversation

@IchordeDionysos
Copy link
Copy Markdown

@IchordeDionysos IchordeDionysos commented Apr 30, 2026

Enable generating sub-resource integrity hashes when using error tracking tools relying on Debug IDs linking generated code files with source maps.

Closes #33108

PR Checklist

Please check to confirm your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

When Angular generates source maps, they only include a link to the source map URL and no Debug ID:

console.log(1);
//# sourceMappingURL=foo.js.map

The source map file also does not contain a debug ID:

{ "version": 3, "debugId": "old", "mappings": "" }

Issue Number: #33108

What is the new behavior?

When Angular generates source maps, in addition to the source map URL, generated files will also include a Debug ID above the sourceMappingURL:

console.log(1);
//# debugId=11111111-2222-5333-9444-555555555555
//# sourceMappingURL=foo.js.map

In addition the source map file will include the matching Debug ID:

{ "version": 3, "debugId": "old", "mappings": "", "debugId": "11111111-2222-5333-9444-555555555555" }

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

I'm happy to hear if there are concerns with this particular approach and which alternative solutions might be a better solution.

This allows error tracking to more reliably map generated code files to their corresponding stack traces.
Error tracking tools have historically solved this by running post-processing scripts that generate and inject Debug IDs after the framework build script and before deployment.

However, this approach will break any integrity hash that Angular generated for SRI as the file content will have changed.

--

This PR is part of a two fold effort to enable SRI for our specific integration of Angular.

The first PR, implementing support for dynamically loaded files can be found here, and should be merged first: #33109

… hashes

Enable generating sub-resource integrity hashes when using error tracking tools relying on Debug IDs linking generated code files with source maps.

Closes angular#33108
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 implements ECMA-426 Debug ID injection into JavaScript files and source maps using a new deterministic UUIDv5 utility. The injection is integrated into the post-bundle build process and includes validation tests. Review feedback suggests hardening the regex for comment detection to prevent false positives and optimizing the source map JSON update to maintain formatting and performance.

Comment on lines +44 to +47
const DEBUG_ID_COMMENT = /^[ \t]*\/\/[ \t]*#[ \t]*debugId=[^\n]*\n?/m;

/** Pattern matching the `//# sourceMappingURL=` comment, used to position the debug-id line. */
const SOURCE_MAPPING_URL_COMMENT = /^[ \t]*\/\/[ \t]*#[ \t]*sourceMappingURL=[^\n]*$/m;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The current regexes for debugId and sourceMappingURL use the multiline flag (/m) and are anchored to the start of the line (^). This can lead to false positives if these strings appear inside string literals or comments within the JavaScript code. Since these magic comments are required to be at the end of the file (per ECMA-426), it is safer to anchor them to the end of the string and avoid the multiline flag.

Suggested change
const DEBUG_ID_COMMENT = /^[ \t]*\/\/[ \t]*#[ \t]*debugId=[^\n]*\n?/m;
/** Pattern matching the `//# sourceMappingURL=` comment, used to position the debug-id line. */
const SOURCE_MAPPING_URL_COMMENT = /^[ \t]*\/\/[ \t]*#[ \t]*sourceMappingURL=[^\n]*$/m;
const DEBUG_ID_COMMENT = /\/\/[ \t]*#[ \t]*debugId=[^\n]*\n?(?=\s*\/\/[ \t]*#[ \t]*sourceMappingURL=|\s*$)/;
const SOURCE_MAPPING_URL_COMMENT = /\/\/[ \t]*#[ \t]*sourceMappingURL=[^\n]*\s*$/;

Comment thread packages/angular/build/src/utils/debug-id.ts Outdated
Comment on lines +30 to +41
export function generateDebugId(name: string | Uint8Array): string {
const sha = createHash('sha1').update(ANGULAR_BUILD_NAMESPACE).update(name).digest();

// Set version (5) in the high nibble of byte 6.
sha[6] = (sha[6] & 0x0f) | 0x50;
// Set RFC 4122 variant bits (10xx) in byte 8.
sha[8] = (sha[8] & 0x3f) | 0x80;

const h = sha.toString('hex');

return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
}
Copy link
Copy Markdown
Author

@IchordeDionysos IchordeDionysos Apr 30, 2026

Choose a reason for hiding this comment

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

There would also be the possibility of using an existing implementation, e.g. of uuid.

Happy to make this change.

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

Labels

area: @angular/build detected: feature PR contains a feature commit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit ECMA-426 source map debug IDs for stable subresource integrity

1 participant