好久不发博文,最近主要是攻考试去了,积累的几篇文章都懒得写。
今天抽空写一下webpack的打包优化,由于我的框架是基于vue-admin-template做的,框架用的是webpack-chain命令做的,所以也导致了我做webpack优化走了不少弯路。
我的优化主要做了happypack多线程打包和DllReferencePlugin抽离依赖库。
1、先介绍happypack的步骤
(1)安装相关插件,os和happypack,安装的命令根据自己喜欢,我用的是yarn add os 和yarn add happypack。
(2)开始引入依赖,在vue.config.js引入相关依赖,如图:
(3)引入之后开始在chainWebpack(config){}里面写相关代码,如图:
代码如下:
config.plugin('happypack')
.use(HappyPack)
.tap(options => {
options[0] = {
id: 'babel',
// 如何处理 用法和loader 的配置一样
loaders: ['babel-loader?cacheDirectory=true'],
// 共享进程池
threadPool: happyThreadPool
}
return options
})
const hRule = config.module.rule('js')
hRule.test(/\.js$/)
.include.add(resolve('src'))
.end()
hRule.uses.clear()
hRule.use('happypack/loader?id=babel')
.loader('happypack/loader?id=babel')
.end()
这里需要注意的是一定要记得定义一下,const hRule = config.module.rule('js') 再进行过滤和匹配,如果直接在config.module.rule('js').test(/\.js$/).include.add(resolve('src')) .end()是不对的,有可能是不报错又不生效的,有的是打包正式环境会报错,我的会报错,具体错误如下:
这个错误是我百度了不少案例,然后结合自己的需要才找到正确的写法的,希望大家不要跟我一样犯这个错误。参考链接是这位小哥的:https://blog.csdn.net/weixin_44083712/article/details/106102706
以上就是多线程打包的代码优化,下面是DllReferencePlugin抽离依赖库的优化
2、下面是DllReferencePlugin的优化,这个优化一波三折,三次停工去做别的,最后是挤时间搞定的。我做这个主要参考https://www.geekjc.com/post/5d7f901fb4f5e60da8f3e628这个博客写的,他写得很全,但我按照写法是有bug的。下面是我的步骤。
(1)先将相关插件下载,用到是add-asset-html-webpack-plugin和clean-webpack-plugin,我用的是yarn add add-asset-html-webpack-plugin,yarn add clean-webpack-plugin喜欢用npm的可以用npm。
(2)引入依赖,如图:
然后安装完之后就可以写代码啦,
(3)首先写要分离的包,在vue.config.js同级目录下新建webpack.dll.config.js文件,目录图如下:
(4)文件内容如下(主要抽你经常不变的依赖库出来,我的库不变的主要有以下几个,所以就打包了以下几个):
const path = require('path')
// const CleanWebpackPlugin = require('clean-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const webpack = require('webpack')
module.exports = {
mode: 'production',
entry: {
vendor: ['vue/dist/vue.runtime.esm.js', 'vuex', 'vue-router', 'element-ui', 'echarts', 'vue-count-to', 'xlsx'],
util: ['lodash']
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, 'dll'),
library: 'dll_[name]'
},
plugins: [
new CleanWebpackPlugin(), // clean-wepback-plugin目前已经更新到2.0.0,不需要传参数path
new webpack.DllPlugin({
name: 'dll_[name]',
path: path.join(__dirname, 'dll', '[name].manifest.json'),
context: __dirname
})
]
}
(5)在package.json写一个命令 "build:dll": "webpack --config webpack.dll.config.js",如图:
(6)写好命令之后在终端运行以下这个命令生成dll文件夹,如图:
(7)运行完6的命令后生成一个dll文件夹,到这儿离成功就剩一半了,但恰恰是这一半耗了我很长的时间。下面是写代码合并进去的时候,在vue.config.js里面写相关代码。如图:
代码如下:
const dllReference = (config) => {
config.plugin('vendorDll')
.use(webpack.DllReferencePlugin, [{
context: __dirname,
manifest: require('./dll/vendor.manifest.json')
}])
config.plugin('utilDll')
.use(webpack.DllReferencePlugin, [{
context: __dirname,
manifest: require('./dll/util.manifest.json')
}])
config.plugin('addAssetHtml')
.use(AddAssetHtmlPlugin, [
[
{
filepath: require.resolve(path.resolve(__dirname, 'dll/vendor.dll.js')),
outputPath: 'dll',
publicPath: 'dll'
},
{
filepath: require.resolve(path.resolve(__dirname, 'dll/util.dll.js')),
outputPath: 'dll',
publicPath: 'dll'
}
]
])
.after('html')
}
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
if (process.env.NODE_ENV === 'production') {
dllReference(config)
}
}
(8)到这打包就完成了。我试着打包,发现报错了,报什么错呢,报Uncaught ReferenceError: _dll_vendor is not defined,我一百度,有个博主有遇到这个问题,说是未在webpack.dll.config.js中 new DllPlugin({})内未配置context。我看看我的代码我内配置了啊,我的问题不是这个,然后找了很久发现了问题
主要是在vue.config.js里面的config.plugin('addAssetHtml')的publicPath: 'dll'到底应该是怎么样的,因为原博客是publicPath: '/dll',我按照他的写法丢上服务器是报错的。然后看了一下是因为我们的module.exports = { publicPath: './'}是不一样的,我的是相对路径他的是绝对路径module.exports = { publicPath: '/'},所以它需要‘/dll’而我不需要,我只需要写‘dll’。处理完之后打包,清除缓存运行,起来了,啊,一把辛酸泪啊!
注意:如果你路径写不对了,更新完之后,请先清缓存,清缓存很重要,并且后台丢包上去之后,你要等会。我就是因为不等或者是因为忘记清缓存,导致我很多次已经成功了,但是页面上还是报错。我又要不停试别的方法,导致多耗了几个小时的时间。