ff-stream-web

git clone git://archive.git.mtrnord.blog/MTRNord/ff-stream-web.git
Log | Files | Refs | README | LICENSE

commit b3670bedb06d9318b350d70cbe4d50ab618a8460
parent 0de4958c4e4f10f0aa998ec9e16eb0a9699560d1
Author: Vladimir Kutepov <frenzzy.man@gmail.com>
Date:   Sat, 12 Mar 2016 22:09:09 +0300

Improve long term caching by adding [chunkhash]

- Use `[chunkhash]` instead of `[hash]` in the names of bundles, it allows to save the bundle name if the content hasn't changed
- Deduplicate assets, use the same `output.path` for files, fix #362
- Use `path.resolve` everywhere in webpack config for consistency
- Use `OccurrenceOrderPlugin` in debug mode too for [hot reload needs](https://github.com/glenjamin/webpack-hot-middleware#installation--usage)
- Move generated (compiled) files from `public` to `public/assets` to not be mixed with other files like static html

Diffstat:
Mtools/start.js | 8+++++---
Mtools/webpack.config.js | 35+++++++++++++++++++++--------------
2 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/tools/start.js b/tools/start.js @@ -30,21 +30,22 @@ async function start() { // Patch the client-side bundle configurations // to enable Hot Module Replacement (HMR) and React Transform webpackConfig.filter(x => x.target !== 'node').forEach(config => { + /* eslint-disable no-param-reassign */ if (Array.isArray(config.entry)) { config.entry.unshift('webpack-hot-middleware/client'); } else { - /* eslint-disable no-param-reassign */ config.entry = ['webpack-hot-middleware/client', config.entry]; - /* eslint-enable no-param-reassign */ } + config.output.filename = config.output.filename.replace('[chunkhash]', '[hash]'); + config.output.chunkFilename = config.output.chunkFilename.replace('[chunkhash]', '[hash]'); config.plugins.push(new webpack.HotModuleReplacementPlugin()); config.plugins.push(new webpack.NoErrorsPlugin()); config .module .loaders .filter(x => x.loader === 'babel-loader') - .forEach(x => (x.query = { // eslint-disable-line no-param-reassign + .forEach(x => (x.query = { ...x.query, // Wraps all React components into arbitrary transforms @@ -66,6 +67,7 @@ async function start() { ], ], })); + /* eslint-enable no-param-reassign */ }); const bundler = webpack(webpackConfig); diff --git a/tools/webpack.config.js b/tools/webpack.config.js @@ -35,10 +35,11 @@ const GLOBALS = { // ----------------------------------------------------------------------------- const config = { - context: path.join(__dirname, '../src'), + context: path.resolve(__dirname, '../src'), output: { - publicPath: '/', + path: path.resolve(__dirname, '../build/public/assets'), + publicPath: '/assets/', sourcePrefix: ' ', }, @@ -94,11 +95,18 @@ const config = { }, { test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/, - loader: 'url-loader?limit=10000', + loader: 'url-loader', + query: { + name: DEBUG ? '[path][name].[ext]?[hash]' : '[hash].[ext]', + limit: 10000, + }, }, { test: /\.(eot|ttf|wav|mp3)$/, loader: 'file-loader', + query: { + name: DEBUG ? '[path][name].[ext]?[hash]' : '[hash].[ext]', + }, }, { test: /\.jade$/, @@ -108,7 +116,7 @@ const config = { }, resolve: { - root: path.join(__dirname, '../src'), + root: path.resolve(__dirname, '../src'), modulesDirectories: ['node_modules'], extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx', '.json'], }, @@ -145,9 +153,8 @@ const clientConfig = extend(true, {}, config, { entry: './client.js', output: { - path: path.join(__dirname, '../build/public'), - filename: DEBUG ? '[name].js?[hash]' : '[name].[hash].js', - chunkFilename: DEBUG ? '[name].[id].js?[hash]' : '[name].[id].[hash].js', + filename: DEBUG ? '[name].js?[chunkhash]' : '[name].[chunkhash].js', + chunkFilename: DEBUG ? '[name].[id].js?[chunkhash]' : '[name].[id].[chunkhash].js', }, target: 'web', @@ -161,21 +168,22 @@ const clientConfig = extend(true, {}, config, { // Emit a file with assets paths // https://github.com/sporto/assets-webpack-plugin#options new AssetsPlugin({ - path: path.join(__dirname, '../build'), + path: path.resolve(__dirname, '../build'), filename: 'assets.js', processOutput: x => `module.exports = ${JSON.stringify(x)};`, }), + // Assign the module and chunk ids by occurrence count + // Consistent ordering of modules required if using any hashing ([hash] or [chunkhash]) + // https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin + new webpack.optimize.OccurenceOrderPlugin(true), + ...(DEBUG ? [] : [ // Search for equal or similar files and deduplicate them in the output // https://webpack.github.io/docs/list-of-plugins.html#dedupeplugin new webpack.optimize.DedupePlugin(), - // Assign the module and chunk ids by occurrence count - // https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin - new webpack.optimize.OccurenceOrderPlugin(true), - // Minimize all JavaScript output of chunks // https://github.com/mishoo/UglifyJS2#compressor-options new webpack.optimize.UglifyJsPlugin({ @@ -204,8 +212,7 @@ const serverConfig = extend(true, {}, config, { entry: './server.js', output: { - path: path.join(__dirname, '../build'), - filename: 'server.js', + filename: '../../server.js', libraryTarget: 'commonjs2', },