Created
October 9, 2017 18:00
-
-
Save ssupinsky/538728b9135c556b28ebb76809aa6179 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* React Starter Kit (https://www.reactstarterkit.com/) | |
* | |
* Copyright © 2014-present Kriasoft, LLC. All rights reserved. | |
* | |
* This source code is licensed under the MIT license found in the | |
* LICENSE.txt file in the root directory of this source tree. | |
*/ | |
import path from 'path'; | |
import webpack from 'webpack'; | |
import AssetsPlugin from 'assets-webpack-plugin'; | |
import ExtractTextPlugin from 'extract-text-webpack-plugin'; | |
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; | |
import pkg from '../package.json'; | |
const isDebug = !process.argv.includes('--release'); | |
const isVerbose = process.argv.includes('--verbose'); | |
const isAnalyze = process.argv.includes('--analyze') || process.argv.includes('--analyse'); | |
// | |
const cssRegExp = /\.css/; | |
// | |
const extractCss = new ExtractTextPlugin({ | |
filename: 'styles-[name]-[contenthash].css', | |
allChunks: true, | |
// disable: false, | |
// ignoreOrder: true, | |
}); | |
// | |
// Common configuration chunk to be used for both | |
// client-side (client.js) and server-side (server.js) bundles | |
// ----------------------------------------------------------------------------- | |
const config = { | |
context: path.resolve(__dirname, '..'), | |
output: { | |
path: path.resolve(__dirname, '../build/public/assets'), | |
publicPath: '/assets/', | |
pathinfo: isVerbose, | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.jsx?$/, | |
loader: 'babel-loader', | |
include: [ | |
path.resolve(__dirname, '../src'), | |
], | |
query: { | |
// https://github.com/babel/babel-loader#options | |
cacheDirectory: isDebug, | |
// https://babeljs.io/docs/usage/options/ | |
babelrc: false, | |
presets: [ | |
// A Babel preset that can automatically determine the Babel plugins and polyfills | |
// https://github.com/babel/babel-preset-env | |
['env', { | |
targets: { | |
browsers: pkg.browserslist, | |
}, | |
modules: false, | |
useBuiltIns: false, | |
debug: false, | |
}], | |
// Experimental ECMAScript proposals | |
// https://babeljs.io/docs/plugins/#presets-stage-x-experimental-presets- | |
'stage-2', | |
// JSX, Flow | |
// https://github.com/babel/babel/tree/master/packages/babel-preset-react | |
'react', | |
// Optimize React code for the production build | |
// https://github.com/thejameskyle/babel-react-optimize | |
...isDebug ? [] : ['react-optimize'], | |
], | |
plugins: [ | |
// Adds component stack to warning messages | |
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source | |
...isDebug ? ['transform-react-jsx-source'] : [], | |
// Adds __self attribute to JSX which React will use for some warnings | |
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-self | |
...isDebug ? ['transform-react-jsx-self'] : [], | |
], | |
}, | |
}, | |
{ | |
test: cssRegExp, | |
// External/third-party styles | |
exclude: path.resolve(__dirname, '../src'), | |
use: ExtractTextPlugin.extract({ | |
use: [ | |
{ | |
loader: 'css-loader', | |
options: { | |
sourceMap: isDebug, | |
minimize: !isDebug, | |
discardComments: { removeAll: true }, | |
}, | |
}, | |
], | |
}), | |
}, | |
{ | |
test: cssRegExp, | |
// Styles from src directory | |
include: path.resolve(__dirname, '../src'), | |
rules: [ | |
{ | |
loader: 'isomorphic-style-loader', | |
}, | |
{ | |
include: path.resolve(__dirname, '../src'), | |
loader: 'css-loader', | |
options: { | |
// CSS Loader https://github.com/webpack/css-loader | |
importLoaders: 1, | |
sourceMap: isDebug, | |
// CSS Modules https://github.com/css-modules/css-modules | |
modules: true, | |
localIdentName: isDebug ? '[name]-[local]-[hash:base64:5]' : '[hash:base64:5]', | |
// CSS Nano http://cssnano.co/options/ | |
minimize: !isDebug, | |
discardComments: { removeAll: true }, | |
}, | |
}, | |
{ | |
loader: 'postcss-loader', | |
options: { | |
config: './tools/postcss.config.js', | |
}, | |
}, | |
], | |
}, | |
{ | |
test: /\.md$/, | |
loader: path.resolve(__dirname, './lib/markdown-loader.js'), | |
}, | |
{ | |
test: /\.txt$/, | |
loader: 'raw-loader', | |
}, | |
{ | |
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/, | |
loader: 'file-loader', | |
query: { | |
name: isDebug ? '[path][name].[ext]?[hash:8]' : '[hash:8].[ext]', | |
}, | |
}, | |
{ | |
test: /\.(mp4|webm|wav|mp3|m4a|aac|oga)(\?.*)?$/, | |
loader: 'url-loader', | |
query: { | |
name: isDebug ? '[path][name].[ext]?[hash:8]' : '[hash:8].[ext]', | |
limit: 10000, | |
}, | |
}, | |
], | |
}, | |
// Don't attempt to continue if there are any errors. | |
bail: !isDebug, | |
cache: isDebug, | |
stats: { | |
colors: true, | |
reasons: isDebug, | |
hash: isVerbose, | |
version: isVerbose, | |
timings: true, | |
chunks: isVerbose, | |
chunkModules: isVerbose, | |
cached: isVerbose, | |
cachedAssets: isVerbose, | |
}, | |
}; | |
// | |
// Configuration for the client-side bundle (client.js) | |
// ----------------------------------------------------------------------------- | |
const clientConfig = { | |
...config, | |
name: 'client', | |
target: 'web', | |
entry: { | |
client: ['babel-polyfill', './src/client.js'], | |
}, | |
output: { | |
...config.output, | |
filename: isDebug ? '[name].js' : '[name].[chunkhash:8].js', | |
chunkFilename: isDebug ? '[name].chunk.js' : '[name].[chunkhash:8].chunk.js', | |
}, | |
plugins: [ | |
extractCss, | |
// Define free variables | |
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin | |
new webpack.DefinePlugin({ | |
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"', | |
'process.env.BROWSER': true, | |
__DEV__: isDebug, | |
}), | |
// Emit a file with assets paths | |
// https://github.com/sporto/assets-webpack-plugin#options | |
new AssetsPlugin({ | |
path: path.resolve(__dirname, '../build'), | |
filename: 'assets.json', | |
prettyPrint: 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({ | |
name: 'vendor', | |
minChunks: module => /node_modules/.test(module.resource), | |
}), | |
...isDebug ? [] : [ | |
// Minimize all JavaScript output of chunks | |
// https://github.com/mishoo/UglifyJS2#compressor-options | |
new webpack.optimize.UglifyJsPlugin({ | |
sourceMap: true, | |
compress: { | |
screw_ie8: true, // React doesn't support IE8 | |
warnings: isVerbose, | |
unused: true, | |
dead_code: true, | |
}, | |
mangle: { | |
screw_ie8: true, | |
}, | |
output: { | |
comments: false, | |
screw_ie8: true, | |
}, | |
}), | |
], | |
// Webpack Bundle Analyzer | |
// https://github.com/th0r/webpack-bundle-analyzer | |
...isAnalyze ? [new BundleAnalyzerPlugin()] : [], | |
], | |
// Choose a developer tool to enhance debugging | |
// http://webpack.github.io/docs/configuration.html#devtool | |
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', | |
}, | |
}; | |
// | |
// Configuration for the server-side bundle (server.js) | |
// ----------------------------------------------------------------------------- | |
const serverConfig = { | |
...config, | |
name: 'server', | |
target: 'node', | |
entry: { | |
server: ['babel-polyfill', './src/server.js'], | |
}, | |
output: { | |
...config.output, | |
filename: '../../server.js', | |
libraryTarget: 'commonjs2', | |
}, | |
module: { | |
...config.module, | |
// Override babel-preset-env configuration for Node.js | |
rules: config.module.rules.map(rule => (rule.loader !== 'babel-loader' ? rule : { | |
...rule, | |
query: { | |
...rule.query, | |
presets: rule.query.presets.map(preset => (preset[0] !== 'env' ? preset : ['env', { | |
targets: { | |
node: parseFloat(pkg.engines.node.replace(/^\D+/g, '')), | |
}, | |
modules: false, | |
useBuiltIns: false, | |
debug: false, | |
}])), | |
}, | |
})), | |
}, | |
externals: [ | |
/^\.\/assets\.json$/, | |
(context, request, callback) => { | |
const isExternal = | |
request.match(/^[@a-z][a-z/.\-0-9]*$/i) && | |
!request.match(/\.(css|less|scss|sss)$/i); | |
callback(null, Boolean(isExternal)); | |
}, | |
], | |
plugins: [ | |
// Define free variables | |
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin | |
new webpack.DefinePlugin({ | |
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"', | |
'process.env.BROWSER': false, | |
__DEV__: isDebug, | |
}), | |
extractCss, | |
// 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({ | |
banner: 'require("source-map-support").install();', | |
raw: true, | |
entryOnly: false, | |
exclude: 'style.css', | |
}), | |
], | |
node: { | |
console: false, | |
global: false, | |
process: false, | |
Buffer: false, | |
__filename: false, | |
__dirname: false, | |
}, | |
devtool: isDebug ? 'cheap-module-source-map' : 'source-map', | |
}; | |
export default [clientConfig, serverConfig]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment