文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
六、webpack 实战场景
6.1 分析打包结果
http://blog.poetries.top/2018/11/20/webpack-bundleAnalyzer/
6.2 优化打包速度
6.2.1 方法一:分开 vendor 和 app
分开第三方代码和业务代码,借助 DllPlugin
和 DllReferencePlugin
之前的打包时间
现在我们来优化这个时间
第一步:新建 webpack.dll.conf.js
// build/webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
// 把这些资源打包成 dll,提高编译速度
react: ['react','react-router-dom','redux','redux-immutable','immutable','react-redux','react-router','redux-logger','redux-thunk','styled-components'],
ui: ['antd-mobile','antd'],
others: ['react-icons','axios','clipboard','humps','lodash','md5','moment','normalizr']
},
output: {
path: path.resolve(__dirname, "../dll/"),
filename: '[name].dll.js',
library: '[name]'
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname,'../dll/','[name]-manifest.json'),
name: '[name]'
}),
new webpack.optimize.UglifyJsPlugin()
]
}
第二步:加一个命令
// package.json
"scripts": {
"dll": "webpack --config config/webpack.dll.conf.js"
}
执行 npm run dll
第三步: 在 plugins 中增加配置
// build/webpack.prod.conf.js
module.exports = {
plugins: [
new webpack.DllReferencePlugin({
manifest: require('../dll/react-manifest.json')
}),
new webpack.DllReferencePlugin({
manifest: require('../dll/ui-manifest.json')
}),
new webpack.DllReferencePlugin({
manifest: require('../dll/others-manifest.json')
})
]
}
再次执行 npm run build
编译时间大大减少了
6.2.2 方法二:UglifyJsPlugin 并行处理
UglifyJsPlugin
parallel
cache
// build/webpack.prod.conf.js
module.exports = {
plugins: [
new UglifyJsPlugin({
parallel:true, //并行处理
cache: true
})
]
}
6.2.3 方法三:happyPack
happyPack
把所有串行的东西并行处理,使得 loader
并行处理,较少文件处理时间
https://www.npmjs.com/package/happypack
// build/webpack.prod.conf.js
// @file: webpack.config.js
const HappyPack = require('happypack');
exports.module = {
rules: [
{
test: /.js$/,
// 1) replace your original list of loaders with "happypack/loader":
// loaders: [ 'babel-loader?presets[]=es2015' ],
use: 'happypack/loader',
include: [ /* ... */ ],
exclude: [ /* ... */ ]
}
],
plugins: [
// 2) create the plugin:
new HappyPack({
// 3) re-add the loaders you replaced above in #1:
loaders: [ 'babel-loader?presets[]=es2015' ]
})
]
}
这时的编译时间也减小了一些
6.2.4 方法四:较少 babel-loader 编译时间
babel-loader
开启缓存,指定编译范围
options.cache
include
exclude
6.2.5 其他
- 减少
resolve
Devtool
去除sourcemap
cache-loader
- 升级
node
- 升级
webpack
6.3 长缓存优化
场景
改变 app
代码, vendor
变化
解决
- 提取
vendor
hash
–>chunkhash
(把hash
变为代码块的hash
,而不是文件的hash
)- 提取
webpack runtime
output: {
path: path.resolve(__dirname, '../build/'),
filename: 'static/js/[name].[chunkhash:5].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
publicPath: '/' //浏览器中访问资源的路径
}
每次打包 vendor
都不会变化,这样就达到了缓存的目的(服务端开启 cache-ctrol
)
场景:引入新模块,模块顺序变化,vendor hash 变化
解决: NamedChunksPlugin
NamedModulesPlugin
对于动态模块引入需要给名称
6.4 多页面应用
6.4.1 多页面特点
- 多入口
- 多页面
HTML
- 每个页面不同的
chunk
- 每个页面不同的参数
6.4.2 多页面多配置
wepback 从 3.1.0
开始支持
优点 :
- 可以使用
parallel-webpack
(并行处理多份配置) 提高打包速度- 配置更独立、灵活
缺点
- 不能多页面之间共享代码
//package.json
{
"name": "多页面配置",
"version": "0.1.0",
"private": true,
"dependencies": {
"clean-webpack-plugin": "^1.0.0",
"css-loader": "^1.0.1",
"ejs-loader": "^0.3.1",
"file-loader": "^2.0.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"react": "^16.3.1",
"style-loader": "^0.23.1",
"webpack": "^4.26.0",
"webpack-merge": "^4.1.4"
},
"scripts": {},
"devDependencies": {
"extract-text-webpack-plugin": "^4.0.0-beta.0"
}
}
/**
* 多页面多配置
* @type {[type]}
*/
const merge = require('webpack-merge')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpack = require('clean-webpack-plugin')
const ExtractTextwebpack = require('extract-text-webpack-plugin')
const path = require('path')
const baseConfig = {
mode: 'development',
entry: {
react: 'react'
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextwebpack.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].[chunkhash].js'
},
plugins: [
new ExtractTextwebpack({
filename: 'css/[name].[hash].css'
}),
new CleanWebpack(['./dist'])
],
optimization: {
splitChunks: {
cacheGroups: {
commons: {
// commons 里面的 name 就是生成的共享模块 bundle 的名字
name: "react",
// chunks 有三个可选值,”initial”, “async” 和 “all”. 分别对应优化时只选择初始的 chunks,所需要的 chunks 还是所有 chunks
chunks: "initial",
minChunks: Infinity
}
}
}
}
}
//生成每个页面配置
const generatePage = function({
title = '',
entry = '',
template = './src/index.html',
name = '',
chunks = []
} = {}){
return {
entry,
plugins: [
new HtmlWebpackPlugin({
chunks,
template:`!!html-loader!${template}`,
filename: name + '.html'
})
]
}
}
const pages = [
generatePage({
title: 'page A',
entry: {
a: './src/pages/a'
},
name: 'a',
chunks: ['react','a']
}),
generatePage({
title: 'page B',
entry: {
b: './src/pages/b'
},
name: 'b',
chunks: ['react','b']
}),
generatePage({
title: 'page C',
entry: {
c: './src/pages/c'
},
name: 'c',
chunks: ['react','c']
})
]
module.exports = pages.map(page=>merge(baseConfig, page))
6.4.3 多页面单配置
多个页面共享一个配置
- 优点:可以共享各个
entry
之间公用代码 - 缺点:打包速度比较慢,输出的内容比较复杂
/**
* 多页面单配置
*/
const merge = require('webpack-merge')
const webpack = require('webpack')
const HtmlWbpackPlugin = require('html-webpack-plugin')
const CleanWebpack = require('clean-webpack-plugin')
const ExtractTextwebpack = require("extract-text-webpack-plugin")
const path = require('path')
const baseConfig = {
mode: 'development',
entry: {
react: 'react'
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextwebpack.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].[chunkhash].js'
},
plugins: [
new ExtractTextwebpack({
filename: 'css/[name].[hash].css'
}),
new CleanWebpack(path.resolve(__dirname, 'dist'))
],
optimization: {
splitChunks: {
cacheGroups: {
commons: {
// commons 里面的 name 就是生成的共享模块 bundle 的名字
name: "react",
// chunks 有三个可选值,”initial”, “async” 和 “all”. 分别对应优化时只选择初始的 chunks,所需要的 chunks 还是所有 chunks
chunks: "initial",
minChunks: Infinity
}
}
}
}
}
//生成每个页面配置
const generatePage = function({
title = '',
entry = '',
template = './src/index.html',
name = '',
chunks = []
} = {}){
return {
entry,
plugins: [
new HtmlWbpackPlugin({
chunks,
template:`!!html-loader!${template}`,
title,
filename: name + '.html'
})
]
}
}
const pages = [
generatePage({
title: 'page A',
entry: {
a: './src/pages/a'
},
name: 'a',
chunks: ['react','a']
}),
generatePage({
title: 'page B',
entry: {
b: './src/pages/b'
},
name: 'b',
chunks: ['react','b']
}),
generatePage({
title: 'page C',
entry: {
c: './src/pages/c'
},
name: 'c',
chunks: ['react','c']
})
]
module.exports = merge([baseConfig].concat(pages))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论