贴出项目中webpack相关配置,逐个解析
1. 生产环境配置 webpack.config.prod.js
var autoprefixer = require('autoprefixer');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ManifestPlugin = require('webpack-manifest-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var url = require('url');
var paths = require('./paths');
var getClientEnvironment = require('./env');
var alias = require('./alias');
function ensureSlash(path, needsSlash) {
var hasSlash = path.endsWith('/');
if (hasSlash && !needsSlash) {
return path.substr(path, path.length - 1);
} else if (!hasSlash && needsSlash) {
return path + '/';
} else {
return path;
}
}
var homepagePath = require(paths.appPackageJson).homepage;
var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
var publicPath = ensureSlash(homepagePathname, true);
var publicUrl = ensureSlash(homepagePathname, false);
var env = getClientEnvironment(publicUrl);
if (env['process.env'].NODE_ENV !== '"production"') {
throw new Error('Production builds must have NODE_ENV=production.');
}
module.exports = {
bail: true,
devtool: 'source-map',
entry: {
common: [
require.resolve('react-dev-utils/webpackHotDevClient'),
require.resolve('./polyfills'),
paths.appIndexJs
],
zh_CN: paths.i18n['zh-CN'],
en_US: paths.i18n['en-US']
},
output: {
path: paths.appBuild,
filename: 'static/js/[name].[chunkhash:8].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
publicPath: publicPath
},
resolve: {
fallback: paths.nodePaths,
extensions: ['.js', '.json', '.jsx', ''],
alias
},
module: {
preLoaders: [
{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc
}
],
loaders: [
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.css$/,
/\.less$/,
/\.json$/,
/\.svg$/
],
loader: 'url',
query: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
},
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
loader: 'babel'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', 'css?importLoaders=1!postcss')
},
{
test: /\.less$/,
loader: `style!css!postcss!less`
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.svg$/,
loader: 'file',
query: {
name: 'static/media/[name].[hash:8].[ext]'
}
}
]
},
postcss: function () {
return [
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
]
}),
];
},
plugins: [
new InterpolateHtmlPlugin({
PUBLIC_URL: publicUrl
}),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
filename: 'index-en.html',
chunks: ['en_US', 'common'],
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
filename: 'index.html',
chunks: ['zh_CN', 'common'],
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
new webpack.DefinePlugin(env),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true,
warnings: false
},
mangle: {
screw_ie8: true
},
output: {
comments: false,
screw_ie8: true
}
}),
new ExtractTextPlugin('static/css/[name].[contenthash:8].css'),
new ManifestPlugin({
fileName: 'asset-manifest.json'
})
],
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};
2. 开发环境配置 webpack.config.dev.js
var autoprefixer = require('autoprefixer');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
var getClientEnvironment = require('./env');
var paths = require('./paths');
var alias = require('./alias');
var publicPath = '/';
var publicUrl = '';
var env = getClientEnvironment(publicUrl);
module.exports = {
devtool: 'cheap-module-source-map',
entry: {
common: [
require.resolve('react-dev-utils/webpackHotDevClient'),
require.resolve('./polyfills'),
paths.appIndexJs
],
zh_CN: paths.i18n['zh-CN'],
en_US: paths.i18n['en-US']
},
output: {
path: paths.appBuild,
pathinfo: true,
filename: 'static/js/[name].bundle.js',
publicPath: publicPath
},
resolve: {
fallback: paths.nodePaths,
extensions: ['.js', '.json', '.jsx', ''],
alias
},
module: {
preLoaders: [
{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc,
}
],
loaders: [
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.less$/,
/\.css$/,
/\.json$/,
/\.svg$/
],
loader: 'url',
query: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
},
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
loader: 'babel'
},
{
test: /\.less$/,
loader: `style!css!postcss!less`
},
{
test: /\.css$/,
loader: 'style!css?importLoaders=1!postcss'
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.svg$/,
loader: 'file',
query: {
name: 'static/media/[name].[hash:8].[ext]'
}
}
]
},
postcss: function () {
return [
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9',
]
}),
];
},
plugins: [
new InterpolateHtmlPlugin({
PUBLIC_URL: publicUrl
}),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
filename: 'index.html',
chunks: ['zh_CN', 'common']
}),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
filename: 'index-en.html',
chunks: ['en_US', 'common']
}),
new webpack.DefinePlugin(env),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
new WatchMissingNodeModulesPlugin(paths.appNodeModules)
],
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};