diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..b2095be8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "semi": false, + "singleQuote": true +} diff --git a/README.md b/README.md index 6abb5174..fae10747 100644 --- a/README.md +++ b/README.md @@ -12,16 +12,21 @@ [![NPM Downloads](https://img.shields.io/npm/dm/bundlesize.svg?style=flat)](https://www.npmjs.com/package/bundlesize)   - -#### minimal setup +#### Setup ```sh npm install bundlesize --save-dev + +# or + +yarn add bundlesize --dev ```   -#### usage +#### Usage + +  Add it to your scripts in `package.json` @@ -31,79 +36,169 @@ Add it to your scripts in `package.json` } ``` -  - -Or you can use `npx` with [NPM 5.2+](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b). +Or you can use it with `npx` from [NPM 5.2+](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b). ```sh npx bundlesize ``` -#### configuration -   -#### 1) Add the path and maxSize in your `package.json`. -By default the gzipped size is tested. You can use the `compression` option to change this. (`gzip`, `brotli`, or `none`). +#### Configuration -```json -{ - "name": "your cool library", - "version": "1.1.2", - "bundlesize": [ - { - "path": "./dist.js", - "maxSize": "3 kB" - } - ] -} -``` - -`bundlesize` also supports [glob patterns](https://github.com/isaacs/node-glob) +  -Example: +`bundlesize` accepts an array of files to check. ```json -"bundlesize": [ +[ { - "path": "./dist/vendor-*.js", - "maxSize": "3 kB" + "path": "./build/vendor.js", + "maxSize": "30 kB" }, { - "path": "./dist/chunk-*.js", - "maxSize": "3 kB" + "path": "./build/chunk-*.js", + "maxSize": "10 kB" } ] - ``` -This makes it great for using with applications that are bundled with another tool. It will match multiple files if necessary and create a new row for each file. +  + +You can keep this array either in + +1. `package.json` + + ```json + { + "name": "your cool library", + "version": "1.1.2", + "bundlesize": [ + { + "path": "./build/vendor.js", + "maxSize": "3 kB" + } + ] + } + ``` + + or in a separate file + +2. `bundlesize.config.js` + + Format: + + ```json + { + "files": [ + { + "path": "./dist.js", + "maxSize": "3 kB" + } + ] + } + ``` + + You can give a different file by using the `--config` flag: + + ``` + bundlesize --config configs/bundlesize.json + ``` + +  + +#### Customisation + +  + +1. Fuzzy matching + + If the names of your build files are not predictable, you can use the [glob pattern](https://github.com/isaacs/node-glob) to specify files. + + This is common if you append a hash to the name or use a tool like create-react-app/nextjs. + + ```json + { + "files": [ + { + "path": "build/**/main-*.js", + "maxSize": "5 kB" + }, + { + "path": "build/**/*.chunk.js", + "maxSize": "50 kB" + } + ] + } + ``` + + It will match multiple files if necessary and create a new row for each file. + +   + +2. Compression options + + By default, bundlesize `gzips` your build files before comparing. + + If you are using `brotli` instead of gzip, you can specify that with each file: + + ```json + { + "files": [ + { + "path": "./build/vendor.js", + "maxSize": "5 kB", + "compression": "brotli" + } + ] + } + ``` + + If you do not use any compression before sending your files to the client, you can switch compression off: + + ```json + { + "files": [ + { + "path": "./build/vendor.js", + "maxSize": "5 kB", + "compression": "none" + } + ] + } + ``` + +  + +#### Build status for GitHub   -#### 2) build status +If your repository is hosted on GitHub, you can set bundlesize up to create a "check" on every pull request. ![build status](https://cdn.rawgit.com/siddharthkp/bundlesize/master/art/status.png) -Currently works for [Travis CI](https://travis-ci.org), [CircleCI](https://circleci.com/), [Wercker](http://www.wercker.com), and [Drone](http://readme.drone.io/). +Currently works with [Travis CI](https://travis-ci.org), [CircleCI](https://circleci.com/), [Wercker](http://www.wercker.com), and [Drone](http://readme.drone.io/). - [Authorize `bundlesize` for status access](https://github.com/login/oauth/authorize?scope=repo%3Astatus&client_id=6756cb03a8d6528aca5a), copy the token provided. - Add this token as `BUNDLESIZE_GITHUB_TOKEN` as environment parameter in your CIs project settings. Using a different CI? You will need to supply an additional 4 environment variables. -- `CI_REPO_OWNER` given the repo `https://github.com/myusername/myrepo` would be `myusername` + +- `CI_REPO_OWNER` given the repo `https://github.com/myusername/myrepo` would be `myusername` - `CI_REPO_NAME` given the repo `https://github.com/myusername/myrepo` would be `myrepo` - `CI_COMMIT_MESSAGE` the commit message - `CI_COMMIT_SHA` the SHA of the CI commit, in [Jenkins](https://jenkins.io/) you would use `${env.GIT_COMMIT}` (Ask me for help if you're stuck) -   -#### CLI +#### Usage with CLI + +  -example usage: +bundlesize can also be used without creating a configuration file. We do not recommend this approach and it might be deprecated in a future version. ```sh bundlesize -f "dist/*.js" -s 20kB @@ -156,7 +251,7 @@ For more granular configuration, we recommend configuring it in the `package.jso #### TODO -- Work with other CI tools +- Work with other CI tools - [AppVeyor](https://www.appveyor.com/) ([#234](https://github.com/siddharthkp/bundlesize/issues/234)) - Automate setup (setting env_var) diff --git a/bundlesize.config.json b/bundlesize.config.json new file mode 100644 index 00000000..657d88aa --- /dev/null +++ b/bundlesize.config.json @@ -0,0 +1,17 @@ +{ + "files": [ + { + "path": "./index.js", + "maxSize": "600B" + }, + { + "path": "./src/files.js", + "maxSize": "600B" + }, + { + "path": "./src/compressed-size.js", + "maxSize": "420B", + "compression": "none" + } + ] +} diff --git a/examples/bundlesize.config.json b/examples/bundlesize.config.json new file mode 100644 index 00000000..62787d20 --- /dev/null +++ b/examples/bundlesize.config.json @@ -0,0 +1,16 @@ +{ + "files": [ + { + "path": "./build/direct-path.js", + "maxSize": "50Kb" + }, + { + "path": "./dist/generated-file-chunk-*.js", + "maxSize": "50Kb" + }, + { + "path": "./dist/all-files-in-folder/**/*.js", + "maxSize": "50Kb" + } + ] +} diff --git a/examples/package.json b/examples/package.json new file mode 100644 index 00000000..11120ced --- /dev/null +++ b/examples/package.json @@ -0,0 +1,25 @@ +{ + "name": "your-project", + "version": "1.0.0", + "scripts": { + "test": "bundlesize" + }, + "bundlesize": [ + { + "path": "./index.js", + "maxSize": "600B" + }, + { + "path": "./src/files.js", + "maxSize": "600B" + }, + { + "path": "./src/compressed-size.js", + "maxSize": "420B", + "compression": "none" + } + ], + "devDependencies": { + "bundlesize": "^0.18.0" + } +} diff --git a/package.json b/package.json index 521cc8e9..6093ec3f 100644 --- a/package.json +++ b/package.json @@ -39,27 +39,12 @@ "bytes": "^3.1.0", "ci-env": "^1.4.0", "commander": "^2.20.0", + "cosmiconfig": "^5.2.1", "github-build": "^1.2.0", "glob": "^7.1.4", "gzip-size": "^4.0.0", - "prettycli": "^1.4.3", - "read-pkg-up": "^3.0.0" + "prettycli": "^1.4.3" }, - "bundlesize": [ - { - "path": "./index.js", - "maxSize": "600B" - }, - { - "path": "./src/files.js", - "maxSize": "600B" - }, - { - "path": "./src/compressed-size.js", - "maxSize": "420B", - "compression": "none" - } - ], "lint-staged": { "*.js": [ "prettier", diff --git a/src/config.js b/src/config.js index ad6c87b1..c1405a1b 100644 --- a/src/config.js +++ b/src/config.js @@ -1,29 +1,48 @@ -const readPkgUp = require('read-pkg-up') +const cosmiconfig = require('cosmiconfig') +const fs = require('fs') -const pkg = readPkgUp.sync().pkg const program = require('commander') const { error } = require('prettycli') const debug = require('./debug') -/* Config from package.json */ -const packageJSONconfig = pkg.bundlesize +// default places we check +const configPaths = ['package.json', 'bundlesize.config.json'] -/* Config from CLI */ +/* Config + Flags from CLI */ +// TODO: Deprecate the config part program .option('-f, --files [files]', 'files to test against (dist/*.js)') .option('-s, --max-size [maxSize]', 'maximum size threshold (3Kb)') .option('--debug', 'run in debug mode') + .option('--config [config]', 'Get path of configuration file') .option( '-c, --compression [compression]', 'specify which compression algorithm to use' ) .parse(process.argv) -let cliConfig +let configFromCli + +if (program.config) { + if (!fs.existsSync(program.config)) { + // throw error if file doesn't exist + error( + `Custom config file does not exist. Make sure the path is relative to the project root. + + You can read about the configuration options here: + https://github.com/siddharthkp/bundlesize#configuration + `, + { silent: true } + ) + } else { + // add to the list of files to check at the 1st position + configPaths.unshift(program.config) + } +} if (program.files) { - cliConfig = [ + configFromCli = [ { path: program.files, maxSize: program.maxSize, @@ -32,9 +51,21 @@ if (program.files) { ] } +/* Config from file */ + +let configFromFile + +const explorer = cosmiconfig('bundlesize', { searchPlaces: configPaths }) +const result = explorer.searchSync() + +if (result) { + if (result.filepath.includes('package.json')) configFromFile = result.config + else configFromFile = result.config.files +} + /* Send to readme if no configuration is provided */ -if (!packageJSONconfig && !cliConfig) { +if (!configFromFile && !configFromCli) { error( `Config not found. @@ -45,10 +76,10 @@ if (!packageJSONconfig && !cliConfig) { ) } -const config = cliConfig || packageJSONconfig +const config = configFromCli || configFromFile -debug('cli config', cliConfig) -debug('package json config', packageJSONconfig) +debug('cli config', configFromCli) +debug('file config', configFromFile) debug('selected config', config) module.exports = config