Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding history for builds into json #15

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
dist
package-lock.json
package-lock.json
.history
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ module.exports = {

---

## Options

### History
This option will store a json file with the history of your build that you then can use to do bundle analysis over a period of time
```js
// webpack.config.js
const SizePlugin = require('size-plugin');

module.exports = {
plugins: [
new SizePlugin({
json: true,
filename: 'report.json' // Relative to where webpack is ran
})
]
}
```

---

## License

[Apache 2.0](LICENSE)
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"escape-string-regexp": "^1.0.5",
"glob": "^7.1.2",
"gzip-size": "^5.0.0",
"jsx": "^0.9.89",
"minimatch": "^3.0.4",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is jsx installed?

"pretty-bytes": "^5.1.0",
"util.promisify": "^1.0.0"
Expand Down
90 changes: 83 additions & 7 deletions src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import path from 'path';
import fs from 'fs';
import promisify from 'util.promisify';
import globPromise from 'glob';
import minimatch from 'minimatch';
Expand All @@ -33,6 +34,9 @@ export default class SizePlugin {
this.options = options || {};
this.pattern = this.options.pattern || '**/*.{mjs,js,css,html}';
this.exclude = this.options.exclude;
this.json = this.options.json;
this.jsonPath = path.resolve(process.cwd(), this.options.filename || 'build-sizes.json');
this.buildTimestamp = Math.floor(Date.now());
}

reverseTemplate(filename, template) {
Expand Down Expand Up @@ -81,8 +85,8 @@ export default class SizePlugin {
stripHash(filename) {
return (
this.reverseTemplate(filename, this.output.filename) ||
this.reverseTemplate(filename, this.output.chunkFilename) ||
filename
this.reverseTemplate(filename, this.output.chunkFilename) ||
filename
);
}

Expand All @@ -104,6 +108,55 @@ export default class SizePlugin {
});
}

async writeFile (file, data) {
return new Promise((resolve, reject) => {
fs.writeFile(file, data, error => {
if (error) reject(error);
resolve();
});
});
}

async readFile (file) {
return new Promise((resolve, reject) => {
fs.readFile(file, (error, data) => {
if (error && error.code !== 'ENOENT') reject(error);
resolve(data);
});
});
}

async storeToFile (buildResult) {
console.log(this.jsonPath);
try {
const fileContents = await this.readFile(this.jsonPath);
let json = [];
if (fileContents) {
json = JSON.parse(fileContents);
}

json.push(buildResult);
await this.writeFile(this.jsonPath, JSON.stringify(json));
console.log(chalk.green(`file got stored at: ${this.jsonPath}`));
}
catch (e) {
console.error(chalk.green(`Couldn't store json: ${e}`));
}
}

async getPreviousSizeFromJson (fileName) {
const fileContents = await this.readFile(this.jsonPath);
if (fileContents) {
const json = JSON.parse(fileContents);
const files = json[json.length - 1].files;
const result = files.find( file => file.filename === fileName );

return result.size;
}

return undefined;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its good to promisify all fs methods so we can make use of async/await function,
let me know your view 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point i made some changes, i didn't use promisify util to make sure it can still support older versions of node. I've also updated the readme file to show the option let me know what you think


async outputSizes (assets) {
// map of filenames to their previous size
// Fix #7 - fast-async doesn't allow non-promise values.
Expand All @@ -112,7 +165,7 @@ export default class SizePlugin {
const isExcluded = this.exclude ? minimatch.filter(this.exclude) : () => false;
const assetNames = Object.keys(assets).filter(file => isMatched(file) && !isExcluded(file));
const sizes = await Promise.all(assetNames.map(name => gzipSize(assets[name].source())));

// map of de-hashed filenames to their final size
this.sizes = toMap(assetNames.map(filename => this.stripHash(filename)), sizes);

Expand All @@ -121,12 +174,32 @@ export default class SizePlugin {

const width = Math.max(...files.map(file => file.length));
let output = '';

let jsonOutput= {
timestamp: this.buildTimestamp,
files: []
};

for (const name of files) {
const size = this.sizes[name] || 0;
const delta = size - (sizesBefore[name] || 0);
const msg = new Array(width - name.length + 2).join(' ') + name + ' ⏤ ';
const size = this.sizes[name] || 0;
let sizeBefore = sizesBefore[name] || 0;
if (sizeBefore === 0) {
sizeBefore = await this.getPreviousSizeFromJson(name);
}
const delta = size - (sizeBefore || 0);
const msg = `${new Array(width - name.length + 2).join(' ')}${name} ⏤ `;
const color = size > 100 * 1024 ? 'red' : size > 40 * 1024 ? 'yellow' : size > 20 * 1024 ? 'cyan' : 'green';
let sizeText = chalk[color](prettyBytes(size));

if (this.json){
jsonOutput.files.push({
filename: name,
previous: sizeBefore || size,
size: size,
diff: delta || 0
});
}

let sizeText = chalk[color](prettyBytes(size));
if (delta) {
let deltaText = (delta > 0 ? '+' : '') + prettyBytes(delta);
if (delta > 1024) {
Expand All @@ -141,6 +214,9 @@ export default class SizePlugin {
output += msg + sizeText + '\n';
}
if (output) {
if (this.json){
this.storeToFile(jsonOutput);
}
console.log(output);
}
}
Expand Down
98 changes: 97 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,23 @@ escodegen@^1.9.1:
optionalDependencies:
source-map "~0.6.1"

"escodegen@~ 0.0.20", "escodegen@~ 0.0.28":
version "0.0.28"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-0.0.28.tgz#0e4ff1715f328775d6cab51ac44a406cd7abffd3"
integrity sha1-Dk/xcV8yh3XWyrUaxEpAbNer/9M=
dependencies:
esprima "~1.0.2"
estraverse "~1.3.0"
optionalDependencies:
source-map ">= 0.1.2"

"escope@~ 1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/escope/-/escope-1.0.3.tgz#759dce8496c4248fec2d0caaf4108bcf3f1a7f5d"
integrity sha1-dZ3OhJbEJI/sLQyq9BCLzz8af10=
dependencies:
estraverse "^2.0.0"

eslint-config-developit@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/eslint-config-developit/-/eslint-config-developit-1.1.1.tgz#724c0855ffcbeab81be033ea7a47afec4b246d2c"
Expand Down Expand Up @@ -2192,6 +2209,19 @@ eslint@^5.4.0:
table "^4.0.3"
text-table "^0.2.0"

"esmangle@~ 0.0.14":
version "0.0.17"
resolved "https://registry.yarnpkg.com/esmangle/-/esmangle-0.0.17.tgz#4c5c93607cde5d1276bad396e836229dba68d90c"
integrity sha1-TFyTYHzeXRJ2utOW6DYinbpo2Qw=
dependencies:
escodegen "~ 0.0.28"
escope "~ 1.0.0"
esprima "~ 1.0.2"
esshorten "~ 0.0.2"
estraverse "~ 1.3.2"
optimist "*"
source-map "~ 0.1.8"

espree@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634"
Expand All @@ -2211,6 +2241,11 @@ esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"

"esprima@~ 1.0.2", esprima@~1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad"
integrity sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=

esquery@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
Expand All @@ -2223,10 +2258,33 @@ esrecurse@^4.1.0:
dependencies:
estraverse "^4.1.0"

"esshorten@~ 0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/esshorten/-/esshorten-0.0.2.tgz#28a652f1efd40c8e227f8c6de7dbe6b560ee8129"
integrity sha1-KKZS8e/UDI4if4xt59vmtWDugSk=
dependencies:
escope "~ 1.0.0"
estraverse "~ 1.2.0"

estraverse@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-2.0.0.tgz#5ae46963243600206674ccb24a09e16674fcdca1"
integrity sha1-WuRpYyQ2ACBmdMyySgnhZnT83KE=

estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"

"estraverse@~ 1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.2.0.tgz#6a3dc8a46a5d6766e5668639fc782976ce5660fd"
integrity sha1-aj3IpGpdZ2blZoY5/Hgpds5WYP0=

"estraverse@~ 1.3.2", estraverse@~1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.3.2.tgz#37c2b893ef13d723f276d878d60d8535152a6c42"
integrity sha1-N8K4k+8T1yPydth41g2FNRUqbEI=

estree-walker@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e"
Expand Down Expand Up @@ -3684,6 +3742,17 @@ jsx-ast-utils@^2.0.1:
dependencies:
array-includes "^3.0.3"

jsx@^0.9.89:
version "0.9.89"
resolved "https://registry.yarnpkg.com/jsx/-/jsx-0.9.89.tgz#c589688dc9ffe04a211fdb633cc7d202dd78a922"
integrity sha1-xYlojcn/4EohH9tjPMfSAt14qSI=
dependencies:
escodegen "~ 0.0.20"
esmangle "~ 0.0.14"
esprima "~ 1.0.2"
source-map "~ 0.1.22"
source-map-support "~ 0.2.1"

kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
Expand Down Expand Up @@ -4348,9 +4417,10 @@ onetime@^2.0.0:
dependencies:
mimic-fn "^1.0.0"

optimist@^0.6.1:
optimist@*, optimist@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
dependencies:
minimist "~0.0.1"
wordwrap "~0.0.2"
Expand Down Expand Up @@ -5633,10 +5703,29 @@ source-map-support@^0.5.6:
buffer-from "^1.0.0"
source-map "^0.6.0"

"source-map-support@~ 0.2.1":
version "0.2.10"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc"
integrity sha1-6lo5AKHByyUJagrozFwrSxDe09w=
dependencies:
source-map "0.1.32"

source-map-url@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"

[email protected]:
version "0.1.32"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266"
integrity sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=
dependencies:
amdefine ">=0.0.4"

"source-map@>= 0.1.2":
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==

source-map@^0.4.4:
version "0.4.4"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
Expand All @@ -5651,6 +5740,13 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"

"source-map@~ 0.1.22", "source-map@~ 0.1.8":
version "0.1.43"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=
dependencies:
amdefine ">=0.0.4"

spdx-correct@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82"
Expand Down