Skip to content

Commit cfc4325

Browse files
committed
Display Build Size Difference
1 parent 884d567 commit cfc4325

File tree

2 files changed

+101
-64
lines changed

2 files changed

+101
-64
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"opn": "4.0.2",
6767
"postcss-loader": "0.9.1",
6868
"promise": "7.1.1",
69+
"recursive-readdir": "^2.0.0",
6970
"rimraf": "2.5.4",
7071
"style-loader": "0.13.1",
7172
"url-loader": "0.5.7",

scripts/build.js

+100-64
Original file line numberDiff line numberDiff line change
@@ -18,79 +18,115 @@ var rimrafSync = require('rimraf').sync;
1818
var webpack = require('webpack');
1919
var config = require('../config/webpack.config.prod');
2020
var paths = require('../config/paths');
21+
var recursive = require('recursive-readdir');
2122

22-
// Remove all content but keep the directory so that
23-
// if you're in it, you don't end up in Trash
24-
rimrafSync(paths.appBuild + '/*');
23+
function removeFileNameHash(fileName) {
24+
return fileName.replace(paths.appBuild, '')
25+
.replace(/\/?(.*)(\.\w+)(\.js|\.css)/, function(match, p1, p2, p3) {
26+
return p1 + p3;
27+
});
28+
}
2529

26-
console.log('Creating an optimized production build...');
27-
webpack(config).run(function(err, stats) {
28-
if (err) {
29-
console.error('Failed to create a production build. Reason:');
30-
console.error(err.message || err);
31-
process.exit(1);
30+
function sizeDifference(currentSize, previousSize) {
31+
if (previousSize === undefined) { return ''; }
32+
var difference = currentSize - previousSize;
33+
var fileSize = filesize(difference);
34+
if (difference > 0) {
35+
return chalk.red('+' + fileSize);
36+
} else if (difference <= 0){
37+
return chalk.green((difference === 0 ? '+' : '') + fileSize);
3238
}
39+
}
3340

34-
console.log(chalk.green('Compiled successfully.'));
35-
console.log();
41+
recursive(paths.appBuild, function (err, fileNames) {
42+
fileNames = fileNames || [];
43+
var previousSizeMap = fileNames.filter(fileName => /\.(js|css)$/.test(fileName))
44+
.reduce((memo, fileName) => {
45+
var contents = fs.readFileSync(fileName);
46+
var key = removeFileNameHash(fileName);
47+
memo[key] = gzipSize(contents);
48+
return memo;
49+
}, {} );
3650

37-
console.log('File sizes after gzip:');
38-
console.log();
39-
var assets = stats.toJson().assets
40-
.filter(asset => /\.(js|css)$/.test(asset.name))
41-
.map(asset => {
42-
var fileContents = fs.readFileSync(paths.appBuild + '/' + asset.name);
43-
var size = gzipSize(fileContents);
44-
return {
45-
folder: path.join('build', path.dirname(asset.name)),
46-
name: path.basename(asset.name),
47-
size: size,
48-
sizeLabel: filesize(size)
49-
};
50-
});
51-
assets.sort((a, b) => b.size - a.size);
51+
// Remove all content but keep the directory so that
52+
// if you're in it, you don't end up in Trash
53+
rimrafSync(paths.appBuild + '/*');
54+
55+
build(previousSizeMap);
56+
});
5257

53-
var longestSizeLabelLength = Math.max.apply(null,
54-
assets.map(a => a.sizeLabel.length)
55-
);
56-
assets.forEach(asset => {
57-
var sizeLabel = asset.sizeLabel;
58-
if (sizeLabel.length < longestSizeLabelLength) {
59-
var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLabel.length);
60-
sizeLabel += rightPadding;
58+
function build(previousSizeMap) {
59+
console.log('Creating an optimized production build...');
60+
webpack(config).run(function(err, stats) {
61+
if (err) {
62+
console.error('Failed to create a production build. Reason:');
63+
console.error(err.message || err);
64+
process.exit(1);
6165
}
62-
console.log(
63-
' ' + chalk.green(sizeLabel) +
64-
' ' + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name)
65-
);
66-
});
67-
console.log();
6866

69-
var openCommand = process.platform === 'win32' ? 'start' : 'open';
70-
var homepagePath = require(paths.appPackageJson).homepage;
71-
if (homepagePath) {
72-
console.log('You can now publish them at ' + homepagePath + '.');
73-
console.log('For example, if you use GitHub Pages:');
67+
console.log(chalk.green('Compiled successfully.'));
7468
console.log();
75-
console.log(' git commit -am "Save local changes"');
76-
console.log(' git checkout -B gh-pages');
77-
console.log(' git add -f build');
78-
console.log(' git commit -am "Rebuild website"');
79-
console.log(' git filter-branch -f --prune-empty --subdirectory-filter build');
80-
console.log(' git push -f origin gh-pages');
81-
console.log(' git checkout -');
69+
70+
console.log('File sizes after gzip:');
8271
console.log();
83-
} else {
84-
console.log('You can now serve them with any static server.');
85-
console.log('For example:');
72+
var assets = stats.toJson().assets
73+
.filter(asset => /\.(js|css)$/.test(asset.name))
74+
.map(asset => {
75+
var fileContents = fs.readFileSync(paths.appBuild + '/' + asset.name);
76+
var size = gzipSize(fileContents);
77+
var previousSize = previousSizeMap[removeFileNameHash(asset.name)];
78+
var difference = sizeDifference(size, previousSize);
79+
return {
80+
folder: path.join('build', path.dirname(asset.name)),
81+
name: path.basename(asset.name),
82+
size: size,
83+
sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : '')
84+
};
85+
});
86+
assets.sort((a, b) => b.size - a.size);
87+
88+
var longestSizeLabelLength = Math.max.apply(null,
89+
assets.map(a => a.sizeLabel.length)
90+
);
91+
assets.forEach(asset => {
92+
var sizeLabel = asset.sizeLabel;
93+
if (sizeLabel.length < longestSizeLabelLength) {
94+
var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLabel.length);
95+
sizeLabel += rightPadding;
96+
}
97+
console.log(
98+
' ' + chalk.yellow(sizeLabel) +
99+
' ' + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name)
100+
);
101+
});
86102
console.log();
87-
console.log(' npm install -g pushstate-server');
88-
console.log(' pushstate-server build');
89-
console.log(' ' + openCommand + ' http://localhost:9000');
103+
104+
var openCommand = process.platform === 'win32' ? 'start' : 'open';
105+
var homepagePath = require(paths.appPackageJson).homepage;
106+
if (homepagePath) {
107+
console.log('You can now publish them at ' + homepagePath + '.');
108+
console.log('For example, if you use GitHub Pages:');
109+
console.log();
110+
console.log(' git commit -am "Save local changes"');
111+
console.log(' git checkout -B gh-pages');
112+
console.log(' git add -f build');
113+
console.log(' git commit -am "Rebuild website"');
114+
console.log(' git filter-branch -f --prune-empty --subdirectory-filter build');
115+
console.log(' git push -f origin gh-pages');
116+
console.log(' git checkout -');
117+
console.log();
118+
} else {
119+
console.log('You can now serve them with any static server.');
120+
console.log('For example:');
121+
console.log();
122+
console.log(' npm install -g pushstate-server');
123+
console.log(' pushstate-server build');
124+
console.log(' ' + openCommand + ' http://localhost:9000');
125+
console.log();
126+
console.log(chalk.dim('The project was built assuming it is hosted at the root.'));
127+
console.log(chalk.dim('Set the "homepage" field in package.json to override this.'));
128+
console.log(chalk.dim('For example, "homepage": "http://user.github.io/project".'));
129+
}
90130
console.log();
91-
console.log(chalk.dim('The project was built assuming it is hosted at the root.'));
92-
console.log(chalk.dim('Set the "homepage" field in package.json to override this.'));
93-
console.log(chalk.dim('For example, "homepage": "http://user.github.io/project".'));
94-
}
95-
console.log();
96-
});
131+
});
132+
}

0 commit comments

Comments
 (0)