场景描述:
使用vue-cli官方提供的webpack项目,进行钉钉移动端的开发,项目中期遇到文件限制大小的问题,钉钉要求一个js不能超过5MB,而npm run dev
的时候,并不会把app.js进行拆分,所以所有的依赖库都在app.js里,太大了。
于是就有了这个需求————在dev环境里,也把依赖库拆出来。
方案一:
把npm run build
里的方法拷贝过来,其实就是CommonsChunkPlugin
原配置里的写法是把node_modules里的库都打包到vendor.js里,这个方法里可以自己配置,返回个布尔值就可以了。
拷贝过来以后,发现app.js是变小了,但是vendor.js巨大,5.2mb,还是超了,而且,理论上这些库(vue全家桶、mint、g2)加起来也不应该这么大呀。
方案二:
把依赖的库,先整体都不作处理地打包出来,剩余自己的app.js还是该怎么样怎么样,webpack给我们提供了这么个插件DllPlugin
新建一个配置文件,比如build/webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
vendor: ['vue','vue-router']
},
output: {
path: path.join(__dirname, '../static'),
filename: 'dll.[name].js',
library: '[name]'
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '../', '[name]-manifest.json'),
name: '[name]'
})
]
}
entry里就是先打包出来的库,output就是输出地址和名字,输出到static,因为原配置已经会把static里的内容直接复制到dist里,就不去折腾改其他地方了。
Dllplugin里的path,会输出一个vendor-manifest.json,这是用来做关联id的,打包的时候不会打包进去,所以不用放到static里
然后运行一下webpack -p --progress --config build/webpack.dll.conf.js
成功以后,static下会有dll.vendor.js,根目录下会有vendor.manifest.json
各自打开看一下,就会看到依赖库的源码和匹配id
ok,到这里,抽离依赖库的事情就完成了,那么接下来问题就是怎么引用呢,怎么在dev和build跑呢?
这里补了一点dll和commonsChunk概念上的区别,commonsChunk之所以慢和大,是因为每次run的时候,都会去做一次打包,而实际上我们不会一直去更新我们引用的依赖库,所以dll的做法就等于是,事先先打包好依赖库,然后只对每次都修改的js做打包。
继续刚才的步骤
修改build/webpack.base.conf.js,添加DllReferencePlugin的配置
const manifest = require('../vendor-manifest.json')
。。。。
plugins: [
new webpack.DllReferencePlugin({
manifest
})
]
然后我们直接打开index.html,在底部加上<script src="./static/dll.vendor.js"></script>
是的,就是这么简单粗暴。
运行一下npm run dev
,打开f12看看网络监控,一切顺利的话,这样就ok了
接下来是打包,只需要把原来的commonsChunkPlugin的东西删掉就可以了。npm run build --report
可以感受到速度比原来快了不是一点点
继续优化
- 依赖从package.json读取,而不是手写;
- 带上hash,以免线上缓存问题;
- 带上hash后,自动修改index.html里的引用;
- 命令太长了,最好yarn run一下就好了
const path = require('path')
const webpack = require('webpack')
const package = require('../package.json')
const AssetsPlugin = require('assets-webpack-plugin')
//读取package.json里的依赖,normalize.css除外,打包会报错
const package = require('../package.json')
let dependencies = Object.keys(package.dependencies) || []
//如果使用了chrome的vue-devtool,那打包的时候把vue也排除掉,因为压缩过的vue是不能使用vue-devtool的
dependencies = dependencies.length > 0 ? dependencies.filter(item => item !== 'vue') : []
module.exports = {
entry: {
vendor: dependencies
},
output: {
path: path.join(__dirname, '../static'),
filename: 'dll.[name]_[hash:6].js',
library: '[name]_[hash:6]'
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '../', '[name]-manifest.json'),
name: '[name]_[hash:6]'
}),
new AssetsPlugin({
filename: 'bundle-config.json',
path: './'
})
]
}
在build文件夹新建一个dll.js,读一下配置,跑一下webpack,输出点日志。
var ora = require('ora')
var chalk = require('chalk')
var webpack = require('webpack')
var webpackConfig = require('./webpack.dll.conf')
var spinner = ora('building for dependencies...')
spinner.start()
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
console.log(chalk.cyan(' Build complete.\n'))
})
保存以后,到package.json里添加命令,"dll": "node build/dll.js"
运行 yarn dll
完成~
代码不在这里赘述,可以看我的 github
总结
没有最好的配置,只有最适合的,遇到问题,思考问题,解决问题
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。