Skip to content

Commit

Permalink
fix: make file name deterministic in parallel emits (fix rollup#4909)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan committed Mar 19, 2023
1 parent 680912e commit 14dcbd7
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 16 deletions.
25 changes: 17 additions & 8 deletions src/utils/FileEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,14 +365,23 @@ export class FileEmitter {
if (!fileName) {
const sourceHash = getSourceHash(source);
fileName = fileNamesBySource.get(sourceHash);
if (!fileName) {
fileName = generateAssetFileName(
consumedFile.name,
source,
sourceHash,
outputOptions,
bundle
);
const newFileName = generateAssetFileName(
consumedFile.name,
source,
sourceHash,
outputOptions,
bundle
);
// make sure file name deterministic in parallel emits, always use the shorter and smaller file name
if (
!fileName ||
fileName.length > newFileName.length ||
(fileName.length === newFileName.length && fileName.localeCompare(newFileName) > 0)
) {
if (fileName) {
delete bundle[fileName];
}
fileName = newFileName;
fileNamesBySource.set(sourceHash, fileName);
}
}
Expand Down
35 changes: 27 additions & 8 deletions test/chunking-form/samples/emit-file/deduplicate-assets/_config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
function asyncify(callback) {
const time = Math.round(Math.random() * 100);

return new Promise(resolve => {
setTimeout(() => {
callback();
resolve();
}, time);
});
}
module.exports = {
description: 'deduplicates asset that have the same source',
solo: true,
options: {
input: ['main.js'],
plugins: {
buildStart() {
this.emitFile({ type: 'asset', name: 'string.txt', source: 'string' });
this.emitFile({ type: 'asset', name: 'stringSameSource.txt', source: 'string' });
this.emitFile({
type: 'asset',
name: 'sameStringAsBuffer.txt',
source: Buffer.from('string') // Test cross Buffer/string deduplication
});
async buildStart() {
await Promise.all([
asyncify(() => this.emitFile({ type: 'asset', name: 'string1.txt', source: 'string' })),
asyncify(() => this.emitFile({ type: 'asset', name: 'string2.txt', source: 'string' })),
asyncify(() =>
this.emitFile({ type: 'asset', name: 'stringSameSource.txt', source: 'string' })
),
asyncify(() =>
this.emitFile({
type: 'asset',
name: 'sameStringAsBuffer.txt',
source: Buffer.from('string') // Test cross Buffer/string deduplication
})
)
]);

// Different string source
this.emitFile({ type: 'asset', name: 'otherString.txt', source: 'otherString' });

Expand Down

0 comments on commit 14dcbd7

Please sign in to comment.