UNPKG

formidable-playbook

Version:
201 lines (144 loc) 6.66 kB
### Start with good base plugins Webpack has a rich plugin ecosystem, including both [core](https://webpack.github.io/docs/list-of-plugins.html) and [open source](http://nipstr.com/#webpack plugin) [modules](https://www.npmjs.com/browse/keyword/webpack-plugin) modules. Webpack also has a straight forward interface to [write your own plugins](https://webpack.github.io/docs/plugins.html). <!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> - [`UglifyJsPlugin`](#uglifyjsplugin) - [`DedupePlugin`](#dedupeplugin) - [`OccurrenceOrderPlugin`](#occurrenceorderplugin) - [`DefinePlugin`](#defineplugin) - [`lodash-webpack-plugin`](#lodash-webpack-plugin) <!-- END doctoc generated TOC please keep comment here to allow auto update --> ##### [`UglifyJsPlugin`](https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin) * Recommended?: **Yes** The `UglifyJsPlugin` minimizes code using [Uglifyjs](https://github.com/mishoo/UglifyJS2) and with most options proxied through to the plugin. Typical configuration: ```js new webpack.optimize.UglifyJsPlugin() ``` ##### [`DedupePlugin`](https://webpack.github.io/docs/list-of-plugins.html#dedupeplugin) * Recommended?: **Yes for `webpack@1`** Collapse identical code chunks to a single reference. The plugin looks for identical occurrences of the same code and replaces real code chunks in the bundle with integer references (think pointers in C/C++) to find an earlier instance of the same code. Typical configuration: ```js new webpack.optimize.DedupePlugin() ``` **Note - npm Deduplication**: This "deduplication" is separate from the deduplication that `npm` performs while flattening the dependency tree in `node_modules`. It is just a scan by webpack to coalesce identical code chunks to a single reference. <!-- **TODO: inspectpack duplicates reference + note - https://github.com/FormidableLabs/formidable-playbook/issues/2* --> **Webpack 2+ Note**: This plugin has been removed as of `webpack@2` with a note that it "isn't needed anymore" because of npm deduplication. Unfortunately, npm deduplication can often fail where the plugin would yield a smaller bundle. Hopefully, this plugin will be resurrected by core or the community as a new OSS project. ##### [`OccurrenceOrderPlugin`](https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin) * Recommended?: **Maybe for `webpack@1`** Reorder module / chunk ids by order of most-to-least occurring. This reduces raw code size since smaller integer indexes are `require`-ed more. Also makes the order of modules deterministic. Typical configuration: ```js new webpack.optimize.OccurrenceOrderPlugin() ``` **Assessment**: The size gains are often not significant, and can make the ultimate minified + gzipped bundle size actually _larger_. And this calculus can change over time, so generally speaking size should not be a motivating factor for enabling this plugin. However, if you need a deterministic ordering of chunks and modules, this plugin is appropriate. **Webpack 2+ Note**: Enabled by default now. ##### [`DefinePlugin`](https://webpack.github.io/docs/list-of-plugins.html#defineplugin) * Recommended?: **Maybe** Add raw replacement strings for free variables in code. This literally rewrites your source code with replacements. With a bit of strategy and a project convention you can opportunistically have code paths removed / variables replaced for a bespoke optimized production build. Additionally, many frameworks / tools such as React, expect a definition of `"process.env.NODE_ENV": JSON.stringify("production")` for the most optimized build of included code. Example configuration: ```js new webpack.optimize.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production"), // or "\"production\"" "DEBUG": false // or "false" }) ``` **Note**: to expand a variable to a quoted string, you must use `JSON.stringify`. If we had this source: ```js if (process.env.NODE_ENV === "production") { console.log("I'm in prod!"); } if (DEBUG) { console.log("Explicit debug switch"); } ``` with the above configuration, the output would be: ```js if ("production" === "production") { console.log("I'm in prod!"); } if (false) { console.log("Explicit debug switch"); } ``` which with minification would become: ```js console.log("I'm in prod!"); ``` ##### [`lodash-webpack-plugin`](https://github.com/lodash/lodash-webpack-plugin) * Recommended?: **Maybe** If your project uses [lodash](https://lodash.com/) and can handle some limiting constraints and complexities, this plugin provides some useful optimizations for reducing code size. Typically you'll want to already use the [`babel-plugin-lodash`](https://github.com/lodash/babel-plugin-lodash) which optimizes some things in a webpack / babel build. This plugin then goes further by removing lots of internal code, grouped in logical ["feature sets"](https://github.com/lodash/lodash-webpack-plugin#feature-sets) **Big Warning**: The plugin's only real value is removing internal stuff that your code **may still depend on**. And it's not always obvious what is getting removed. For example, looking to a simple example provided at: https://github.com/exogen/test-lodash-webpack-plugin we have this starting code: ```js import get from "lodash/get"; import assert from "assert"; const x = { a: { b: { c: 1 } } }; assert.strictEqual(get(x, "a.b.c"), 1); ``` Using the plugin with no configuration: ```js new LodashModuleReplacementPlugin() ``` will fail the assertion because the result of `get(x, "a.b.c")` is `undefined`. The reason is that all deep path traversal code is removed under the hood by default. Thus to support deep path traversal for the `get()` call, we would need to configure the plugin like: ```js new LodashModuleReplacementPlugin({ paths: true }) ``` Thus, this plugin is not really a "fire and forget" thing, but rather a power tool with very few safeties. You must be familiar with all the of the feature sets removed, probably need to coordinate re-enabling key ones for your specific project, and ensure that all lodash usage is tested / complies with the internal rewriting of the plugin. For example, after enabling it without configuration in the Victory project, we later found that we needed several configurations enabled. See: https://github.com/FormidableLabs/builder-victory-component/pull/64 In short, it's easier to just not add the plugin. But if you need that extra bit of super-optimized lodash tuning, you can enable the plugin and accept the complexity cost of it.