网上关于webpack的优化的已经很多了,只是都比较零散,结合实战项目自己做个总结
webpack 优化,实际项目中主要做到了一下几点:
1、 文件压缩(css, js, html, 字体文件, 图片文件)
2、 babel-loader 避免不必要的转义
3、 babel-转义结果进行缓存
4、 公共模块的提取
5、 loader 转为多进程
6、 按需加载
7、 DllPlugin 增加开发时打包速度
8、 Gzip进行文件压缩,webpack压缩文件,后台可以再次进行压缩
接下来针对每一个细节点进行详细说明
1、文件压缩(html, css, js, 字体文件,图片文件的压缩和转码)
HtmlWebpackPlugin 官网链接 https://webpack.docschina.org/plugins/html-webpack-plugin/#src/components/Sidebar/Sidebar.jsx
关于 HtmlWebpackPlugin 的插件使用就不过多赘述,参考官方文档,主要是用来压缩代码以及自动将打包后生成的就是文件插入到html中
如图中所示的<script></script>标签对js的引入都是该插件的功劳,具体用法和配置如下
plugins: [
new HtmlWebpackPlugin({
filename: config.build.index, // 指定项目的生成名称
template: 'index.html', // 将模板指向根那个目录
inject: true, // 指定生成的<script></script>放在那个目录
// 去掉空格、注释、多余的应用等等都在这里配置
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency', // 成产环境下的第三方依赖进行压缩
}),
]
js 压缩用法同上,就不细讲了参见官方文档
https://webpack.docschina.org/guides/migrating/#uglifyjsplugin-sourcemap
css、图片、字体文件压缩主要通过 loader 来进行
配置如下:
const webpackConfig = {
module: {
rules: [
{
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000, // 限制压缩文件的大小
name: utils.assetsPath('media/[name].[hash:7].[ext]') // 文件的路径
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
2、3 关于babel 的转码和转码缓存
const webpackConfig = {
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory=true', // 将转译结果缓存至文件系统
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] // 针对特定的文件进行转码 通过include来配置,效率比 exclude 要高
},
]
}
}
4、公共模块的提取配置文件如下
plugins配置如下
const webpackConfig = {
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
]
}
主要是目的是将第三方依赖抽取到公共模块放到vendor.js,然后针对动态引入的静态文件做进一步的抽离放到 manifest.js 中
5、多进程转码
具体用法和配置如下:
const HappyPack = require('happypack') // 引入第三方依赖
const happyThreadPool = HappyPack.ThreadPool({size: 5}) // 设定五个线程池这里默认设置5个进程
module.exports = {
plugins: [
new HappyPack({
id: 'happyBabel', // 定义唯一id
threadPool: happyThreadPool, // 指定进程池
loaders: ['babel-loader?cacheDirectory=true']
}),
],
module: {
rules: [
{
test: /\.js$/,
loader: 'happypack/loader?id=happyBabel', // 通过唯一id进行查找
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
]
}
}
6、按需加载配置如下,实际生产中减少渲染压力
{
path: '/test',
name: 'test',
component: resolve => require(['@/test'], resolve)
}
7、DllPlugin 插件的使用(这里提供简单的配置,具体根据实际需要)
首先在你的build文件加下新建 webpack.dall.config.js 文件,内容如下
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
vendor: [
'aws-sdk',
'axios',
'moment',
'vue',
'vue-awesome-swiper',
'vue-router',
'vuex',
]
},
output: {
path: path.resolve(__dirname, '../static'), // 这里通过绝对路径指定生成文件
filename: '[name].dll.js',
library: '[name]_library'
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(__dirname, '../static', '[name]-manifest.json'),
name: '[name]_library'
}),
]
}
控制台输入 webpack --config build/webpack.dall.config.js
或者 在package.json文件中进行如下配置 运行 npm/cnpm/yarn build build:dall
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"test": "cross-env NODE_ENV=test env_config=test node build/build.js",
"lint": "eslint --ext .js,.vue src",
"build": "cross-env NODE_ENV=production env_config=prod node build/build.js",
"build:dall": "webpack --config build/webpack.dall.config.js"
},
将会看到static目录项生成 vendor.dall.js 和 vende-manifest.json文件,生成文件如下
接下来在生 build 下的 webpack.prod.conf.js 进行引用
到这个时候我们进行一口深呼吸,以为打工打工告成,结果发现每次打包,然并卵,各位可怜的程序员,别急,万里长征还剩最后一步,生成的js文件你不引用还能怪谁啊亲
看清楚了怎么引用
找到你的index.html文件手动引入 vendor.dll.js如下
第一次运行速度依然没啥改变,当你再次运行的时候你会有飞一般的感觉
8、Gzip 文件压缩 根据实际情况,具体配置如下
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
以上是个人在实际生产项目中的webpack打包以及代码压缩的优化,从一开始的发版打包项目 接近一份到到 20几秒将近一半时间的缩短,从一开始发版后端人员的抱怨:好没好,你们打包这么这么慢 到 我靠!!!这么快就好了。这是一种自我价值的体现和别人对你的肯定。
更多的干货请点击这里 https://blog.csdn.net/woleigequshawanyier
欢迎各位看官的批评和指正,共同学习和成长
希望该文章对您有帮助,也希望得到您的鼓励和支持