Giter Club home page Giter Club logo

size-plugin's Introduction

size-plugin npm

Prints the gzipped sizes of your webpack assets and the changes since the last build.

size-plugin

πŸ™‹ Using Rollup? Check out the rollup-plugin-size port.

Installation

Install size-plugin as a development dependency using npm:

npm i -D size-plugin

Usage

Add an instance of the plugin to your webpack configuration:

// webpack.config.js
+ const SizePlugin = require('size-plugin');

module.exports = {
  plugins: [
+    new SizePlugin()
  ]
}

Options

Table of Contents

SizePlugin

new SizePlugin(options)

Parameters

  • options Object
    • options.pattern string? minimatch pattern of files to track
    • options.exclude string? minimatch pattern of files NOT to track
    • options.filename string? file name to save filesizes to disk
    • options.publish boolean? option to publish filesizes to size-plugin-store
    • options.writeFile boolean? option to save filesizes to disk
    • options.stripHash function? custom function to remove/normalize hashed filenames for comparison

Item

Properties

  • name string Filename of the item
  • sizeBefore number Previous size, in kilobytes
  • size number Current size, in kilobytes
  • sizeText string Formatted current size
  • delta number Difference from previous size, in kilobytes
  • deltaText string Formatted size delta
  • msg string Full item's default message
  • color string The item's default CLI color

Data

Properties

  • sizes Array<Item> List of file size items
  • output string Current buffered output

License

Apache 2.0

This is not an official Google product.

size-plugin's People

Contributors

amilajack avatar blackhole1 avatar developit avatar djaler avatar kuldeepkeshwar avatar samundrak avatar sebkolind avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

size-plugin's Issues

Ability to set limits and error on them

This plugin is so awesome for a first release! It'd be even more awesome if you could set upper limits on the delta and overall sizes to end with errors.

TypeScript types

First off, thanks for the plugin. πŸ‘

I'm going to be creating the TypeScript types for this package as it's used in the Refined GitHub extension, refined-github/refined-github#1987 (comment), where I recently helped convert the project to TypeScript.

My question is, would you be willing to host the types in this repository if I put up a PR or am I better off sending a PR to the DefinitelyTyped project?

Output size difference is always the same size as actual output

Hi,

Love the idea of this plugin ! Has anybody got it working ?

For me the output of the plugin is always the same the actual file size output, i.e. it never compares with previous builds

I.e. sample output

vendors~admin~create-bet~login.bundle.9aa89c670076013d8fb7.js ⏀  20.9 kB (+20.9 kB)
                                                      main.css ⏀  2.18 kB (+2.18 kB)
                           main.bundle.ca78aa7c8d6b80d6a794.js ⏀  8.28 kB (+8.28 kB)
                                                         2.css ⏀  107 B (+107 B)
                      dashboard.bundle.c2606a256910c68c213f.js ⏀  1.17 kB (+1.17 kB)
                     create-bet.bundle.3b2e0767f6308ec7e4ca.js ⏀  1.23 kB (+1.23 kB)
                                                         4.css ⏀  205 B (+205 B)
                          admin.bundle.5740df303ba85130515a.js ⏀  3.02 kB (+3.02 kB)
                          login.bundle.96773d2bb3d6c67df42a.js ⏀  1.04 kB (+1.04 kB)
                   vendors~main.bundle.73fbc0215d9b89852b15.js ⏀  149 kB (+149 kB)
                                                    index.html ⏀  541 B (+541 B)

And here is my sample webpack config :

https://github.com/stevenfitzpatrick/mybettingslips/blob/master/build-utils/webpack.prod.js

And yes I tried to change the order of the size plugin putting it first / last always same result.

[BUG] unwanted **size-plugin.json** file

Hello,

Since latest release 2.0.0 a size-plugin.json file is created.
Passing option writeFile: false doesn't help to prevent that.

I guess this is bug introduced with the new release as I nothing change on my side.

Cheers :)

Bottom

Would it be possible to show in the bottom of everything? I have to scroll up to see the result πŸ‘Ž

Other than that, great plugin! πŸ‘

Ability for a custom function using sizes

Hi there πŸ‘‹

I'm trying to create a plugin that calculates file sizes of all bundles and then pushes those stats to a custom data store, Firebase Cloud Firestore in my case. So I've looked into reusing this plugin.

One approach would be to create a new plugin that extends SizePlugin, overriding the apply method to not print to console, and instead use this.sizes as I see fit. Somethingl ik

export default class MyCustomSizePlugin extends SizePlugin {
    async apply(compiler) {
        const outputPath = compiler.options.output.path;
        this.output = compiler.options.output;

        const afterEmit = (compilation, callback) => {
            this.load(outputPath)
                .then((sizes)=> {
                    /* do what I need to do with sizes */
                })
                .catch(console.error)
                .then(callback);
        };

        /* ... */
    }
}

Note: the example above doesn't work fully as expected, still haven't figured out why, but I imagine it's possible to make it work.

Another approach I like more is to add a new feature to size-plugin to offer a custom callback. This way, we keep pretty printing as well as offer the ability for developers to do any additional operations with the calculated sizes. It could look like this:

// in webpack config
plugins: [
  SizePlugin({
    onSizesCalculated: (sizes) => { /* custom handling of the bundle sizes */ },
  }),
],

The code change required would likely be minimal, probably:

if (this.options.onSizesCalculated) {
    this.options.onSizesCalculated(Object.assign({}, this.sizes});
}

For context, the this.sizes object of the plugin looks like this:

{
    'bundle.js': 1070,
    '1.*****.chunk.js': 102,
    '2.*****.chunk.js': 137,
}

How do these ideas sound? Am I over-complicating myself and there's a simpler way to solve my problem without using size-plugin? Or does the idea of adding a custom callback sound valuable? I'd be happy to open PR if that's the case.

Store the output

More of a feature request, anyway i can extract it and store the sizing over multiple builds? So i can historically track down major jumps?

Let it write to a json or something that i can then graph out in jenkins or in local for analysis?

Webpack 3 compatibility?

Awesome project! It is one of those many DX features, which CRA gets right - only generalized for everyone's benefit. Thank you! :)
Is there a chance to make the plugin compatible with webpack@3? Many projects are still using it (including CRA) and can benefit greatly from your plugin.

Emits all dependencies files if output path is set to project root

In webpack v4 it will create dist folder if not defined, but if we explicitly set the output path to the root of the project then this plugin will console log all the dependencies and its diff.
Problem is seen on glob it fetches all files and even there will be an error of like can't read on the directory.

image

TypeError: this.sizes.then is not a function

Getting this when running webpack in watch mode:

TypeError: this.sizes.then is not a function
    at SizePlugin.<anonymous> (node_modules/size-plugin/src/index.mjs:91:23)
    at new Promise (<anonymous>)
    at SizePlugin.outputSizes (node_modules/size-plugin/dist/size-plugin.js:81:12)
    at node_modules/size-plugin/src/index.mjs:86:65
    at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:8:1)
    at asyncLib.forEach.err (node_modules/webpack/lib/Compiler.js:355:27)
    at done (node_modules/neo-async/async.js:2854:11)
    at node_modules/neo-async/async.js:2805:7
    at MemoryFileSystem.writeFile (node_modules/memory-fs/lib/MemoryFileSystem.js:328:9)
    at writeOut (node_modules/webpack/lib/Compiler.js:339:29)
    at Immediate.<anonymous> (node_modules/memory-fs/lib/MemoryFileSystem.js:288:4)
    at runCallback (timers.js:693:18)
    at tryOnImmediate (timers.js:664:5)
    at processImmediate (timers.js:646:5)
    at process.topLevelDomainCallback (domain.js:121:23)

Using thread-loader, webpack-serve, ts-loader, ExtractTextPlugin and a few others. Not sure if relevant.

Files missing in Output

Greetings Everyone!

I'm trying to integrate this Plugin into one of my current projects. unfrtunately its not working as expected and >90% of my files are not getting reported/tracked.

Everything that my project needs is located in the src folder and weback builds into my public folder. For several reasons i have different Plugins in my configuration maybe they interfere each other. The output directory is set in my webpack configuration

Expected Behaviour

After the build is finished, a stats.json should be generated with all the informations about my files in the output directory

Actual Behaviour

A stats file is generated with almost none files

[
	{
		"timestamp": 1636799658202,
		"files": [
			{
				"filename": "css/dark.css",
				"previous": 0,
				"size": 122,
				"diff": 122
			},
			{
				"filename": "css/light.css",
				"previous": 0,
				"size": 111,
				"diff": 111
			},
			{
				"filename": "index.html",
				"previous": 0,
				"size": 320,
				"diff": 320
			}
		]
	}
]

Webpack configuration

const path = require("path");
const zlib = require("zlib");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const SizePlugin = require('size-plugin');

module.exports = {
    entry: "./src/react/index.ts",
    resolve: {
        extensions: [".ts", ".tsx", ".js", "css"],
    },
    devServer: {
        static: {
            directory: path.join(__dirname, "public"),
        },
    },
    experiments: {
        asset: true,
    },
    output: {
        path: path.join(__dirname, "/public"),
        filename: "./js/[name].bundle.js",
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: "ts-loader",
            },
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            esModule: false,
                        },
                    },
                    "css-loader",
                ],
                exclude: [
                    path.resolve("src/css/dark.css"),
                    path.resolve("src/css/light.css"),
                ],
            },
            {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: "asset/resource",
                generator: {
                    filename: "img/[hash][ext][query]",
                },
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/i,
                type: "asset/resource",
                generator: {
                    filename: "css/[hash][ext][query]",
                },
            },
        ],
    },
    optimization: {
        splitChunks: {
            cacheGroups: {
                defaultVendors: {
                    test: /[\\/]node_modules[\\/]/,
                    name: "vendors",
                    chunks: "all",
                },
            },
        },
        minimize: true,
        minimizer: [
            new TerserPlugin(),
            new CssMinimizerPlugin(),
        ],
    },
    plugins: [
        new CopyPlugin({
            patterns: [
                {
                    context: "./src",
                    from: "css/dark.css",
                    to: "./css/dark.css",
                },
                {
                    context: "./src",
                    from: "css/light.css",
                    to: "./css/light.css",
                },
                {
                    context: "./src",
                    from: "img/**/*",
                    to: "./",
                },
                {
                    context: "./src",
                    from: "locales/**/*",
                    to: "./",
                },
            ],
        }),
        new MiniCssExtractPlugin({
            filename: "./css/[name].css",
            chunkFilename: "./css/[name].bundle.css",
        }),
        new HtmlWebpackPlugin({
            template: "./src/html/index.html",
            favicon: "./src/html/favicon.ico",
        }),
        new CompressionPlugin({
            filename: "[path][base].br",
            algorithm: "brotliCompress",
            test: /\.js$|\.css$|\.html$|\.jpg$|\.svg$|\.eot$|\.ttf$|\.woff$|\.woff2$/,
            compressionOptions: {
                params: {
                    [zlib.constants.BROTLI_PARAM_QUALITY]: 11,
                },
            },
            minRatio: Number.MAX_SAFE_INTEGER,
        }),
        new CompressionPlugin({
            filename: "[path][base].gz",
            algorithm: "gzip",
            test: /\.js$|\.css$|\.html$|\.jpg$|\.svg$|\.eot$|\.ttf$|\.woff$|\.woff2$/,
            minRatio: Number.MAX_SAFE_INTEGER,
        }),
        new SizePlugin(),
    ],
};

Final remarks

  • Besides that i have to admit that im not an webpack magician and this behaviour may be expected, i missed some configuration to the plugin or the order of the plugins is wrong.
  • Im using v2.0.2 because the newest is not working with the new version of webpack #40
  • i tried several variants of the pattern value but they didnt affect the outcome

Testcase

Its always hard to imagine what another person is doing and because of this i have created a minimal example that shows what im doing and what is happening

Repository

I would greatly appreciate any hints to solve this :)

Add option to show real build size not gzipped

Hi,

When comparing real assets size to the output of your plugin I see a huge difference.

I guess it's because size-plugin show gzipped sizes...
This can be confusing or non relevant depending of the use case and it could be nice to add a column to the output. (to display both compressed and real assets size)

Or maybe just an option to choose what too show?!

Tks !!

ETA on new version

Hey there,

I see #21 was merged a while ago πŸŽ‰ Is there an ETA for when a new npm version will be published?

Cheers.

Compatibility with clean-webpack-plugin (or just any plugin to clean the build dir before the build

Related to #6 but different in that I only want the data to be cached right at the start, so that a clean build can still be performed.

Also I'm running into issues when trying to use both this plug-in and clean-webpack-plugin:

(node:29504) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open 'C:\Users\Eric\code\vscode-gitlens\dist\extension.js'
(node:29504) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:29504) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Warning: The 'no-floating-promises' rule requires type information.
(node:29504) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
{ Error: ENOENT: no such file or directory, open 'C:\Users\Eric\code\vscode-gitlens\dist\extension.js'
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'C:\\Users\\Eric\\code\\vscode-gitlens\\dist\\extension.js' }

In my webpack config, I was adding new SizePlugin() as the first plugin.

Include deleted files in Diff

We should consider including files from the previous build in the diff which are not present in the new build.
Currently size-plugin only includes files present in both builds (current & previous) plus files which are added in the current build.

PS showing total bundle size(+/- diff) can be useful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.