├── .gitignore
├── .travis.yml
├── appveyor.yml
├── LICENSE.md
├── CHANGELOG.md
├── package.json
├── README.md
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /.nyc_output
3 | /test/cache
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - "9"
5 | - "8"
6 | - "6"
7 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | environment:
2 | matrix:
3 | - nodejs_version: "9"
4 | - nodejs_version: "8"
5 | - nodejs_version: "6"
6 |
7 | platform:
8 | - x64
9 |
10 | install:
11 | - ps: Install-Product node $env:nodejs_version $env:platform
12 | - npm config set spin false
13 | - npm install
14 |
15 | test_script:
16 | - npm test
17 |
18 | matrix:
19 | fast_finish: true
20 |
21 | build: off
22 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) npm, Inc.
4 |
5 | Permission to use, copy, modify, and/or distribute this software for
6 | any purpose with or without fee is hereby granted, provided that the
7 | above copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE COPYRIGHT HOLDER DISCLAIMS
10 | ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 | COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
13 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
14 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
16 | USE OR PERFORMANCE OF THIS SOFTWARE.
17 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [1.1.1](https://github.com/npm/do-you-even-lift/compare/v1.1.0...v1.1.1) (2020-03-24)
7 |
8 |
9 | ### Bug Fixes
10 |
11 | * remove old weall* stuff ([4279bff](https://github.com/npm/do-you-even-lift/commit/4279bff))
12 |
13 |
14 |
15 |
16 | # [1.1.0](https://github.com/npm/do-you-even-lift/compare/v1.0.0...v1.1.0) (2018-04-30)
17 |
18 |
19 | ### Features
20 |
21 | * **bundle:** report which bundler succeeded ([5d5f94a](https://github.com/npm/do-you-even-lift/commit/5d5f94a))
22 | * **error:** better reporting of fallthrough errors ([1df5dce](https://github.com/npm/do-you-even-lift/commit/1df5dce))
23 |
24 |
25 |
26 |
27 | # 1.0.0 (2018-04-26)
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "do-you-even-lift",
3 | "version": "1.1.1",
4 | "description": "Figure out an estimate of how heavy a particular npm package might be in various compression configurations",
5 | "main": "index.js",
6 | "files": [
7 | "*.js",
8 | "lib"
9 | ],
10 | "scripts": {
11 | "prerelease": "npm t",
12 | "postrelease": "npm publish && git push --follow-tags",
13 | "pretest": "standard",
14 | "release": "standard-version -s",
15 | "test": "tap -J --coverage test/*.js"
16 | },
17 | "repository": "https://github.com/npm/do-you-even-lift",
18 | "keywords": [
19 | "npm",
20 | "bundle",
21 | "web",
22 | "rollup",
23 | "browserify"
24 | ],
25 | "author": "Kat Marchán ",
26 | "license": "ISC",
27 | "dependencies": {
28 | "babel-core": "^6.26.3",
29 | "babel-preset-minify": "^0.4.0",
30 | "browserify": "^16.2.0",
31 | "figgy-pudding": "^3.1.0",
32 | "glob": "^7.1.2",
33 | "pacote": "^8.1.1",
34 | "rollup": "^0.58.2",
35 | "rollup-plugin-commonjs": "^9.1.0",
36 | "unique-filename": "^1.1.0"
37 | },
38 | "devDependencies": {
39 | "standard": "^11.0.1",
40 | "standard-version": "^4.3.0",
41 | "tap": "^11.1.3"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # do-you-even-lift [](https://npm.im/do-you-even-lift) [](https://npm.im/do-you-even-lift) [](https://travis-ci.org/npm/do-you-even-lift) [](https://ci.appveyor.com/project/npm/do-you-even-lift) [](https://coveralls.io/github/npm/do-you-even-lift?branch=latest)
2 |
3 | [`do-you-even-lift`](https://github.com/npm/do-you-even-lift) is a Node.js
4 | library for calculating how big a specific package might be once bundled and
5 | compressed. It's built on top of [`pacote`](https://npm.im/pacote) and so will
6 | accept any valid package specifier for extraction.
7 |
8 | ## Install
9 |
10 | `$ npm install do-you-even-lift`
11 |
12 | ### Example
13 |
14 | ```javascript
15 | const liftMeBro = require('do-you-even-lift')
16 |
17 | liftMeBro('react').then(console.log)
18 | // =>
19 | {
20 | unpackedSize: 119169,
21 | bundleSize: 55615,
22 | minifiedBundleSize: 19747,
23 | gzippedBundleSize: 15783,
24 | gzippedMinifiedBundleSize: 7090,
25 | bundleTime: 1242
26 | }
27 | ```
28 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const util = require('util')
4 |
5 | const babel = require('babel-core')
6 | const browserify = require('browserify')
7 | const cjsResolve = require('rollup-plugin-commonjs')
8 | // const figgyPudding = require('figgy-pudding')
9 | const fs = require('fs')
10 | const glob = util.promisify(require('glob'))
11 | const os = require('os')
12 | const pacote = require('pacote')
13 | const path = require('path')
14 | const rimraf = util.promisify(require('rimraf'))
15 | const rollup = require('rollup')
16 | const uniqueFilename = require('unique-filename')
17 | const zlib = require('zlib')
18 |
19 | const gzipAsync = util.promisify(zlib.gzip)
20 | const statAsync = util.promisify(fs.stat)
21 |
22 | module.exports = pkgStats
23 |
24 | // const LiftConfig = figgyPudding({
25 | // tmpdir: {}
26 | // })
27 |
28 | async function pkgStats (pkg, opts) {
29 | // opts = LiftConfig(opts)
30 | opts = opts || {}
31 | const stats = {}
32 | const pkgDir = uniqueFilename(opts.tmpdir || os.tmpdir())
33 | const startTime = Date.now()
34 | try {
35 | await pacote.extract(pkg, pkgDir, opts)
36 | stats.unpackedSize = await getSize('**/*', pkgDir)
37 | const bundle = await bundlePackage(pkgDir)
38 | stats.bundler = bundle.bundler
39 | stats.bundleSize = Buffer.from(bundle.code, 'utf8').length
40 | const minifyResult = babel.transform(bundle.code, {
41 | presets: ['minify']
42 | })
43 | const minified = Buffer.from(minifyResult.code, 'utf8')
44 | stats.minifiedBundleSize = minified.length
45 | stats.gzippedBundleSize = (await gzipAsync(bundle.code)).length
46 | stats.gzippedMinifiedBundleSize = (await gzipAsync(minified)).length
47 | } finally {
48 | await rimraf(pkgDir)
49 | }
50 | stats.bundleTime = Date.now() - startTime
51 | return stats
52 | }
53 |
54 | async function getSize (str, cwd) {
55 | const files = await glob(str, {cwd})
56 | const stats = await Promise.all(files.map(f => statAsync(path.join(cwd, f))))
57 | return stats.reduce((acc, stat) => {
58 | if (stat.isFile()) {
59 | return acc + stat.size
60 | } else {
61 | return acc
62 | }
63 | }, 0)
64 | }
65 |
66 | async function bundlePackage (pkgDir) {
67 | const pkgJson = require(path.join(pkgDir, 'package.json'))
68 | const entry = path.join(pkgDir, pkgJson.main || pkgJson.module || 'index.js')
69 | try {
70 | return Object.assign(await (await rollup.rollup({
71 | input: entry,
72 | onwarn: () => {},
73 | plugins: [
74 | cjsResolve({
75 | ignoreGlobal: false,
76 | sourceMap: true,
77 | exclude: ['node_modules/**'] // no deps -- just this one
78 | })
79 | ]
80 | })).generate({name: pkgJson.name, format: 'umd'}), {
81 | bundler: 'rollup'
82 | })
83 | } catch (rollupError) {
84 | const b = browserify(entry, {
85 | bare: true,
86 | bundleExternal: false,
87 | ignoreMissing: true
88 | })
89 | try {
90 | return await new Promise((resolve, reject) => {
91 | b.bundle((err, buf) => {
92 | if (err) {
93 | reject(err)
94 | } else {
95 | resolve({code: buf, map: '', bundler: 'browserify'})
96 | }
97 | })
98 | })
99 | } catch (browserifyError) {
100 | throw Object.assign(
101 | new Error(
102 | `Bundle could not be built. All bundlers failed.\nRollup Error: ${rollupError.message}\nBrowserify Error: ${browserifyError.message}`
103 | ), {
104 | browserifyError,
105 | rollupError
106 | }
107 | )
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------