GithubHelp home page GithubHelp logo

trysound / rollup-plugin-size-snapshot Goto Github PK

View Code? Open in Web Editor NEW
162.0 5.0 14.0 1.2 MB

Track your library bundles size and its treeshakability with less effort

License: MIT License

JavaScript 100.00%

rollup-plugin-size-snapshot's Introduction

rollup-plugin-size-snapshot Build Status

This plugin provides details about

  • actual bundle size (bundler parsing size)
  • minified bundle size (browser parsing size)
  • gzipped bundle size (download size)

All of these sizes are important criteria when choosing a library, and they will be stored in the .size-snapshot.json file.

There is also a nice feature for the es output format which provides sizes of treeshaked bundles with both rollup and webpack, so if your library has more than one independent parts, you can track that users will not consume dead code. Such bundles entry point looks like this

// nothing is imported here so nothing should go in user bundle
import {} from "library";

Why bundle with rollup

  • internals are hidden so you shouldn't worry that user reuses your frequently updated modules
  • faster user bundling if library has a lot of modules
  • predictable and more efficient scope hoisting and as a result more predictable size
  • easier to work without sourcemaps with vendors since development bundlers add a lot of unreadable stuff in module definition

Usage

import { sizeSnapshot } from "rollup-plugin-size-snapshot";

export default {
  input: "src/index.js",
  output: {
    file: "dist/index.js",
    format: "es",
  },
  plugins: [sizeSnapshot()],
};

If you use uglify or terser plugins, then make sure they are placed after this one.

import { uglify } from "rollup-plugin-uglify";
// or import { terser } from "rollup-plugin-terser";
import { sizeSnapshot } from "rollup-plugin-size-snapshot";

export default {
  // ...
  plugins: [sizeSnapshot(), uglify({ toplevel: true })],
};

Options

snapshotPath

type: string
default: '.size-snapshot.json'

matchSnapshot

This option allows you to verify that contributors don't forget to build or commit the .size-snapshot.json file. If this is true, the plugin will validate the snapshot against an existing one. Typically, one would define this option's value as true during continuous integration; using it locally is unintended.

type: boolean
default: false

threshold

Possible difference between sizes in actual snapshot and generated one.

Note: Make sense only when matchSnapshot is true.

type: number
default: 0

printInfo

Allows you to disable log to terminal.

type: boolean
default: true

License

MIT ยฉ Bogdan Chadkin

rollup-plugin-size-snapshot's People

Contributors

dependabot[bot] avatar eps1lon avatar kylemh avatar michaeldeboey avatar mohsinulhaq avatar transitive-bullshit avatar trysound 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

rollup-plugin-size-snapshot's Issues

Provide more detailed output in terminal

Sizes are good with key: value format, but treeshaking requires some description. It may look like this

Every process.env.NODE_ENV in the bundle is replaced with "production",
the result is treeshaked with rollup and then uglified with `toplevel: true`
option. The final size is 16 566 B

Unpredictable key sort order

I imagine this is because serializing an object is not guaranteed to always sort the keys in the same order, but when having the snapshot checked into a repo to compare with then it's a necessity. The final step in our builds is to see if any git tracked files have changed (we're using that instead of the flag in rollup-plugin-size-snapshot because the flag disables the writing of a new file).

Example:
image

Fill release notes

This package is not stable and there is no release notes for version. So we cannot upgrade the package version starting from 0.11.

Moreover there is breaking change. It just doesn't work :)
mui/material-ui-pickers#1828

webpack dependency causing problems in cra

Project folder structure:

/root
  + project (some npm lib, using rollup-plugin-size-snapshot)
      + examples (created via create-react-app)

when i try to run examples it says this:

yarn run v1.17.3
$ react-app-rewired start

There might be a problem with the project dependency tree.
It is likely not a bug in Create React App, but something you need to fix locally.

The react-scripts package provided by Create React App requires a dependency:

  "webpack": "4.41.2"

Don't try to install it manually: your package manager does it automatically.
However, a different version of webpack was detected higher up in the tree:

  /Users/xyz/dev/react-three-fiber/node_modules/webpack (version: 4.41.5) 

Manually installing incompatible versions is known to cause hard-to-debug issues.

If you would prefer to ignore this check, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That will permanently disable this message but you might encounter other issues.

To fix the dependency tree, try following the steps below in the exact order:

  1. Delete package-lock.json (not package.json!) and/or yarn.lock in your project folder.
  2. Delete node_modules in your project folder.
  3. Remove "webpack" from dependencies and/or devDependencies in the package.json file in your project folder.
  4. Run npm install or yarn, depending on the package manager you use.

In most cases, this should be enough to fix the problem.
If this has not helped, there are a few other things you can try:

  5. If you used npm, install yarn (http://yarnpkg.com/) and repeat the above steps with it instead.
     This may help because npm has known issues with package hoisting which may get resolved in future versions.

  6. Check if /Users/xyz/dev/react-three-fiber/node_modules/webpack is outside your project directory.
     For example, you might have accidentally installed something in your home folder.

  7. Try running npm ls webpack in your project folder.
     This will tell you which other package (apart from the expected react-scripts) installed webpack.

If nothing else helps, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That would permanently disable this preflight check in case you want to proceed anyway.

P.S. We know this message is long but please read the steps above :-) We hope you find them helpful!

trying to track it, it points to rollup-plugin-size-snapshots webpack dependency. have you ever gotten something like this before?

Provide ability to update snapshot

Currently, if there's a desired size mis-match, I'm required to:

  • delete the file
  • delete { matchSnapshot: true } from plugin config
  • create build (new snapshot defined)
  • re-add { matchSnapshot: true } to plugin config

This feels like it can be improved.

Provide a better output for mismatched snapshot

Probably something like this

  bundled: 1,372 B
- minified with uglify: 1,088 B
+ minified with uglify: 1,090 B
  minified and gzipped: 551 B
  treeshaked with rollup and uglified: 821 B
  treeshaked with webpack in production mode: 1,532 B

also would be good if rollup could catch errors for each config in multiconfig separately, so we could see mismatched output for all bundles not only for the first one (usually umd).

Add fuzzy option for check

Right now updateSnapshot is used to avoid creating a snapshot and run a test instead.

Proposal:

Rename to testSnapshotSize (or something similar) to indicate that this is a validation step.

Also, can there also be an option to allow for a threshold of difference when testing against the current snapshot? Use case:

  • I want to bump master on a branch
  • I no longer satisfy the snapshot

I think it would be good to have an option to allow for a fuzzy threshold of difference between the current snapshot and the new one. Eg you could pass in that you would allow a 5% difference. This is purely to support merges from master.

Thoughts?

Updates needed for post-2021

updated

I have already got Webpack v5 working in my work area ... and working with Node.js 17, would be happy to work on the other items (except for renaming the default branch) if anyone is interested.

Experimental code splitting support

I'm getting an error like this:

[!] (size-snapshot plugin) Error: output file in rollup options should be specified
Error: output file in rollup options should be specified
    at Object.renderChunk (/me/my-sweet-project/node_modules/rollup-plugin-size-snapshot/dist/index.js:66:15)
    at /me/my-sweet-project/node_modules/rollup/dist/rollup.js:20962:25
    at <anonymous>

The beginning of renderChunk inside sizeSnapshot function for this plugin looks like:

    renderChunk(source, chunk, outputOptions) {
      const format = outputOptions.format;
      const output = outputOptions.file;
      const shouldTreeshake = format === "es" || format === "esm";

      if (typeof output !== "string") {
        throw Error("output file in rollup options should be specified");
      }

I believe it should be checking if top-level experimentalCodeSplitting property of the rollup config is set to true, in which case output.dir exists instead of output.file. So that error checking could possibly be changed to

if (typeof output !== "string" && outputOptions.dir !== "string") {
  throw Error("Either output file or dir in rollup options should be specified");
}

However, I see that output variable is used later on in the code, so I tried changing it to

const snapshotParams = {
  snapshotPath,
  name: output || dir,
  data: sizes,
  threshold
};

just to see what happens, and ended up getting a different error after running npx rollup -c:

[!] (size-snapshot plugin) Error: Could not resolve './chunk-1d12f2bd.js' from ../../../../__size_snapshot_bundle__.js
Error: Could not resolve './chunk-1d12f2bd.js' from ../../../../__size_snapshot_bundle__.js
    at error (/me/my-sweet-project/node_modules/rollup/dist/rollup.js:3460:30)
    at /me/my-sweet-project/node_modules/rollup/dist/rollup.js:21854:25
    at <anonymous>

@TrySound not sure if this issue is related to one you posted on July 26, Test treeshaking with code splitting. Linking that one just in case

Update terser dependency

We are using this plugin plus the rollup-terser-plugin in a couple projects, and in a newer one we started targeting a newer version of ECMA in the output, which lead to some more modern JS features remaining in the js during transpile (for example optional chaining). This choked up rollup-plugin-terser, but updating it fixed it. However, when I use rollup-plugin-size-snapshot, it dies on line 80 because of line 68:

      const minified = (0, _terser.minify)(source).code;

returns undefined due to modern ECMA symbols breaking the version of the terser included as a dependency:
image

If it doesn't break anything, it'd be nice to see the terser as a peer dependency or just updated to support modern js features.

13 reasons why... to bundle

  • internals are hidden so you shouldn't worry that user reuses your frequently updated modules
  • faster user bundling if library has a lot of modules
  • predictable and more efficient scope hoisting with rollup and as a result more predictable size
  • easier to work without sourcemaps with vendors since development bundlers add a lot of unreadable stuff in module definition

Add support Node v18

Hello!
Thank you for maintaining this great plugin ๐Ÿ™‚

rollup-plugin-size-snapshot does not seem to support Node v18 at the moment.
This error gets thrown when I try to make build:
image

According to stack overflow this could also be mitigated by passing:

NODE_OPTIONS=--openssl-legacy-provider

Usage with rollup 1.0 errors out

[!] (size-snapshot plugin) TypeError: Cannot read property 'length' of undefined TypeError: Cannot read property 'length' of undefined at then.then.then.result (rollup-plugin-size-snapshot/dist/treeshakeWithRollup.js:75:25)

Cannot resolve webpack/buildin/harmony-module.js

I'm getting these crashes in cssinjs/jss#936 (comment):

Error: ModuleNotFoundError: Module not found: Error: Can't resolve '.~/Projects/jss/node_modules/webpack/buildin/harmony-module.js' in '/'
    at compiler.run (~/Projects/jss/node_modules/rollup-plugin-size-snapshot/dist/treeshakeWithWebpack.js:58:16)
    at finalCallback (~/Projects/jss/node_modules/webpack/lib/Compiler.js:210:39)
    at hooks.done.callAsync.err (~/Projects/jss/node_modules/webpack/lib/Compiler.js:226:13)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (~/Projects/jss/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (~/Projects/jss/node_modules/tapable/lib/Hook.js:154:20)
    at onCompiled (~/Projects/jss/node_modules/webpack/lib/Compiler.js:224:21)
    at hooks.afterCompile.callAsync.err (~/Projects/jss/node_modules/webpack/lib/Compiler.js:552:14)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (~/Projects/jss/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (~/Projects/jss/node_modules/tapable/lib/Hook.js:154:20)
    at compilation.seal.err (~/Projects/jss/node_modules/webpack/lib/Compiler.js:549:30)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (~/Projects/jss/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (~/Projects/jss/node_modules/tapable/lib/Hook.js:154:20)
    at hooks.optimizeAssets.callAsync.err (~/Projects/jss/node_modules/webpack/lib/Compilation.js:1323:35)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (~/Projects/jss/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (~/Projects/jss/node_modules/tapable/lib/Hook.js:154:20)
    at hooks.optimizeChunkAssets.callAsync.err (~/Projects/jss/node_modules/webpack/lib/Compilation.js:1314:32)
    at _err0 (eval at create (~/Projects/jss/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:11:1)
    at taskRunner.run (~/Projects/jss/node_modules/terser-webpack-plugin/dist/index.js:315:9)
    at step (~/Projects/jss/node_modules/terser-webpack-plugin/dist/TaskRunner.js:76:9)
    at done (~/Projects/jss/node_modules/terser-webpack-plugin/dist/TaskRunner.js:84:30)
    at tryCatcher (~/Projects/jss/node_modules/cacache/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (~/Projects/jss/node_modules/cacache/node_modules/bluebird/js/release/promise.js:512:31)

I've found a similar error in yahoo/fluxible#306, which was related to the version of webpack being used. I tried upgrading to the latest Webpack (4.27.1) and ensuring that this plugin was using the hoisted version, but those didn't resolve the issue.

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.