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

move common logic to size-plugin-core #27

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6949fa5
added load & save functions
kuldeepkeshwar Jun 14, 2019
e4d39f7
updated snapshot
kuldeepkeshwar Jun 14, 2019
36f2622
added option to write stats to disk
kuldeepkeshwar Jun 14, 2019
344ea91
included files deleted in last build
kuldeepkeshwar Jun 17, 2019
304a4d0
updated test snapshot
kuldeepkeshwar Jun 20, 2019
c8f0bcb
write diff file for bot
kuldeepkeshwar Jun 21, 2019
e9963a3
removed writeToDisk and added webpack mode
kuldeepkeshwar Jun 23, 2019
0824ac2
updated test
kuldeepkeshwar Jun 25, 2019
c75b96e
Add support for size-plugin-bot
kuldeepkeshwar Jul 26, 2019
58cef5b
fix typo in comments
kuldeepkeshwar Jul 26, 2019
ea124be
reverted files ext
kuldeepkeshwar Jul 26, 2019
ae9d2fa
update comments
kuldeepkeshwar Jul 26, 2019
1a095b0
remove publish option default value as true
kuldeepkeshwar Aug 2, 2019
65ba82d
Update src/index.mjs
kuldeepkeshwar Aug 6, 2019
560057f
Update index.mjs
kuldeepkeshwar Aug 6, 2019
52ac7ac
changes from upstream
kuldeepkeshwar Aug 22, 2019
a46740d
Update README.md
kuldeepkeshwar Aug 22, 2019
5a30895
Merge branch 'master' into master
kuldeepkeshwar Aug 22, 2019
191cb2a
fixes #28 & remove pull_request_number
kuldeepkeshwar Aug 24, 2019
9429289
move publish logic in a new pkg size-plugin-store
kuldeepkeshwar Aug 27, 2019
b3b24a8
delete yarn lock
kuldeepkeshwar Aug 27, 2019
3ab2edf
fix: empty size*.json file
kuldeepkeshwar Aug 30, 2019
12389e0
move common logic to size-plugin-core
kuldeepkeshwar Sep 2, 2019
2956e62
update readme
kuldeepkeshwar Sep 2, 2019
23c7d9c
update docs for compression option
kuldeepkeshwar Sep 2, 2019
6caf0d2
correct docs
kuldeepkeshwar Sep 2, 2019
3fc927d
update SizePluginCore syntax
kuldeepkeshwar Sep 7, 2019
42a528b
update size-plugin-store version
kuldeepkeshwar Sep 8, 2019
735f944
update size-plugin-core version
kuldeepkeshwar Sep 14, 2019
46028ca
update size-plugin-core version
kuldeepkeshwar Oct 4, 2019
8c7b6d3
Update package.json
kuldeepkeshwar Oct 4, 2019
37b0161
update size-plugin-core version
kuldeepkeshwar Oct 18, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
</p>

> 🙋 Using Rollup? Check out the [rollup-plugin-size](https://github.com/luwes/rollup-plugin-size) port.
>
> 🙋‍♂ Using CI ? Check out [size-plugin-bot](https://github.com/kuldeepkeshwar/size-plugin-bot) 🤖 to automate intergation with CI

## Installation

Expand Down Expand Up @@ -62,6 +64,7 @@ module.exports = {
#### Parameters

- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
- `options.compression` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** compression method(gzip/brotli) to use, default: 'gzip'
- `options.pattern` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** minimatch pattern of files to track
- `options.exclude` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** minimatch pattern of files NOT to track
- `options.filename` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** file name to save filesizes to disk
Expand Down
9 changes: 1 addition & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,8 @@
"webpack": "^4.39.2"
},
"dependencies": {
"axios": "^0.19.0",
"chalk": "^2.4.2",
"ci-env": "^1.9.0",
"escape-string-regexp": "^1.0.5",
"glob": "^7.1.4",
"gzip-size": "^5.1.1",
"minimatch": "^3.0.4",
"pretty-bytes": "^5.3.0",
"util.promisify": "^1.0.0"
"size-plugin-core": "^0.0.7"
},
"peerDependencies": {
"webpack": "*"
Expand Down
186 changes: 18 additions & 168 deletions src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,15 @@
* the License.
*/

import path from 'path';
import promisify from 'util.promisify';
import globPromise from 'glob';
import minimatch from 'minimatch';
import gzipSize from 'gzip-size';
import chalk from 'chalk';
import prettyBytes from 'pretty-bytes';
import escapeRegExp from 'escape-string-regexp';
import { toMap, dedupe, toFileMap } from './util.mjs';
import { publishSizes, publishDiff } from './publish-size.mjs';
import fs from 'fs-extra';
import SizePluginCore from 'size-plugin-core';

const glob = promisify(globPromise);
const NAME = 'SizePlugin';

/**
* `new SizePlugin(options)`
* @param {Object} options
* @param {string} [options.compression] compression method(gzip/brotli) to use, default: 'gzip'
* @param {string} [options.pattern] minimatch pattern of files to track
* @param {string} [options.exclude] minimatch pattern of files NOT to track
* @param {string} [options.filename] file name to save filesizes to disk
Expand All @@ -44,12 +35,10 @@ const NAME = 'SizePlugin';
*/
export default class SizePlugin {
constructor(options) {
this.options = options || {};
this.pattern = this.options.pattern || '**/*.{mjs,js,css,html}';
this.exclude = this.options.exclude;
this.options.filename = this.options.filename || 'size-plugin.json';
this.options.writeFile = this.options.writeFile !== false;
this.filename = path.join(process.cwd(), this.options.filename);
const pluginOptions=options||{};
const coreOptions={ ...pluginOptions,stripHash: pluginOptions.stripHash||this.stripHash.bind(this) };
const core = new SizePluginCore(coreOptions);
this.core = core;
}

reverseTemplate(filename, template) {
Expand Down Expand Up @@ -100,66 +89,27 @@ export default class SizePlugin {

stripHash(filename) {
return (
(this.options.stripHash && this.options.stripHash(filename)) ||
this.reverseTemplate(filename, this.output.filename) ||
this.reverseTemplate(filename, this.output.chunkFilename) ||
filename
);
}
async readFromDisk(filename) {
try {
await fs.ensureFile(filename);
const oldStats = await fs.readJSON(filename);
return oldStats.sort((a, b) => b.timestamp - a.timestamp);
}
catch (err) {
return [];
}
}
async writeToDisk(filename, stats) {
if (
this.mode === 'production' &&
stats.files.some(file => file.diff !== 0)
) {
const data = await this.readFromDisk(filename);
data.unshift(stats);
if (this.options.writeFile) {
await fs.ensureFile(filename);
await fs.writeJSON(filename, data);
}
this.options.publish && (await publishSizes(data, this.options.filename));
}
}
async save(files) {
const stats = {
timestamp: Date.now(),
files: files.map(file => ({
filename: file.name,
previous: file.sizeBefore,
size: file.size,
diff: file.size - file.sizeBefore
}))
};
this.options.publish && (await publishDiff(stats, this.options.filename));
this.options.save && (await this.options.save(stats));
await this.writeToDisk(this.filename, stats);
}
async load(outputPath) {
const data = await this.readFromDisk(this.filename);
if (data.length) {
const [{ files }] = data;
return toFileMap(files);
}
return this.getSizes(outputPath);
}

async apply(compiler) {
const outputPath = compiler.options.output.path;
this.output = compiler.options.output;
this.sizes = this.load(outputPath);
this.mode = compiler.options.mode;
this.core.options.mode = compiler.options.mode;
const outputPath = compiler.options.output.path;

const afterEmit = (compilation, callback) => {
this.outputSizes(compilation.assets)
const assets = Object.keys(compilation.assets).reduce((agg, key) => {
agg[key] = {
source: compilation.assets[key].source()
};
return agg;
}, {});
// assets => {'a.js':{source:'console.log(1)'}}

this.core.execute(assets, outputPath)
.then(output => {
if (output) {
process.nextTick(() => {
Expand All @@ -180,107 +130,8 @@ export default class SizePlugin {
compiler.plugin('after-emit', afterEmit);
}
}

async outputSizes(assets) {
// map of filenames to their previous size
// Fix #7 - fast-async doesn't allow non-promise values.
const sizesBefore = await Promise.resolve(this.sizes);
const isMatched = minimatch.filter(this.pattern);
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
);

// get a list of unique filenames
const files = [
...Object.keys(sizesBefore),
...Object.keys(this.sizes)
].filter(dedupe);

const width = Math.max(...files.map(file => file.length));
let output = '';
const items = [];
for (const name of files) {
const size = this.sizes[name] || 0;
const sizeBefore = sizesBefore[name] || 0;
const delta = size - sizeBefore;
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));
let deltaText = '';
if (delta && Math.abs(delta) > 1) {
deltaText = (delta > 0 ? '+' : '') + prettyBytes(delta);
if (delta > 1024) {
sizeText = chalk.bold(sizeText);
deltaText = chalk.red(deltaText);
}
else if (delta < -10) {
deltaText = chalk.green(deltaText);
}
sizeText += ` (${deltaText})`;
}
let text = msg + sizeText + '\n';
const item = {
name,
sizeBefore,
size,
sizeText,
delta,
deltaText,
msg,
color
};
items.push(item);
if (this.options.decorateItem) {
text = this.options.decorateItem(text, item) || text;
}
output += text;
}
if (this.options.decorateAfter) {
const opts = {
sizes: items,
raw: { sizesBefore, sizes: this.sizes },
output
};
const text = this.options.decorateAfter(opts);
if (text) {
output += '\n' + text.replace(/^\n/g, '');
}
}
await this.save(items);
return output;
}

async getSizes(cwd) {
const files = await glob(this.pattern, { cwd, ignore: this.exclude });

const sizes = await Promise.all(
files.map(file => gzipSize.file(path.join(cwd, file)).catch(() => null))
);

return toMap(files.map(filename => this.stripHash(filename)), sizes);
}
}


/**
* @name Item
* @typedef Item
Expand All @@ -295,7 +146,6 @@ export default class SizePlugin {
* @public
*/


/**
* @name Data
* @typedef Data
Expand Down
30 changes: 0 additions & 30 deletions src/publish-size.mjs

This file was deleted.

34 changes: 0 additions & 34 deletions src/util.mjs

This file was deleted.