From 5ce8b93340c11cac36ff94157a1c9d16717cf68c Mon Sep 17 00:00:00 2001 From: Siddharth Kshetrapal Date: Tue, 9 Jul 2019 15:47:08 +0530 Subject: [PATCH] Make brotli optional (#320) * add a smart layer over brotli * add plugin * remove brotli size * undo unintentional change * unused dep * add 3 node versions to test * call out explicit versions in travis * add brotli plugin as a dev dependency * show raw error as well * fix polyfill require --- .travis.yml | 2 + package.json | 2 +- packages/bundlesize-plugin-brotli/index.js | 3 + .../bundlesize-plugin-brotli/package.json | 12 ++++ packages/bundlesize-plugin-brotli/readme.md | 56 +++++++++++++++++++ src/brotli.js | 48 ++++++++++++++++ src/compressed-size.js | 2 +- 7 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 packages/bundlesize-plugin-brotli/index.js create mode 100644 packages/bundlesize-plugin-brotli/package.json create mode 100644 packages/bundlesize-plugin-brotli/readme.md create mode 100644 src/brotli.js diff --git a/.travis.yml b/.travis.yml index 95cf3570..a18567b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: node_js node_js: + - 12 # Latest + - 10 # LTS - 8 cache: directories: diff --git a/package.json b/package.json index ec5cfb56..3125d60f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "license": "MIT", "dependencies": { "axios": "^0.19.0", - "brotli-size": "0.1.0", "bytes": "^3.1.0", "ci-env": "^1.4.0", "commander": "^2.20.0", @@ -65,6 +64,7 @@ "babel-preset-es2015": "^7.0.0-beta.3", "babel-preset-stage-3": "^7.0.0-beta.3", "babel-traverse": "^7.0.0-beta.3", + "bundlesize-plugin-brotli": "^1.0.0", "execa": "^2.0.1", "husky": "^0.14.3", "lint-staged": "^7.1.1", diff --git a/packages/bundlesize-plugin-brotli/index.js b/packages/bundlesize-plugin-brotli/index.js new file mode 100644 index 00000000..aecca97a --- /dev/null +++ b/packages/bundlesize-plugin-brotli/index.js @@ -0,0 +1,3 @@ +const brotliSize = require('brotli-size') + +module.exports = { sync: brotliSize.sync } diff --git a/packages/bundlesize-plugin-brotli/package.json b/packages/bundlesize-plugin-brotli/package.json new file mode 100644 index 00000000..82edf9d3 --- /dev/null +++ b/packages/bundlesize-plugin-brotli/package.json @@ -0,0 +1,12 @@ +{ + "name": "bundlesize-plugin-brotli", + "version": "1.0.0", + "description": "Plugin to use brotli compression with bundlesize", + "main": "index.js", + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "brotli-size": "0.1.0" + } +} diff --git a/packages/bundlesize-plugin-brotli/readme.md b/packages/bundlesize-plugin-brotli/readme.md new file mode 100644 index 00000000..f5ab4c40 --- /dev/null +++ b/packages/bundlesize-plugin-brotli/readme.md @@ -0,0 +1,56 @@ +

+ +

+ Plugin to use brotli compression with bundlesize on Node < 10.6.0 +
+

+ +  + +#### Note: + +If you are using Node version >= 10.16.0, you do not need this plugin. + +  + +#### Install + +```sh +npm install bundlesize-plugin-brotli --save-dev + +# or + +yarn add bundlesize-plugin-brotli --dev +``` + +  + +#### Setting up bundlesize + +  + +See bundlesize usage here: https://github.com/siddharthkp/bundlesize + +  + +#### Using brotli compression + +  + +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" + } + ] +} +``` + +  diff --git a/src/brotli.js b/src/brotli.js new file mode 100644 index 00000000..b1018917 --- /dev/null +++ b/src/brotli.js @@ -0,0 +1,48 @@ +const { error } = require('prettycli') +const zlib = require('zlib') + +const config = require('./config') + +function getBrotliSync() { + // Does this project want brotli compression? + const needsBrotli = config.find(row => row.compression === 'brotli') + + // If it doesn't, save us the trouble. + if (!needsBrotli) return null + + // Check if the installed version of node supports brotli + const hasBrotli = zlib.brotliCompressSync + if (hasBrotli) return nativeBrotliSync + + // Looks like this version of node does not have brotli + // We recommend using bundlesize-plugin-brotli which acts + // like a polyfill + + try { + const polyfill = require('bundlesize-plugin-brotli') + // if the user has installed the plugin, we can safely return it + return polyfill.sync + } catch (err) { + // if they haven't, show them an error and exit with error code 1 + if (err && err.code === 'MODULE_NOT_FOUND') { + const message = `Missing dependency: bundlesize-plugin-brotli + + To use brotli with Node versions lower than v10.16.0, + please install bundlesize-plugin-brotli as a dev dependency. + + You can read about the compression options here: + https://github.com/siddharthkp/bundlesize#customisation` + + error(message, { silent: true }) + } else { + // if it's a different error, show the raw error + error(err, { silent: true }) + } + } +} + +function nativeBrotliSync(input) { + return zlib.brotliCompressSync(input).length +} + +module.exports = { sync: getBrotliSync() } diff --git a/src/compressed-size.js b/src/compressed-size.js index e7846924..c51f403d 100644 --- a/src/compressed-size.js +++ b/src/compressed-size.js @@ -1,5 +1,5 @@ const gzip = require('gzip-size') -const brotli = require('brotli-size') +const brotli = require('./brotli') const getCompressedSize = (data, compression = 'gzip') => { let size