commit 274b1178630b15777d02624388712487546d3290
parent e61838ad6ce7b57773623a42494470fd8b2c73c7
Author: Vladimir Kutepov <frenzzy.man@gmail.com>
Date: Thu, 24 Nov 2016 23:24:42 +0400
Improve hot reload speed (#989)
Diffstat:
3 files changed, 55 insertions(+), 38 deletions(-)
diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js
@@ -13,6 +13,7 @@ import s from './Header.css';
import Link from '../Link';
import Navigation from '../Navigation';
import logoUrl from './logo-small.png';
+import logoUrl2x from './logo-small@2x.png';
class Header extends React.Component {
render() {
@@ -21,7 +22,7 @@ class Header extends React.Component {
<div className={s.container}>
<Navigation className={s.nav} />
<Link className={s.brand} to="/">
- <img src={logoUrl} width="38" height="38" alt="React" />
+ <img src={logoUrl} srcSet={`${logoUrl2x} 2x`} width="38" height="38" alt="React" />
<span className={s.brandTxt}>Your Company</span>
</Link>
<div className={s.banner}>
diff --git a/tools/start.js b/tools/start.js
@@ -32,8 +32,8 @@ async function start() {
if (config.debug) {
config.entry.client = ['react-hot-loader/patch', 'webpack-hot-middleware/client']
.concat(config.entry.client);
- config.output.filename = config.output.filename.replace('[chunkhash]', '[hash]');
- config.output.chunkFilename = config.output.chunkFilename.replace('[chunkhash]', '[hash]');
+ config.output.filename = config.output.filename.replace('[chunkhash', '[hash');
+ config.output.chunkFilename = config.output.chunkFilename.replace('[chunkhash', '[hash');
config.module.loaders.find(x => x.loader === 'babel-loader')
.query.plugins.unshift('react-hot-loader/babel');
config.plugins.push(new webpack.HotModuleReplacementPlugin());
diff --git a/tools/webpack.config.js b/tools/webpack.config.js
@@ -89,20 +89,12 @@ const config = {
localIdentName: isDebug ? '[name]-[local]-[hash:base64:5]' : '[hash:base64:5]',
// CSS Nano http://cssnano.co/options/
minimize: !isDebug,
+ discardComments: { removeAll: true },
})}`,
'postcss-loader?pack=default',
],
},
{
- test: /\.scss$/,
- loaders: [
- 'isomorphic-style-loader',
- `css-loader?${JSON.stringify({ sourceMap: isDebug, minimize: !isDebug })}`,
- 'postcss-loader?pack=sass',
- 'sass-loader',
- ],
- },
- {
test: /\.json$/,
loader: 'json-loader',
},
@@ -111,18 +103,18 @@ const config = {
loader: 'raw-loader',
},
{
- test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
- loader: 'url-loader',
+ test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
+ loader: 'file-loader',
query: {
- name: isDebug ? '[path][name].[ext]?[hash]' : '[hash].[ext]',
- limit: 10000,
+ name: isDebug ? '[path][name].[ext]?[hash:8]' : '[hash:8].[ext]',
},
},
{
- test: /\.(eot|ttf|wav|mp3)$/,
- loader: 'file-loader',
+ test: /\.(mp4|webm|wav|mp3|m4a|aac|oga)(\?.*)?$/,
+ loader: 'url-loader',
query: {
- name: isDebug ? '[path][name].[ext]?[hash]' : '[hash].[ext]',
+ name: isDebug ? '[path][name].[ext]?[hash:8]' : '[hash:8].[ext]',
+ limit: 10000,
},
},
],
@@ -134,6 +126,9 @@ const config = {
extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx', '.json'],
},
+ // Don't attempt to continue if there are any errors.
+ bail: !isDebug,
+
cache: isDebug,
debug: isDebug,
@@ -201,10 +196,14 @@ const config = {
require('postcss-flexbugs-fixes')(),
// Add vendor prefixes to CSS rules using values from caniuse.com
// https://github.com/postcss/autoprefixer
- require('autoprefixer')(),
- ],
- sass: [
- require('autoprefixer')(),
+ require('autoprefixer')({
+ browsers: [
+ '>1%',
+ 'last 4 versions',
+ 'Firefox ESR',
+ 'not ie < 9', // React doesn't support IE8 anyway
+ ],
+ }),
],
};
},
@@ -220,8 +219,8 @@ const clientConfig = extend(true, {}, config, {
},
output: {
- filename: isDebug ? '[name].js?[chunkhash]' : '[name].[chunkhash].js',
- chunkFilename: isDebug ? '[name].[id].js?[chunkhash]' : '[name].[id].[chunkhash].js',
+ filename: isDebug ? '[name].js' : '[name].[chunkhash:8].js',
+ chunkFilename: isDebug ? '[name].chunk.js' : '[name].[chunkhash:8].chunk.js',
},
target: 'web',
@@ -241,14 +240,9 @@ const clientConfig = extend(true, {}, config, {
new AssetsPlugin({
path: path.resolve(__dirname, '../build'),
filename: 'assets.js',
- processOutput: x => `module.exports = ${JSON.stringify(x)};`,
+ processOutput: x => `module.exports = ${JSON.stringify(x, null, 2)};`,
}),
- // 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.OccurrenceOrderPlugin(true),
-
// Move modules that occur in multiple entry chunks to a new entry chunk (the commons chunk).
// http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
new webpack.optimize.CommonsChunkPlugin({
@@ -257,6 +251,11 @@ const clientConfig = extend(true, {}, config, {
}),
...isDebug ? [] : [
+ // 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.OccurrenceOrderPlugin(true),
+
// 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(),
@@ -265,16 +264,33 @@ const clientConfig = extend(true, {}, config, {
// https://github.com/mishoo/UglifyJS2#compressor-options
new webpack.optimize.UglifyJsPlugin({
compress: {
- screw_ie8: true,
+ screw_ie8: true, // React doesn't support IE8
warnings: isVerbose,
},
+ mangle: {
+ screw_ie8: true,
+ },
+ output: {
+ comments: false,
+ screw_ie8: true,
+ },
}),
],
],
// Choose a developer tool to enhance debugging
// http://webpack.github.io/docs/configuration.html#devtool
- devtool: isDebug ? 'source-map' : false,
+ devtool: isDebug ? 'cheap-module-source-map' : false,
+
+ // Some libraries import Node modules but don't use them in the browser.
+ // Tell Webpack to provide empty mocks for them so importing them works.
+ // https://webpack.github.io/docs/configuration.html#node
+ // https://github.com/webpack/node-libs-browser/tree/master/mock
+ node: {
+ fs: 'empty',
+ net: 'empty',
+ tls: 'empty',
+ },
});
//
@@ -312,14 +328,14 @@ const serverConfig = extend(true, {}, config, {
__DEV__: isDebug,
}),
+ // Do not create separate chunks of the server bundle
+ // https://webpack.github.io/docs/list-of-plugins.html#limitchunkcountplugin
+ new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
+
// Adds a banner to the top of each generated chunk
// https://webpack.github.io/docs/list-of-plugins.html#bannerplugin
new webpack.BannerPlugin('require("source-map-support").install();',
{ raw: true, entryOnly: false }),
-
- // Do not create separate chunks of the server bundle
- // https://webpack.github.io/docs/list-of-plugins.html#limitchunkcountplugin
- new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
],
node: {
@@ -331,7 +347,7 @@ const serverConfig = extend(true, {}, config, {
__dirname: false,
},
- devtool: 'source-map',
+ devtool: isDebug ? 'cheap-module-source-map' : 'source-map',
});
export default [clientConfig, serverConfig];