Skip to content

Commit

Permalink
[FIX] Bundler: Ensure reproducibility for bundles with multiple parts
Browse files Browse the repository at this point in the history
Sort modules in preload sections alphabetically.
This caused different bundle contents based on the order of modules that
the resolver provides, which is not deterministic.

Remove terser from size estimation as modules are now already optimized
if the 'optimize' bundle option is enabled.
This caused incorrect estimations about the bundle size which resulted
into size differences of the individual parts.
  • Loading branch information
matz3 committed Jan 21, 2022
1 parent 26084d1 commit ec73582
Showing 1 changed file with 10 additions and 23 deletions.
33 changes: 10 additions & 23 deletions lib/lbt/bundle/AutoSplitter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use strict";

const terser = require("terser");
const {pd} = require("pretty-data");

const ModuleName = require("../utils/ModuleName");
Expand Down Expand Up @@ -112,6 +111,7 @@ class AutoSplitter {

resolvedModule.sections.forEach( (section) => {
let currentSection;
let sequence;
switch ( section.mode ) {
case SectionType.Provided:
// 'provided' sections are no longer needed in a fully resolved module
Expand All @@ -131,16 +131,20 @@ class AutoSplitter {
});
break;
case SectionType.Preload:
sequence = section.modules.slice();
// simple version: just sort alphabetically
sequence.sort();

// NODE_TODO: sort by copyright:
// sequence = section.modules.slice();
// jsBuilder.beforeWriteFunctionPreloadSection((List<ModuleName>) sequence);

currentSection = {
mode: SectionType.Preload,
filters: []
};
currentSection.name = section.name;
currentModule.sections.push( currentSection );
section.modules.forEach( (module) => {
sequence.forEach( (module) => {
const moduleSize = moduleSizes[module];
if ( part + 1 < numberOfParts && totalSize + moduleSize / 2 > partSize ) {
part++;
Expand Down Expand Up @@ -195,26 +199,9 @@ class AutoSplitter {
}

if ( /\.js$/.test(module) ) {
// console.log("determining compressed size for %s", module);
let fileContent = await resource.buffer();
if ( this.optimize ) {
// console.log("uglify %s start", module);
const result = await terser.minify({
[resource.name]: String(fileContent)
}, {
warnings: false, // TODO configure?
compress: false, // TODO configure?
output: {
comments: copyrightCommentsPattern,
wrap_func_args: false
}
// , outFileName: resource.name
// , outSourceMap: true
});
// console.log("uglify %s end", module);
fileContent = result.code;
}
// trace.debug("analyzed %s:%d%n", module, mw.getTargetLength());
// No optimize / minify step here as the input should be
// either already optimized or not, based on the bundle options
const fileContent = await resource.buffer();
return fileContent.length;
} else if ( /\.properties$/.test(module) ) {
/* NODE-TODO minimize *.properties
Expand Down

0 comments on commit ec73582

Please sign in to comment.