From c6aa5752fca04b59add4bccf8055ddac5b511522 Mon Sep 17 00:00:00 2001 From: Mattias Ekstrand Date: Wed, 6 Sep 2023 07:26:58 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Added=20option=20to=20name=20sourcemap=20fi?= =?UTF-8?q?les,=20i.e.=20a=20output.sourcemapFileName=E2=80=A6=20(#5105)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added option to name sourcemap files, i.e. a output.sourcemapFileNames property * Added chunkhash placeholder to sourcemap names * Improve coverage --------- Co-authored-by: Lukas Taegert-Atkinson Co-authored-by: Lukas Taegert-Atkinson --- cli/help.md | 1 + docs/command-line-interface/index.md | 2 + docs/configuration-options/index.md | 16 +++++ docs/javascript-api/index.md | 1 + docs/repl/stores/options.ts | 22 ++++--- src/Chunk.ts | 38 ++++++++++- src/rollup/types.d.ts | 4 ++ src/utils/FileEmitter.ts | 1 + src/utils/options/mergeOptions.ts | 1 + src/utils/options/normalizeOutputOptions.ts | 12 ++++ src/utils/renderChunks.ts | 66 +++++++++++++++---- .../samples/render-chunk-transform/_config.js | 6 +- .../sourcemap-file-names-function/_config.js | 27 ++++++++ .../_expected/amd/dynamic-a0f7e361.js | 6 ++ .../amd/dynamic-eea0ce30202b-5ec8d44f.js.map | 1 + .../_expected/amd/dynamic-hashed-5ec8d44f.js | 6 ++ .../_expected/amd/dynamic.js.map | 1 + .../_expected/amd/main.js | 7 ++ .../_expected/amd/main.js.map | 1 + .../_expected/cjs/dynamic-03a87e17.js | 4 ++ .../cjs/dynamic-44faaace9dbc-e21b9079.js.map | 1 + .../_expected/cjs/dynamic-hashed-e21b9079.js | 4 ++ .../_expected/cjs/dynamic.js.map | 1 + .../_expected/cjs/main.js | 5 ++ .../_expected/cjs/main.js.map | 1 + .../es/dynamic-769057acb768-4b06902b.js.map | 1 + .../_expected/es/dynamic-c7ad594d.js | 2 + .../_expected/es/dynamic-hashed-4b06902b.js | 2 + .../_expected/es/dynamic.js.map | 1 + .../_expected/es/main.js | 3 + .../_expected/es/main.js.map | 1 + .../dynamic-883b8003cd49-c0b30ec8.js.map | 1 + .../_expected/system/dynamic-ef271780.js | 11 ++++ .../system/dynamic-hashed-c0b30ec8.js | 11 ++++ .../_expected/system/dynamic.js.map | 1 + .../_expected/system/main.js | 12 ++++ .../_expected/system/main.js.map | 1 + .../dynamic-hashed.js | 1 + .../sourcemap-file-names-function/dynamic.js | 1 + .../sourcemap-file-names-function/main.js | 2 + .../samples/sourcemap-file-names/_config.js | 22 +++++++ .../amd/main-543232e9-amd-af8f17da.js.map | 1 + .../_expected/amd/main-543232e9-amd.js | 6 ++ .../cjs/main-3fddaf82-cjs-c64b742b.js.map | 1 + .../_expected/cjs/main-3fddaf82-cjs.js | 4 ++ .../es/main-824894f4-es-dbab040a.js.map | 1 + .../_expected/es/main-824894f4-es.js | 2 + .../main-6186746c-system-bce3d2ab.js.map | 1 + .../_expected/system/main-6186746c-system.js | 11 ++++ .../samples/sourcemap-file-names/main.js | 1 + .../emit-file/prebuilt-chunk/_config.js | 2 + test/misc/optionList.js | 4 +- test/sourcemaps/index.js | 5 +- 53 files changed, 321 insertions(+), 26 deletions(-) create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_config.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-a0f7e361.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-eea0ce30202b-5ec8d44f.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-hashed-5ec8d44f.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-03a87e17.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-44faaace9dbc-e21b9079.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-hashed-e21b9079.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-769057acb768-4b06902b.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-c7ad594d.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-hashed-4b06902b.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-883b8003cd49-c0b30ec8.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-ef271780.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-hashed-c0b30ec8.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/dynamic-hashed.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/dynamic.js create mode 100644 test/chunking-form/samples/sourcemap-file-names-function/main.js create mode 100644 test/chunking-form/samples/sourcemap-file-names/_config.js create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd-af8f17da.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd.js create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs-c64b742b.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs.js create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es-dbab040a.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es.js create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system-bce3d2ab.js.map create mode 100644 test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system.js create mode 100644 test/chunking-form/samples/sourcemap-file-names/main.js diff --git a/cli/help.md b/cli/help.md index d943588d4..74afadf40 100644 --- a/cli/help.md +++ b/cli/help.md @@ -69,6 +69,7 @@ Basic options: --sourcemapBaseUrl Emit absolute sourcemap URLs with given base --sourcemapExcludeSources Do not include source code in source maps --sourcemapFile Specify bundle position for source maps +--sourcemapFileNames Name pattern for emitted sourcemaps --stdin=ext Specify file extension used for stdin input --no-stdin Do not read "-" from stdin --no-strict Don't emit `"use strict";` in the generated modules diff --git a/docs/command-line-interface/index.md b/docs/command-line-interface/index.md index 54d223b64..b223f7caa 100755 --- a/docs/command-line-interface/index.md +++ b/docs/command-line-interface/index.md @@ -106,6 +106,7 @@ export default { sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, + sourcemapFileNames, sourcemapIgnoreList, sourcemapPathTransform, validate, @@ -420,6 +421,7 @@ Many options have command line equivalents. In those cases, any arguments passed --sourcemapBaseUrl Emit absolute sourcemap URLs with given base --sourcemapExcludeSources Do not include source code in source maps --sourcemapFile Specify bundle position for source maps +--sourcemapFileNames Name pattern for emitted sourcemaps --stdin=ext Specify file extension used for stdin input --no-stdin Do not read "-" from stdin --no-strict Don't emit `"use strict";` in the generated modules diff --git a/docs/configuration-options/index.md b/docs/configuration-options/index.md index aefccc40a..08485f511 100755 --- a/docs/configuration-options/index.md +++ b/docs/configuration-options/index.md @@ -1470,6 +1470,22 @@ The location of the generated bundle. If this is an absolute path, all the `sour `sourcemapFile` is not required if `output` is specified, in which case an output filename will be inferred by adding ".map" to the output filename for the bundle. +### output.sourcemapFileNames + +| | | +| ----: | :--------------------------------------------- | +| Type: | `string \| ((chunkInfo: ChunkInfo) => string)` | +| CLI: | `--sourcemapFileNames ` | + +The pattern to use for sourcemaps, or a function that is called per sourcemap to return such a pattern. Patterns support the following placeholders: + +- `[format]`: The rendering format defined in the output options, e.g. `es` or `cjs`. +- `[hash]`: A hash based only on the content of the final generated sourcemap. You can also set a specific hash length via e.g. `[hash:10]`. +- `[chunkhash]`: The same hash as the one used for the corresponding generated chunk (if any). +- `[name]`: The file name (without extension) of the entry point, unless the object form of input was used to define a different name. + +Forward slashes `/` can be used to place files in sub-directories. When using a function, `chunkInfo` is a reduced version of the one in [`generateBundle`](../plugin-development/index.md#generatebundle) without properties that depend on file names and no information about the rendered modules as rendering only happens after file names have been generated. You can however access a list of included `moduleIds`. See also [`output.assetFileNames`](#output-assetfilenames), [`output.chunkFileNames`](#output-chunkfilenames). + ### output.sourcemapIgnoreList | | | diff --git a/docs/javascript-api/index.md b/docs/javascript-api/index.md index 568373109..e23428449 100755 --- a/docs/javascript-api/index.md +++ b/docs/javascript-api/index.md @@ -181,6 +181,7 @@ const outputOptions = { sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, + sourcemapFileNames, sourcemapIgnoreList, sourcemapPathTransform, validate, diff --git a/docs/repl/stores/options.ts b/docs/repl/stores/options.ts index 9d7693584..33cafd18e 100644 --- a/docs/repl/stores/options.ts +++ b/docs/repl/stores/options.ts @@ -311,14 +311,14 @@ export const useOptions = defineStore('options2', () => { available: optionOutputPreserveModules.value, name: 'output.preserveModulesRoot' }); - const optionOutputSourcemap = getBoolean({ - name: 'output.sourcemap' - }); const optionOutputSanitizeFileName = getBoolean({ available: alwaysTrue, defaultValue: true, name: 'output.sanitizeFileName' }); + const optionOutputSourcemap = getBoolean({ + name: 'output.sourcemap' + }); const optionOutputSourcemapBaseUrl = getString({ available: optionOutputSourcemap.value, name: 'output.sourcemapBaseUrl' @@ -327,12 +327,22 @@ export const useOptions = defineStore('options2', () => { available: optionOutputSourcemap.value, name: 'output.sourcemapExcludeSources' }); + const optionOutputSourcemapFileNames = getString({ + available: alwaysTrue, + defaultValue: undefined, + name: 'output.sourcemapFileNames' + }); const optionOutputStrict = getBoolean({ available: () => optionOutputFormat.value.value !== undefined && optionOutputFormat.value.value !== 'es', defaultValue: true, name: 'output.strict' }); + const optionOutputSystemNullSetters = getBoolean({ + available: () => optionOutputFormat.value.value === 'system', + defaultValue: true, + name: 'output.systemNullSetters' + }); const optionOutputValidate = getBoolean({ name: 'output.validate' }); @@ -342,11 +352,6 @@ export const useOptions = defineStore('options2', () => { name: 'preserveEntrySignatures', options: () => ['strict', 'allow-extension', 'exports-only', false] }); - const optionOutputSystemNullSetters = getBoolean({ - available: () => optionOutputFormat.value.value === 'system', - defaultValue: true, - name: 'output.systemNullSetters' - }); const optionShimMissingExports = getBoolean({ defaultValue: false, name: 'shimMissingExports' @@ -436,6 +441,7 @@ export const useOptions = defineStore('options2', () => { optionOutputPreserveModules, optionOutputPreserveModulesRoot, optionOutputSourcemap, + optionOutputSourcemapFileNames, optionOutputSanitizeFileName, optionOutputSourcemapBaseUrl, optionOutputSourcemapExcludeSources, diff --git a/src/Chunk.ts b/src/Chunk.ts index 2b1a65910..377210e98 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -72,6 +72,7 @@ export interface ChunkRenderResult { chunk: Chunk; magicString: MagicStringBundle; preliminaryFileName: PreliminaryFileName; + preliminarySourcemapFileName: PreliminaryFileName | null; usedModules: Module[]; } @@ -187,6 +188,7 @@ export default class Chunk { private needsExportsShim = false; private preRenderedChunkInfo: PreRenderedChunk | null = null; private preliminaryFileName: PreliminaryFileName | null = null; + private preliminarySourcemapFileName: PreliminaryFileName | null = null; private renderedChunkInfo: RenderedChunk | null = null; private renderedDependencies: Map | null = null; private readonly renderedModules: { @@ -328,6 +330,7 @@ export default class Chunk { finalizeChunk( code: string, map: SourceMap | null, + sourcemapFileName: string | null, hashesByPlaceholder: Map ): OutputChunk { const renderedChunkInfo = this.getRenderedChunkInfo(); @@ -349,7 +352,8 @@ export default class Chunk { imports: renderedChunkInfo.imports.map(finalize), map, preliminaryFileName, - referencedFiles: renderedChunkInfo.referencedFiles.map(finalize) + referencedFiles: renderedChunkInfo.referencedFiles.map(finalize), + sourcemapFileName }; } @@ -544,6 +548,36 @@ export default class Chunk { return (this.preliminaryFileName = { fileName, hashPlaceholder }); } + getPreliminarySourcemapFileName(): PreliminaryFileName | null { + if (this.preliminarySourcemapFileName) { + return this.preliminarySourcemapFileName; + } + let sourcemapFileName: string | null = null; + let hashPlaceholder: string | null = null; + const { sourcemapFileNames, format } = this.outputOptions; + if (sourcemapFileNames) { + const [pattern, patternName] = [sourcemapFileNames, 'output.sourcemapFileNames']; + sourcemapFileName = renderNamePattern( + typeof pattern === 'function' ? pattern(this.getPreRenderedChunkInfo()) : pattern, + patternName, + { + chunkhash: () => this.getPreliminaryFileName().hashPlaceholder || '', + format: () => format, + hash: size => + hashPlaceholder || (hashPlaceholder = this.getPlaceholder(patternName, size)), + name: () => this.getChunkName() + } + ); + if (!hashPlaceholder) { + sourcemapFileName = makeUnique(sourcemapFileName, this.bundle); + } + } else { + return null; + } + + return (this.preliminarySourcemapFileName = { fileName: sourcemapFileName, hashPlaceholder }); + } + public getRenderedChunkInfo(): RenderedChunk { if (this.renderedChunkInfo) { return this.renderedChunkInfo; @@ -606,6 +640,7 @@ export default class Chunk { } const preliminaryFileName = this.getPreliminaryFileName(); + const preliminarySourcemapFileName = this.getPreliminarySourcemapFileName(); const { accessedGlobals, indent, magicString, renderedSource, usedModules, usesTopLevelAwait } = this.renderModules(preliminaryFileName.fileName); @@ -670,6 +705,7 @@ export default class Chunk { chunk: this, magicString, preliminaryFileName, + preliminarySourcemapFileName, usedModules }; } diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index 07f6f4032..d12c4116b 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -164,6 +164,7 @@ export interface EmittedPrebuiltChunk { exports?: string[]; fileName: string; map?: SourceMap; + sourcemapFileName?: string; type: 'prebuilt-chunk'; } @@ -744,6 +745,7 @@ export interface OutputOptions { sourcemapBaseUrl?: string; sourcemapExcludeSources?: boolean; sourcemapFile?: string; + sourcemapFileNames?: string | ((chunkInfo: PreRenderedChunk) => string); sourcemapIgnoreList?: boolean | SourcemapIgnoreListOption; sourcemapPathTransform?: SourcemapPathTransformOption; strict?: boolean; @@ -799,6 +801,7 @@ export interface NormalizedOutputOptions { sourcemapBaseUrl: string | undefined; sourcemapExcludeSources: boolean; sourcemapFile: string | undefined; + sourcemapFileNames: string | ((chunkInfo: PreRenderedChunk) => string) | undefined; sourcemapIgnoreList: SourcemapIgnoreListOption; sourcemapPathTransform: SourcemapPathTransformOption | undefined; strict: boolean; @@ -862,6 +865,7 @@ export interface RenderedChunk extends PreRenderedChunk { export interface OutputChunk extends RenderedChunk { code: string; map: SourceMap | null; + sourcemapFileName: string | null; preliminaryFileName: string; } diff --git a/src/utils/FileEmitter.ts b/src/utils/FileEmitter.ts index d10729578..c5405eb4d 100644 --- a/src/utils/FileEmitter.ts +++ b/src/utils/FileEmitter.ts @@ -326,6 +326,7 @@ export class FileEmitter { name: prebuiltChunk.fileName, preliminaryFileName: prebuiltChunk.fileName, referencedFiles: [], + sourcemapFileName: prebuiltChunk.sourcemapFileName || null, type: 'chunk' }; } diff --git a/src/utils/options/mergeOptions.ts b/src/utils/options/mergeOptions.ts index f384e50c1..4d7217a2a 100644 --- a/src/utils/options/mergeOptions.ts +++ b/src/utils/options/mergeOptions.ts @@ -282,6 +282,7 @@ async function mergeOutputOptions( sourcemapBaseUrl: getOption('sourcemapBaseUrl'), sourcemapExcludeSources: getOption('sourcemapExcludeSources'), sourcemapFile: getOption('sourcemapFile'), + sourcemapFileNames: getOption('sourcemapFileNames'), sourcemapIgnoreList: getOption('sourcemapIgnoreList'), sourcemapPathTransform: getOption('sourcemapPathTransform'), strict: getOption('strict'), diff --git a/src/utils/options/normalizeOutputOptions.ts b/src/utils/options/normalizeOutputOptions.ts index 48863043e..5827e4115 100644 --- a/src/utils/options/normalizeOutputOptions.ts +++ b/src/utils/options/normalizeOutputOptions.ts @@ -104,6 +104,7 @@ export async function normalizeOutputOptions( sourcemapBaseUrl: getSourcemapBaseUrl(config), sourcemapExcludeSources: config.sourcemapExcludeSources || false, sourcemapFile: config.sourcemapFile, + sourcemapFileNames: getSourcemapFileNames(config, unsetOptions), sourcemapIgnoreList: typeof config.sourcemapIgnoreList === 'function' ? config.sourcemapIgnoreList @@ -528,6 +529,17 @@ const getNamespaceToStringTag = ( return generatedCode.symbols || false; }; +const getSourcemapFileNames = ( + config: OutputOptions, + unsetOptions: Set +): NormalizedOutputOptions['sourcemapFileNames'] => { + const configSourcemapFileNames = config.sourcemapFileNames; + if (configSourcemapFileNames == null) { + unsetOptions.add('sourcemapFileNames'); + } + return configSourcemapFileNames; +}; + const getSourcemapBaseUrl = ( config: OutputOptions ): NormalizedOutputOptions['sourcemapBaseUrl'] => { diff --git a/src/utils/renderChunks.ts b/src/utils/renderChunks.ts index cd1f92cc2..e154cc62d 100644 --- a/src/utils/renderChunks.ts +++ b/src/utils/renderChunks.ts @@ -32,6 +32,7 @@ interface RenderedChunkWithPlaceholders { chunk: Chunk; code: string; fileName: string; + sourcemapFileName: string | null; map: SourceMap | null; } @@ -52,6 +53,7 @@ export async function renderChunks( const chunkGraph = getChunkGraph(chunks); const { + initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, renderedChunksByPlaceholder, hashDependenciesByPlaceholder @@ -65,6 +67,7 @@ export async function renderChunks( const hashesByPlaceholder = generateFinalHashes( renderedChunksByPlaceholder, hashDependenciesByPlaceholder, + initialHashesByPlaceholder, bundle ); addChunksToBundle( @@ -200,6 +203,7 @@ async function transformChunksAndGenerateContentHashes( const nonHashedChunksWithPlaceholders: RenderedChunkWithPlaceholders[] = []; const renderedChunksByPlaceholder = new Map(); const hashDependenciesByPlaceholder = new Map(); + const initialHashesByPlaceholder = new Map(); const placeholders = new Set(); for (const { preliminaryFileName: { hashPlaceholder } @@ -211,12 +215,14 @@ async function transformChunksAndGenerateContentHashes( async ({ chunk, preliminaryFileName: { fileName, hashPlaceholder }, + preliminarySourcemapFileName, magicString, usedModules }) => { - const transformedChunk = { + const transformedChunk: RenderedChunkWithPlaceholders = { chunk, fileName, + sourcemapFileName: preliminarySourcemapFileName?.fileName ?? null, ...(await transformChunk( magicString, fileName, @@ -227,7 +233,8 @@ async function transformChunksAndGenerateContentHashes( log )) }; - const { code } = transformedChunk; + const { code, map } = transformedChunk; + if (hashPlaceholder) { // To create a reproducible content-only hash, all placeholders are // replaced with the same value before hashing @@ -256,11 +263,23 @@ async function transformChunksAndGenerateContentHashes( } else { nonHashedChunksWithPlaceholders.push(transformedChunk); } + + const sourcemapHashPlaceholder = preliminarySourcemapFileName?.hashPlaceholder; + if (map && sourcemapHashPlaceholder) { + initialHashesByPlaceholder.set( + preliminarySourcemapFileName.hashPlaceholder, + createHash() + .update(map.toString()) + .digest('hex') + .slice(0, preliminarySourcemapFileName.hashPlaceholder.length) + ); + } } ) ); return { hashDependenciesByPlaceholder, + initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, renderedChunksByPlaceholder }; @@ -269,9 +288,10 @@ async function transformChunksAndGenerateContentHashes( function generateFinalHashes( renderedChunksByPlaceholder: Map, hashDependenciesByPlaceholder: Map, + initialHashesByPlaceholder: Map, bundle: OutputBundleWithPlaceholders ) { - const hashesByPlaceholder = new Map(); + const hashesByPlaceholder = new Map(initialHashesByPlaceholder); for (const [placeholder, { fileName }] of renderedChunksByPlaceholder) { let hash = createHash(); const hashDependencyPlaceholders = new Set([placeholder]); @@ -308,22 +328,46 @@ function addChunksToBundle( pluginDriver: PluginDriver, options: NormalizedOutputOptions ) { - for (const { chunk, code, fileName, map } of renderedChunksByPlaceholder.values()) { + for (const { + chunk, + code, + fileName, + sourcemapFileName, + map + } of renderedChunksByPlaceholder.values()) { let updatedCode = replacePlaceholders(code, hashesByPlaceholder); const finalFileName = replacePlaceholders(fileName, hashesByPlaceholder); + let finalSourcemapFileName = null; if (map) { + finalSourcemapFileName = sourcemapFileName + ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) + : `${finalFileName}.map`; map.file = replacePlaceholders(map.file, hashesByPlaceholder); - updatedCode += emitSourceMapAndGetComment(finalFileName, map, pluginDriver, options); + updatedCode += emitSourceMapAndGetComment(finalSourcemapFileName, map, pluginDriver, options); } - bundle[finalFileName] = chunk.finalizeChunk(updatedCode, map, hashesByPlaceholder); + bundle[finalFileName] = chunk.finalizeChunk( + updatedCode, + map, + finalSourcemapFileName, + hashesByPlaceholder + ); } - for (const { chunk, code, fileName, map } of nonHashedChunksWithPlaceholders) { + for (const { chunk, code, fileName, sourcemapFileName, map } of nonHashedChunksWithPlaceholders) { let updatedCode = hashesByPlaceholder.size > 0 ? replacePlaceholders(code, hashesByPlaceholder) : code; + let finalSourcemapFileName = null; if (map) { - updatedCode += emitSourceMapAndGetComment(fileName, map, pluginDriver, options); + finalSourcemapFileName = sourcemapFileName + ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) + : `${fileName}.map`; + updatedCode += emitSourceMapAndGetComment(finalSourcemapFileName, map, pluginDriver, options); } - bundle[fileName] = chunk.finalizeChunk(updatedCode, map, hashesByPlaceholder); + bundle[fileName] = chunk.finalizeChunk( + updatedCode, + map, + finalSourcemapFileName, + hashesByPlaceholder + ); } } @@ -337,11 +381,11 @@ function emitSourceMapAndGetComment( if (sourcemap === 'inline') { url = map.toUrl(); } else { - const sourcemapFileName = `${basename(fileName)}.map`; + const sourcemapFileName = basename(fileName); url = sourcemapBaseUrl ? new URL(sourcemapFileName, sourcemapBaseUrl).toString() : sourcemapFileName; - pluginDriver.emitFile({ fileName: `${fileName}.map`, source: map.toString(), type: 'asset' }); + pluginDriver.emitFile({ fileName, source: map.toString(), type: 'asset' }); } return sourcemap === 'hidden' ? '' : `//# ${SOURCEMAPPING_URL}=${url}\n`; } diff --git a/test/chunking-form/samples/render-chunk-transform/_config.js b/test/chunking-form/samples/render-chunk-transform/_config.js index 5c1131ec0..d45b42c72 100644 --- a/test/chunking-form/samples/render-chunk-transform/_config.js +++ b/test/chunking-form/samples/render-chunk-transform/_config.js @@ -47,7 +47,8 @@ module.exports = defineTest({ imports: [], preliminaryFileName: 'entry-main1-!~{001}~.js', referencedFiles: [], - map: null + map: null, + sourcemapFileName: null }, 'entry-main2.js': { exports: [], @@ -65,7 +66,8 @@ module.exports = defineTest({ imports: ['entry-main1.js'], preliminaryFileName: 'entry-main2-!~{002}~.js', referencedFiles: [], - map: null + map: null, + sourcemapFileName: null } }); } diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_config.js b/test/chunking-form/samples/sourcemap-file-names-function/_config.js new file mode 100644 index 000000000..aaee53297 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_config.js @@ -0,0 +1,27 @@ +module.exports = defineTest({ + description: 'observes sourcemapFileNames property when using a function', + options: { + output: { + sourcemap: true, + entryFileNames: '[name].js', + chunkFileNames: '[name]-[hash].js', + sourcemapFileNames: ({ name }) => { + switch (name) { + case 'main': { + // chunkhash should be empty string + return 'main[chunkhash].js.map'; + } + case 'dynamic': { + return 'dynamic.js.map'; + } + case 'dynamic-hashed': { + return 'dynamic-[hash:12]-[chunkhash].js.map'; + } + default: { + throw new Error(`Unexpected name ${name}`); + } + } + } + } + } +}); diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-a0f7e361.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-a0f7e361.js new file mode 100644 index 000000000..6e68bc23d --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-a0f7e361.js @@ -0,0 +1,6 @@ +define((function () { 'use strict'; + + console.log('dynamic'); + +})); +//# sourceMappingURL=dynamic.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-eea0ce30202b-5ec8d44f.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-eea0ce30202b-5ec8d44f.js.map new file mode 100644 index 000000000..c8102366e --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-eea0ce30202b-5ec8d44f.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-hashed-5ec8d44f.js","sources":["../../dynamic-hashed.js"],"sourcesContent":["console.log('dynamic-hashed');\n"],"names":[],"mappings":";;CAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-hashed-5ec8d44f.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-hashed-5ec8d44f.js new file mode 100644 index 000000000..775befa5f --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic-hashed-5ec8d44f.js @@ -0,0 +1,6 @@ +define((function () { 'use strict'; + + console.log('dynamic-hashed'); + +})); +//# sourceMappingURL=dynamic-eea0ce30202b-5ec8d44f.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic.js.map new file mode 100644 index 000000000..3af06b91a --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/dynamic.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-a0f7e361.js","sources":["../../dynamic.js"],"sourcesContent":["console.log('dynamic');\n"],"names":[],"mappings":";;CAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js new file mode 100644 index 000000000..2c4333834 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js @@ -0,0 +1,7 @@ +define(['require'], (function (require) { 'use strict'; + + new Promise(function (resolve, reject) { require(['./dynamic-a0f7e361'], resolve, reject); }); + new Promise(function (resolve, reject) { require(['./dynamic-hashed-5ec8d44f'], resolve, reject); }); + +})); +//# sourceMappingURL=main.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js.map new file mode 100644 index 000000000..77d397ccc --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/amd/main.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main.js","sources":["../../main.js"],"sourcesContent":["import('./dynamic.js');\nimport('./dynamic-hashed.js');\n"],"names":[],"mappings":";;AAAA,mDAAO,oBAAc,uBAAC,CAAC;AACvB,mDAAO,2BAAqB,uBAAC;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-03a87e17.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-03a87e17.js new file mode 100644 index 000000000..7de73b8dd --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-03a87e17.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log('dynamic'); +//# sourceMappingURL=dynamic.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-44faaace9dbc-e21b9079.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-44faaace9dbc-e21b9079.js.map new file mode 100644 index 000000000..b1be3c6ea --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-44faaace9dbc-e21b9079.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-hashed-e21b9079.js","sources":["../../dynamic-hashed.js"],"sourcesContent":["console.log('dynamic-hashed');\n"],"names":[],"mappings":";;AAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-hashed-e21b9079.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-hashed-e21b9079.js new file mode 100644 index 000000000..4f1a4393c --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic-hashed-e21b9079.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log('dynamic-hashed'); +//# sourceMappingURL=dynamic-44faaace9dbc-e21b9079.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic.js.map new file mode 100644 index 000000000..8535c836d --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/dynamic.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-03a87e17.js","sources":["../../dynamic.js"],"sourcesContent":["console.log('dynamic');\n"],"names":[],"mappings":";;AAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js new file mode 100644 index 000000000..ecf6f5b43 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js @@ -0,0 +1,5 @@ +'use strict'; + +Promise.resolve().then(function () { return require('./dynamic-03a87e17.js'); }); +Promise.resolve().then(function () { return require('./dynamic-hashed-e21b9079.js'); }); +//# sourceMappingURL=main.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js.map new file mode 100644 index 000000000..7d54836ff --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/cjs/main.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main.js","sources":["../../main.js"],"sourcesContent":["import('./dynamic.js');\nimport('./dynamic-hashed.js');\n"],"names":[],"mappings":";;AAAA,oDAAO,uBAAc,KAAC,CAAC;AACvB,oDAAO,8BAAqB,KAAC;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-769057acb768-4b06902b.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-769057acb768-4b06902b.js.map new file mode 100644 index 000000000..35d31d3d6 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-769057acb768-4b06902b.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-hashed-4b06902b.js","sources":["../../dynamic-hashed.js"],"sourcesContent":["console.log('dynamic-hashed');\n"],"names":[],"mappings":"AAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-c7ad594d.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-c7ad594d.js new file mode 100644 index 000000000..e3094ebbb --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-c7ad594d.js @@ -0,0 +1,2 @@ +console.log('dynamic'); +//# sourceMappingURL=dynamic.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-hashed-4b06902b.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-hashed-4b06902b.js new file mode 100644 index 000000000..ca9acfeed --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic-hashed-4b06902b.js @@ -0,0 +1,2 @@ +console.log('dynamic-hashed'); +//# sourceMappingURL=dynamic-769057acb768-4b06902b.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic.js.map new file mode 100644 index 000000000..45e7b978c --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/dynamic.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-c7ad594d.js","sources":["../../dynamic.js"],"sourcesContent":["console.log('dynamic');\n"],"names":[],"mappings":"AAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js new file mode 100644 index 000000000..ae85ca097 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js @@ -0,0 +1,3 @@ +import('./dynamic-c7ad594d.js'); +import('./dynamic-hashed-4b06902b.js'); +//# sourceMappingURL=main.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js.map new file mode 100644 index 000000000..e433cc70d --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/es/main.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main.js","sources":["../../main.js"],"sourcesContent":["import('./dynamic.js');\nimport('./dynamic-hashed.js');\n"],"names":[],"mappings":"AAAA,OAAO,uBAAc,CAAC,CAAC;AACvB,OAAO,8BAAqB,CAAC"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-883b8003cd49-c0b30ec8.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-883b8003cd49-c0b30ec8.js.map new file mode 100644 index 000000000..4efbf1079 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-883b8003cd49-c0b30ec8.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-hashed-c0b30ec8.js","sources":["../../dynamic-hashed.js"],"sourcesContent":["console.log('dynamic-hashed');\n"],"names":[],"mappings":";;;;;GAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;;;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-ef271780.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-ef271780.js new file mode 100644 index 000000000..6b9651b1e --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-ef271780.js @@ -0,0 +1,11 @@ +System.register([], (function () { + 'use strict'; + return { + execute: (function () { + + console.log('dynamic'); + + }) + }; +})); +//# sourceMappingURL=dynamic.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-hashed-c0b30ec8.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-hashed-c0b30ec8.js new file mode 100644 index 000000000..d23349da9 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic-hashed-c0b30ec8.js @@ -0,0 +1,11 @@ +System.register([], (function () { + 'use strict'; + return { + execute: (function () { + + console.log('dynamic-hashed'); + + }) + }; +})); +//# sourceMappingURL=dynamic-883b8003cd49-c0b30ec8.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic.js.map new file mode 100644 index 000000000..49fa5e4dd --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/dynamic.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dynamic-ef271780.js","sources":["../../dynamic.js"],"sourcesContent":["console.log('dynamic');\n"],"names":[],"mappings":";;;;;GAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;;;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js new file mode 100644 index 000000000..a366b8a53 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js @@ -0,0 +1,12 @@ +System.register([], (function (exports, module) { + 'use strict'; + return { + execute: (function () { + + module.import('./dynamic-ef271780.js'); + module.import('./dynamic-hashed-c0b30ec8.js'); + + }) + }; +})); +//# sourceMappingURL=main.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js.map b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js.map new file mode 100644 index 000000000..c61b09415 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/_expected/system/main.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main.js","sources":["../../main.js"],"sourcesContent":["import('./dynamic.js');\nimport('./dynamic-hashed.js');\n"],"names":[],"mappings":";;;;;AAAA,iBAAO,uBAAc,CAAC,CAAC;AACvB,iBAAO,8BAAqB,CAAC;;;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names-function/dynamic-hashed.js b/test/chunking-form/samples/sourcemap-file-names-function/dynamic-hashed.js new file mode 100644 index 000000000..477aa42f8 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/dynamic-hashed.js @@ -0,0 +1 @@ +console.log('dynamic-hashed'); diff --git a/test/chunking-form/samples/sourcemap-file-names-function/dynamic.js b/test/chunking-form/samples/sourcemap-file-names-function/dynamic.js new file mode 100644 index 000000000..955cedef8 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/dynamic.js @@ -0,0 +1 @@ +console.log('dynamic'); diff --git a/test/chunking-form/samples/sourcemap-file-names-function/main.js b/test/chunking-form/samples/sourcemap-file-names-function/main.js new file mode 100644 index 000000000..29507b175 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names-function/main.js @@ -0,0 +1,2 @@ +import('./dynamic.js'); +import('./dynamic-hashed.js'); diff --git a/test/chunking-form/samples/sourcemap-file-names/_config.js b/test/chunking-form/samples/sourcemap-file-names/_config.js new file mode 100644 index 000000000..2ea7138dc --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_config.js @@ -0,0 +1,22 @@ +const assert = require('node:assert'); + +module.exports = defineTest({ + description: + 'populates sourcemapFileName property of OutputChunk with final name when using sourcemapFileNames option', + options: { + output: { + sourcemap: true, + entryFileNames: '[name]-[hash]-[format].js', + sourcemapFileNames: '[name]-[chunkhash]-[format]-[hash].js.map' + }, + plugins: [ + { + name: 'test-bundle', + generateBundle(options, bundle) { + const [sourcemapFileName, fileName] = Object.keys(bundle).sort(); + assert.strictEqual(bundle[fileName].sourcemapFileName, sourcemapFileName); + } + } + ] + } +}); diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd-af8f17da.js.map b/test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd-af8f17da.js.map new file mode 100644 index 000000000..242d8eda3 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd-af8f17da.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main-543232e9-amd.js","sources":["../../main.js"],"sourcesContent":["console.log( 42 );\n"],"names":[],"mappings":";;CAAA,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd.js b/test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd.js new file mode 100644 index 000000000..3970ebf7c --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/amd/main-543232e9-amd.js @@ -0,0 +1,6 @@ +define((function () { 'use strict'; + + console.log( 42 ); + +})); +//# sourceMappingURL=main-543232e9-amd-af8f17da.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs-c64b742b.js.map b/test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs-c64b742b.js.map new file mode 100644 index 000000000..be5e8ad1c --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs-c64b742b.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main-3fddaf82-cjs.js","sources":["../../main.js"],"sourcesContent":["console.log( 42 );\n"],"names":[],"mappings":";;AAAA,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs.js b/test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs.js new file mode 100644 index 000000000..98bd52e71 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/cjs/main-3fddaf82-cjs.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log( 42 ); +//# sourceMappingURL=main-3fddaf82-cjs-c64b742b.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es-dbab040a.js.map b/test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es-dbab040a.js.map new file mode 100644 index 000000000..83eea7bfe --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es-dbab040a.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main-824894f4-es.js","sources":["../../main.js"],"sourcesContent":["console.log( 42 );\n"],"names":[],"mappings":"AAAA,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es.js b/test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es.js new file mode 100644 index 000000000..556fd1f82 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/es/main-824894f4-es.js @@ -0,0 +1,2 @@ +console.log( 42 ); +//# sourceMappingURL=main-824894f4-es-dbab040a.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system-bce3d2ab.js.map b/test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system-bce3d2ab.js.map new file mode 100644 index 000000000..2d95a47c5 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system-bce3d2ab.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main-6186746c-system.js","sources":["../../main.js"],"sourcesContent":["console.log( 42 );\n"],"names":[],"mappings":";;;;;GAAA,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE;;;;;;;;"} \ No newline at end of file diff --git a/test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system.js b/test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system.js new file mode 100644 index 000000000..6d33eca3a --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/_expected/system/main-6186746c-system.js @@ -0,0 +1,11 @@ +System.register([], (function () { + 'use strict'; + return { + execute: (function () { + + console.log( 42 ); + + }) + }; +})); +//# sourceMappingURL=main-6186746c-system-bce3d2ab.js.map diff --git a/test/chunking-form/samples/sourcemap-file-names/main.js b/test/chunking-form/samples/sourcemap-file-names/main.js new file mode 100644 index 000000000..5c72ff351 --- /dev/null +++ b/test/chunking-form/samples/sourcemap-file-names/main.js @@ -0,0 +1 @@ +console.log( 42 ); diff --git a/test/function/samples/emit-file/prebuilt-chunk/_config.js b/test/function/samples/emit-file/prebuilt-chunk/_config.js index 82164251a..496b924c5 100644 --- a/test/function/samples/emit-file/prebuilt-chunk/_config.js +++ b/test/function/samples/emit-file/prebuilt-chunk/_config.js @@ -60,6 +60,7 @@ module.exports = defineTest({ ...prebuiltChunk1ConsumedProperties, name: fileName, map: null, + sourcemapFileName: null, preliminaryFileName: 'my-chunk.js' }); this.emitFile({ @@ -73,6 +74,7 @@ module.exports = defineTest({ name: fileName2, exports: [], map: null, + sourcemapFileName: null, preliminaryFileName: 'my-chunk2.js' }); } diff --git a/test/misc/optionList.js b/test/misc/optionList.js index cce929c1f..e34a54586 100644 --- a/test/misc/optionList.js +++ b/test/misc/optionList.js @@ -1,6 +1,6 @@ exports.input = 'acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, experimentalLogSideEffects, external, inlineDynamicImports, input, logLevel, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileOps, maxParallelFileReads, moduleContext, onLog, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch'; exports.flags = - 'acorn, acornInjectPlugins, amd, assetFileNames, banner, bundleConfigAsCjs, c, cache, chunkFileNames, compact, config, configPlugin, context, d, dir, dynamicImportFunction, dynamicImportInCjs, e, entryFileNames, environment, esModule, experimentalCacheExpiry, experimentalDeepDynamicChunkOptimization, experimentalLogSideEffects, experimentalMinChunkSize, exports, extend, external, externalImportAssertions, externalLiveBindings, f, failAfterWarnings, file, filterLogs, footer, format, freeze, g, generatedCode, globals, h, hoistTransitiveImports, i, indent, inlineDynamicImports, input, interop, intro, logLevel, m, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileOps, maxParallelFileReads, minifyInternalExports, moduleContext, n, name, namespaceToStringTag, noConflict, o, onLog, onwarn, outro, p, paths, perf, plugin, plugins, preferConst, preserveEntrySignatures, preserveModules, preserveModulesRoot, preserveSymlinks, sanitizeFileName, shimMissingExports, silent, sourcemap, sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, stdin, strict, strictDeprecations, systemNullSetters, treeshake, v, validate, w, waitForBundleInput, watch'; + 'acorn, acornInjectPlugins, amd, assetFileNames, banner, bundleConfigAsCjs, c, cache, chunkFileNames, compact, config, configPlugin, context, d, dir, dynamicImportFunction, dynamicImportInCjs, e, entryFileNames, environment, esModule, experimentalCacheExpiry, experimentalDeepDynamicChunkOptimization, experimentalLogSideEffects, experimentalMinChunkSize, exports, extend, external, externalImportAssertions, externalLiveBindings, f, failAfterWarnings, file, filterLogs, footer, format, freeze, g, generatedCode, globals, h, hoistTransitiveImports, i, indent, inlineDynamicImports, input, interop, intro, logLevel, m, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileOps, maxParallelFileReads, minifyInternalExports, moduleContext, n, name, namespaceToStringTag, noConflict, o, onLog, onwarn, outro, p, paths, perf, plugin, plugins, preferConst, preserveEntrySignatures, preserveModules, preserveModulesRoot, preserveSymlinks, sanitizeFileName, shimMissingExports, silent, sourcemap, sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, sourcemapFileNames, stdin, strict, strictDeprecations, systemNullSetters, treeshake, v, validate, w, waitForBundleInput, watch'; exports.output = - 'amd, assetFileNames, banner, chunkFileNames, compact, dir, dynamicImportFunction, dynamicImportInCjs, entryFileNames, esModule, experimentalDeepDynamicChunkOptimization, experimentalMinChunkSize, exports, extend, externalImportAssertions, externalLiveBindings, file, footer, format, freeze, generatedCode, globals, hoistTransitiveImports, indent, inlineDynamicImports, interop, intro, manualChunks, minifyInternalExports, name, namespaceToStringTag, noConflict, outro, paths, plugins, preferConst, preserveModules, preserveModulesRoot, sanitizeFileName, sourcemap, sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, sourcemapIgnoreList, sourcemapPathTransform, strict, systemNullSetters, validate'; + 'amd, assetFileNames, banner, chunkFileNames, compact, dir, dynamicImportFunction, dynamicImportInCjs, entryFileNames, esModule, experimentalDeepDynamicChunkOptimization, experimentalMinChunkSize, exports, extend, externalImportAssertions, externalLiveBindings, file, footer, format, freeze, generatedCode, globals, hoistTransitiveImports, indent, inlineDynamicImports, interop, intro, manualChunks, minifyInternalExports, name, namespaceToStringTag, noConflict, outro, paths, plugins, preferConst, preserveModules, preserveModulesRoot, sanitizeFileName, sourcemap, sourcemapBaseUrl, sourcemapExcludeSources, sourcemapFile, sourcemapFileNames, sourcemapIgnoreList, sourcemapPathTransform, strict, systemNullSetters, validate'; diff --git a/test/sourcemaps/index.js b/test/sourcemaps/index.js index 47d48021d..d3119aece 100644 --- a/test/sourcemaps/index.js +++ b/test/sourcemaps/index.js @@ -59,8 +59,9 @@ async function generateAndTestBundle(bundle, outputOptions, config, format, warn } else if (warnings.length > 0) { throw new Error(`Unexpected warnings`); } + const { - output: [{ code, map, fileName }] + output: [{ code, map, fileName, sourcemapFileName }] } = await bundle.write(outputOptions); - await config.test(code, map, { fileName, format }); + await config.test(code, map, { fileName, sourcemapFileName, format }); } From 884e6781ed67b1c94232fdf80cfe6b1d8fafb9d5 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Wed, 6 Sep 2023 07:27:37 +0200 Subject: [PATCH 2/3] Deoptimize custom event detail (#5123) --- src/ast/nodes/shared/knownGlobals.ts | 12 +++++++++++- test/form/samples/custom-event-detail/_config.js | 3 +++ test/form/samples/custom-event-detail/_expected.js | 5 +++++ test/form/samples/custom-event-detail/main.js | 5 +++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 test/form/samples/custom-event-detail/_config.js create mode 100644 test/form/samples/custom-event-detail/_expected.js create mode 100644 test/form/samples/custom-event-detail/main.js diff --git a/src/ast/nodes/shared/knownGlobals.ts b/src/ast/nodes/shared/knownGlobals.ts index 13e8294a6..0059b64c5 100644 --- a/src/ast/nodes/shared/knownGlobals.ts +++ b/src/ast/nodes/shared/knownGlobals.ts @@ -478,7 +478,17 @@ const knownGlobals: GlobalDescription = { CSSSupportsRule: C, CustomElementRegistry: C, customElements: O, - CustomEvent: C, + CustomEvent: { + __proto__: null, + [ValueProperties]: { + deoptimizeArgumentsOnCall({ args }: NodeInteractionCalled) { + args[2]?.deoptimizePath(['detail']); + }, + getLiteralValue: getTruthyLiteralValue, + hasEffectsWhenCalled: returnFalse + }, + prototype: O + }, DataTransfer: C, DataTransferItem: C, DataTransferItemList: C, diff --git a/test/form/samples/custom-event-detail/_config.js b/test/form/samples/custom-event-detail/_config.js new file mode 100644 index 000000000..e9a52e0fd --- /dev/null +++ b/test/form/samples/custom-event-detail/_config.js @@ -0,0 +1,3 @@ +module.exports = defineTest({ + description: 'observes side effects for custom event payloads' +}); diff --git a/test/form/samples/custom-event-detail/_expected.js b/test/form/samples/custom-event-detail/_expected.js new file mode 100644 index 000000000..098316cf8 --- /dev/null +++ b/test/form/samples/custom-event-detail/_expected.js @@ -0,0 +1,5 @@ +const detail = { value: null }; +const event = new CustomEvent('test', { detail }); +event.detail.value = true; +if (detail.value) console.log('ok'); +else console.log('failed'); diff --git a/test/form/samples/custom-event-detail/main.js b/test/form/samples/custom-event-detail/main.js new file mode 100644 index 000000000..098316cf8 --- /dev/null +++ b/test/form/samples/custom-event-detail/main.js @@ -0,0 +1,5 @@ +const detail = { value: null }; +const event = new CustomEvent('test', { detail }); +event.detail.value = true; +if (detail.value) console.log('ok'); +else console.log('failed'); From 642e56626a6b610465617eb1007f352f79eb4b86 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Wed, 6 Sep 2023 07:48:51 +0200 Subject: [PATCH 3/3] 3.29.0 --- CHANGELOG.md | 22 ++++++++++++++++++++++ browser/package.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbce95e0a..b93b9b67b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # rollup changelog +## 3.29.0 + +_2023-09-06_ + +### Features + +- Add output.sourcemapFileNames option (#5105) +- Add generic type parameter for `api` to Plugin type (#5112) + +### Bug Fixes + +- Ensure mutations of CustomEvent details are tracked (#5123) + +### Pull Requests + +- [#5105](https://github.com/rollup/rollup/pull/5105): Added option to name sourcemap files, i.e. a output.sourcemapFileName… (@atti187) +- [#5108](https://github.com/rollup/rollup/pull/5108): chore(deps): lock file maintenance minor/patch updates (@renovate[bot]) +- [#5109](https://github.com/rollup/rollup/pull/5109): Docs: load full path of rollup.browser.js for Rollup V4 (@TrickyPi) +- [#5112](https://github.com/rollup/rollup/pull/5112): feat(types): add generic type for plugin api (@sxzz) +- [#5115](https://github.com/rollup/rollup/pull/5115): chore(deps): lock file maintenance minor/patch updates (@renovate[bot]) +- [#5123](https://github.com/rollup/rollup/pull/5123): Deoptimize custom event detail (@lukastaegert) + ## 3.28.1 _2023-08-22_ diff --git a/browser/package.json b/browser/package.json index 5840865d6..18937dff1 100644 --- a/browser/package.json +++ b/browser/package.json @@ -1,6 +1,6 @@ { "name": "@rollup/browser", - "version": "3.28.1", + "version": "3.29.0", "description": "Next-generation ES module bundler browser build", "main": "dist/rollup.browser.js", "module": "dist/es/rollup.browser.js", diff --git a/package-lock.json b/package-lock.json index 1dc507ecf..236000795 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rollup", - "version": "3.28.1", + "version": "3.29.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rollup", - "version": "3.28.1", + "version": "3.29.0", "license": "MIT", "bin": { "rollup": "dist/bin/rollup" diff --git a/package.json b/package.json index 5ededb2bd..7998e2dbd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "3.28.1", + "version": "3.29.0", "description": "Next-generation ES module bundler", "main": "dist/rollup.js", "module": "dist/es/rollup.js",