Webpack v1.x 笔记

混淆和压缩
1
2
3
4
5
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false },
}),
]
支持jQuery

npm install jquery,然后

1
2
3
plugins: [
new webpack.ProvidePlugin({ jQuery: 'jquery' }),
]
生成html入口文件
1
2
3
4
5
6
7
const HtmlWebpackPlugin = require('html-webpack-plugin');
...
plugins: [
new HtmlWebpackPlugin({
template: 'index.template.html',
}),
]

template文件如

1
2
3
4
5
6
7
8
9
10
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hello React</title>
</head>
<body>
<div id='root'></div>
</body>
</html>

插件会在template的<body>内最后插入js脚本,在<head>内最后插入css样式

参见:Using the HTML Webpack Plugin for generating HTML files

dev-server.js还要修改

1
2
3
4
5
6
7
8
9
10
11
const compiler = webpack(webpackConfig);
...
app.use('*', (req, res, next) => {
const filename = path.join(compiler.outputPath, 'index.html');
compiler.outputFileSystem.readFile(filename, (err, result) => {
if (err) return next(err);
res.set('content-type', 'text/html');
res.send(result);
res.end();
});
});

参见:issue 145

提取vendor模块
1
2
3
4
5
6
7
8
9
10
const pkg = require('./package.json');
...
entry: {
vendor: Object.keys(pkg.dependencies),
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest'],
}),
]

CommonsChunkPlugin需要这第二个参数manifest,这样才能在app模块更新时不影响vendor模块的chunkhash值。

参见:Splitting Bundles

资源名hash化
1
2
3
output: {
filename: '[name].[chunkhash].js',
}

name可以理解为entry配置中指定的模块名。 chunkhash是某个分片的hash值,hash是bundle整体的hash值。HMR热更新会与chunkhash冲突,需要HMR热更新的开发环境只能用[name].[hash].js

提取css文件
1
2
3
4
5
6
7
8
9
10
const ExtractTextPlugin = require('extract-text-webpack-plugin');
...
plugins: [
new ExtractTextPlugin('[name].[chunkhash].css'),
],
module: {
loaders: [
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css') },
],
}

HMR热更新会与ExtractTextPlugin冲突,需要HMR热更新的开发环境不能用ExtractTextPlugin,比如:

1
2
3
4
5
module: {
loaders: [
{ test: /\.css$/, loader: 'style!css' },
],
}
启用css-modules

在loader中加上modules即为启用,localIdentName是设置生成样式的命名规则

1
2
3
4
5
6
module: {
loaders: [{
test: /\.css$/,
loader: 'style!css?modules&localIdentName=[local]__[hash:base64:5]'
}],
}

使用ExtractTextPlugin时:

1
2
3
4
5
6
module: {
loaders: [{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[local]__[hash:base64:5]'
}],
}

使用sass时:

1
2
3
4
5
6
module: {
loaders: [{
test: /\.scss$/,
loader: 'style!css?modules&localIdentName=[local]__[hash:base64:5]!sass'
}],
}

src/styles目录是全局样式,其他目录是使用css-modules的局部样式:

1
2
3
4
5
6
7
8
9
10
11
module: {
loaders: [{
test: /\.scss$/,
exclude: path.resolve(__dirname, 'src/styles'),
loader: 'style!css?modules&localIdentName=[local]__[hash:base64:5]!sass'
}, {
test: /\.scss$/,
include: path.resolve(__dirname, 'src/styles'),
loader: 'style!css!sass'
}
}
去除没用的css

这个插件较慢,只需在生产环境下使用

1
2
3
4
5
const PurifyCSSPlugin = require('purifycss-webpack-plugin');
...
plugins: [
new PurifyCSSPlugin({}),
]

参考