Widget webpack optimization
by Troy Rhinehart
What is webpack?
"Webpack is a bundler for modules. The main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset
why we're using it
- NPM Modules
- Babel/ES6
- LESS/PostCSS
- Assets
- Uglify/Compress
- Plugins/Loaders
- Build process
- Chunking/Hashing
- Hot reload
size does matter
guac-widget-header
25kB
guac-widget-footer
542kB
WTH?
guac-widget-contact
912kB
guac-widget-about
2.12MB
what I found
- Dependency issues
- Build issues
- Webpack config issues
- Module Resolving Issues
peer dependencies
"peerDependencies": {
"@wsb/guac-widget-core": "^0.10.12",
"fluxible-addons-connect-props": "^0.1.1",
"keymirror": "^0.1.1",
"react": "^0.14.2"
}
dev dependencies
everything
actual dependencies
nothing
build issues
c:\git\projects\vnext\guac-widget-about>npm run pack
> @wsb/guac-widget-about@2.0.17 pack c:\git\projects\vnext\guac-widget-about
> webpack --verbose
c:\git\projects\vnext\guac-widget-about>npm run pack
> @wsb/guac-widget-about@2.0.18 pack c:\git\projects\vnext\guac-widget-about
> webpack -p
webpack cli
webpack 1.12.14
Usage: https://webpack.github.io/docs/cli.html
Options:
--help, -h, -?
--config
--context
--entry
--module-bind
--module-bind-post
--module-bind-pre
--output-path
--output-file
--output-chunk-file
--output-named-chunk-file
--output-source-map-file
--output-public-path
--output-jsonp-function
--output-pathinfo
--output-library
--output-library-target
--records-input-path
--records-output-path
--records-path
--define
--target
--cache
--watch, -w
--watch which closes when stdin ends
--watch-aggregate-timeout
--watch-poll
--hot
--debug
--devtool
--progress
--resolve-alias
--resolve-loader-alias
--optimize-max-chunks
--optimize-min-chunk-size
--optimize-minimize
--optimize-occurence-order
--optimize-dedupe
--prefetch
--provide
--labeled-modules
--plugin
--bail
--profile
-d (--debug --devtool sourcemap)
--output-pathinfo
-p (--optimize-minimize)
--json, -j
--colors, -c
--sort-modules-by
--sort-chunks-by
--sort-assets-by
--hide-modules
--display-exclude
--display-modules
--display-chunks
--display-error-details
--display-origins
--display-cached
--display-cached-assets
--display-reasons, --verbose, -v
webpack config
var webpack = require('webpack');
module.exports = {
entry: {
manifest: './src/manifest',
about1: './src/about1/',
about2: './src/about2/',
about3: './src/about3/'
},
externals: {
'react': 'commonjs react',
'@wsb/guac-widget-core': 'commonjs @wsb/guac-widget-core',
'@wsb/guac-dials': 'commonjs @wsb/guac-dials',
'fluxible-addons-connect-props': 'commonjs fluxible-addons-connect-props',
'lodash': 'commonjs lodash',
'keymirror': 'commonjs keymirror'
},
output: {
libraryTarget: 'umd',
path: './lib/',
filename: '[name].js'
},
module: {
loaders: [{ test: /\.jsx?$/, loader: 'babel', exclude: /node_modules/ }]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
}
})
]
};
externals
externals: {
'react': 'commonjs react',
'@wsb/guac-widget-core': 'commonjs @wsb/guac-widget-core',
'@wsb/guac-dials': 'commonjs @wsb/guac-dials',
'fluxible-addons-connect-props': 'commonjs fluxible-addons-connect-props',
'lodash': 'commonjs lodash',
'keymirror': 'commonjs keymirror'
}
plugins
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
}
})
]
dedupe plugin
"Search for equal or similar files and deduplicate them in the output. This comes with some overhead for the entry chunk, but can reduce file size effectively.This doesn’t change the module semantics at all. Don’t expect to solve problems with multiple module instance. They won’t be one instance after deduplication.
Note: Don’t use it in watch mode. Only for production builds."
Occurrence Order Plugin
"Assign the module and chunk ids by occurrence count. Ids that are used often get lower (shorter) ids. This make ids predictable, reduces to total file size and is recommended. preferEntry (boolean) give entry chunks higher priority. This make entry chunks smaller but increases the overall size. (recommended)"
module resolving issues
import connectPropsToStores from 'fluxible-addons-connect-props/connectPropsToStores';
import NestedProp from '@wsb/guac-widget-core/lib/utils/NestedPropConnector';
import Website from '@wsb/guac-widget-core/lib/utils/WebsitePropConnector';
import Config from '@wsb/guac-widget-core/lib/utils/ConfigPropConnector';
import { NEUTRAL } from '@wsb/guac-widget-core/lib/constants/colorPackCategories';
import { utils, constants } from '@wsb/guac-widget-core';
import { connectPropsToStores } from 'fluxible-addons-connect-props';
const { NestedPropConnector: NestedProp, WebsitePropConnector: Website, ConfigPropConnector: Config } = utils;
const { colorPackCategories: { NEUTRAL } } = constants;
results
guac-widget-header
25kb
5.54kb
-77.84%
guac-widget-footer
542kb
3.86kb
-99.29%
guac-widget-contact
912kb
193kb
-78.84%
guac-widget-about
2.12MB
20kb
-99.06%
future optimizations
- Move publish dependencies to widgets
- Put all entries into a single entry
- Split out bootstrapped raw dependency
- Push widgets to Ceph/CDN
Questions?
thank you!
Widget Webpack Optimizations
By gingur
Widget Webpack Optimizations
- 74

