Skip to content

Commit

Permalink
feat: Add support for injecting Debug IDs (#5712)
Browse files Browse the repository at this point in the history
* feat: Add support for injecting Debug IDs

* Add docs

* PR review changes and full coverage
  • Loading branch information
timfish authored Nov 9, 2024
1 parent 0f4676d commit d0935a8
Show file tree
Hide file tree
Showing 18 changed files with 99 additions and 2 deletions.
1 change: 1 addition & 0 deletions cli/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Basic options:
--shimMissingExports Create shim variables for missing exports
--silent Don't print warnings
--sourcemapBaseUrl <url> Emit absolute sourcemap URLs with given base
--sourcemapDebugIds Emit unique debug ids in source and sourcemaps
--sourcemapExcludeSources Do not include source code in source maps
--sourcemapFile <file> Specify bundle position for source maps
--sourcemapFileNames <pattern> Name pattern for emitted sourcemaps
Expand Down
2 changes: 2 additions & 0 deletions docs/command-line-interface/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export default {
preserveModulesRoot,
sourcemap,
sourcemapBaseUrl,
sourcemapDebugIds,
sourcemapExcludeSources,
sourcemapFile,
sourcemapFileNames,
Expand Down Expand Up @@ -439,6 +440,7 @@ Many options have command line equivalents. In those cases, any arguments passed
--shimMissingExports Create shim variables for missing exports
--silent Don't print warnings
--sourcemapBaseUrl <url> Emit absolute sourcemap URLs with given base
--sourcemapDebugIds Emit unique debug ids in source and sourcemaps
--sourcemapExcludeSources Do not include source code in source maps
--sourcemapFile <file> Specify bundle position for source maps
--sourcemapFileNames <pattern> Name pattern for emitted sourcemaps
Expand Down
10 changes: 10 additions & 0 deletions docs/configuration-options/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,16 @@ If `true`, a separate sourcemap file will be created. If `"inline"`, the sourcem

By default, sourcemap files generated by Rollup uses relative URLs to reference the files they describe. By providing an absolute base URL, e.g. `https://example.com`, sourcemaps will use absolute URLs instead.

### output.sourcemapDebugIds

| | |
| -------: | :--------------------------------------------- |
| Type: | `boolean` |
| CLI: | `--sourcemapDebugIds`/`--no-sourcemapDebugIds` |
| Default: | `false` |

if `true`, unique ids will be emitted in source and sourcemaps which streamlines identifying sourcemaps across different builds. See the [TC39 sourcemap debug ID proposal](https://github.com/tc39/source-map/blob/main/proposals/debug-id.md) for more details.

### output.sourcemapExcludeSources

| | |
Expand Down
1 change: 1 addition & 0 deletions docs/javascript-api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ const outputOptions = {
preserveModulesRoot,
sourcemap,
sourcemapBaseUrl,
sourcemapDebugIds,
sourcemapExcludeSources,
sourcemapFile,
sourcemapFileNames,
Expand Down
2 changes: 2 additions & 0 deletions src/rollup/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ export interface OutputOptions {
sourcemapFileNames?: string | ((chunkInfo: PreRenderedChunk) => string);
sourcemapIgnoreList?: boolean | SourcemapIgnoreListOption;
sourcemapPathTransform?: SourcemapPathTransformOption;
sourcemapDebugIds?: boolean;
strict?: boolean;
systemNullSetters?: boolean;
validate?: boolean;
Expand Down Expand Up @@ -836,6 +837,7 @@ export interface NormalizedOutputOptions {
sourcemapFileNames: string | ((chunkInfo: PreRenderedChunk) => string) | undefined;
sourcemapIgnoreList: SourcemapIgnoreListOption;
sourcemapPathTransform: SourcemapPathTransformOption | undefined;
sourcemapDebugIds: boolean;
strict: boolean;
systemNullSetters: boolean;
validate: boolean;
Expand Down
1 change: 1 addition & 0 deletions src/utils/options/mergeOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ async function mergeOutputOptions(
sanitizeFileName: getOption('sanitizeFileName'),
sourcemap: getOption('sourcemap'),
sourcemapBaseUrl: getOption('sourcemapBaseUrl'),
sourcemapDebugIds: getOption('sourcemapDebugIds'),
sourcemapExcludeSources: getOption('sourcemapExcludeSources'),
sourcemapFile: getOption('sourcemapFile'),
sourcemapFileNames: getOption('sourcemapFileNames'),
Expand Down
1 change: 1 addition & 0 deletions src/utils/options/normalizeOutputOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export async function normalizeOutputOptions(
: defaultSanitizeFileName,
sourcemap: config.sourcemap || false,
sourcemapBaseUrl: getSourcemapBaseUrl(config),
sourcemapDebugIds: config.sourcemapDebugIds || false,
sourcemapExcludeSources: config.sourcemapExcludeSources || false,
sourcemapFile: config.sourcemapFile,
sourcemapFileNames: getSourcemapFileNames(config, unsetOptions),
Expand Down
21 changes: 21 additions & 0 deletions src/utils/renderChunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ function addChunksToBundle(
const finalFileName = replacePlaceholders(fileName, hashesByPlaceholder);
let finalSourcemapFileName = null;
if (map) {
if (options.sourcemapDebugIds) {
updatedCode += calculateDebugIdAndGetComment(updatedCode, map);
}
finalSourcemapFileName = sourcemapFileName
? replacePlaceholders(sourcemapFileName, hashesByPlaceholder)
: `${finalFileName}.map`;
Expand All @@ -365,6 +368,9 @@ function addChunksToBundle(
hashesByPlaceholder.size > 0 ? replacePlaceholders(code, hashesByPlaceholder) : code;
let finalSourcemapFileName = null;
if (map) {
if (options.sourcemapDebugIds) {
updatedCode += calculateDebugIdAndGetComment(updatedCode, map);
}
finalSourcemapFileName = sourcemapFileName
? replacePlaceholders(sourcemapFileName, hashesByPlaceholder)
: `${fileName}.map`;
Expand Down Expand Up @@ -402,3 +408,18 @@ function emitSourceMapAndGetComment(
}
return sourcemap === 'hidden' ? '' : `//# ${SOURCEMAPPING_URL}=${url}\n`;
}

function calculateDebugIdAndGetComment(code: string, map: SourceMap & { debugId?: string }) {
const hash = hasherByType.hex(code);
const debugId = [
hash.slice(0, 8),
hash.slice(8, 12),
'4' + hash.slice(12, 15),
((parseInt(hash.slice(15, 16), 16) & 3) | 8).toString(16) + hash.slice(17, 20),
hash.slice(20, 32)
].join('-');

map.debugId = debugId;

return '//# debugId=' + debugId + '\n';
}
1 change: 1 addition & 0 deletions test/function/samples/output-options-hook/_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ module.exports = defineTest({
preserveModules: false,
reexportProtoFromExternal: true,
sourcemap: false,
sourcemapDebugIds: false,
sourcemapExcludeSources: false,
strict: true,
systemNullSetters: true,
Expand Down
4 changes: 2 additions & 2 deletions test/misc/optionList.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions test/sourcemaps/samples/debug-ids-with-placeholder/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const assert = require('node:assert');

module.exports = defineTest({
description: 'are injected into the source and sourcemaps when using placeholders',
options: {
output: {
name: 'myModule',
sourcemapDebugIds: true,
entryFileNames: '[name]-[hash].js'
}
},
async test(code, map) {
const match = code.match(/\/\/# debugId=([a-fA-F0-9-]+)/);
assert.ok(match, 'Could not find debugId in source');
const sourceDebugId = match[1];
assert.equal(
map.debugId,
sourceDebugId,
"debugId in source doesn't match debugId in sourcemap"
);
}
});
1 change: 1 addition & 0 deletions test/sourcemaps/samples/debug-ids-with-placeholder/bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function Foo () {}
5 changes: 5 additions & 0 deletions test/sourcemaps/samples/debug-ids-with-placeholder/foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Bar from './bar';

export default function Foo () {}

Foo.prototype = Object.create( Bar.prototype );
1 change: 1 addition & 0 deletions test/sourcemaps/samples/debug-ids-with-placeholder/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Foo } from './foo';
21 changes: 21 additions & 0 deletions test/sourcemaps/samples/debug-ids/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const assert = require('node:assert');

module.exports = defineTest({
description: 'are injected into the source and sourcemaps',
options: {
output: {
name: 'myModule',
sourcemapDebugIds: true
}
},
async test(code, map) {
const match = code.match(/\/\/# debugId=([a-fA-F0-9-]+)/);
assert.ok(match, 'Could not find debugId in source');
const sourceDebugId = match[1];
assert.equal(
map.debugId,
sourceDebugId,
"debugId in source doesn't match debugId in sourcemap"
);
}
});
1 change: 1 addition & 0 deletions test/sourcemaps/samples/debug-ids/bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function Foo () {}
5 changes: 5 additions & 0 deletions test/sourcemaps/samples/debug-ids/foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Bar from './bar';

export default function Foo () {}

Foo.prototype = Object.create( Bar.prototype );
1 change: 1 addition & 0 deletions test/sourcemaps/samples/debug-ids/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Foo } from './foo';

0 comments on commit d0935a8

Please sign in to comment.