webpack踩坑记——DllPlugin和DllReferencePlugin

场景描述:

使用vue-cli官方提供的webpack项目,进行钉钉移动端的开发,项目中期遇到文件限制大小的问题,钉钉要求一个js不能超过5MB,而npm run dev的时候,并不会把app.js进行拆分,因此全部的依赖库都在app.js里,太大了。
因而就有了这个需求————在dev环境里,也把依赖库拆出来。javascript

方案一:

npm run build里的方法拷贝过来,其实就是CommonsChunkPlugincss

原配置里的写法是把node_modules里的库都打包到vendor.js里,这个方法里能够本身配置,返回个布尔值就能够了。
拷贝过来之后,发现app.js是变小了,可是vendor.js巨大,5.2mb,仍是超了,并且,理论上这些库(vue全家桶、mint、g2)加起来也不该该这么大呀。html

方案二:

把依赖的库,先总体都不做处理地打包出来,剩余本身的app.js仍是该怎么样怎么样,webpack给咱们提供了这么个插件DllPluginvue

新建一个配置文件,好比build/webpack.dll.conf.jsjava

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
各自打开看一下,就会看到依赖库的源码和匹配idnode

ok,到这里,抽离依赖库的事情就完成了,那么接下来问题就是怎么引用呢,怎么在dev和build跑呢?webpack

这里补了一点dll和commonsChunk概念上的区别,commonsChunk之因此慢和大,是由于每次run的时候,都会去作一次打包,而实际上咱们不会一直去更新咱们引用的依赖库,因此dll的作法就等因而,事先先打包好依赖库,而后只对每次都修改的js作打包。git

继续刚才的步骤

修改build/webpack.base.conf.js,添加DllReferencePlugin的配置github

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了web

接下来是打包,只须要把原来的commonsChunkPlugin的东西删掉就能够了。
npm run build --report
能够感觉到速度比原来快了不是一点点

继续优化

  1. 依赖从package.json读取,而不是手写;
  2. 带上hash,以避免线上缓存问题;
  3. 带上hash后,自动修改index.html里的引用;
  4. 命令太长了,最好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

总结

没有最好的配置,只有最适合的,遇到问题,思考问题,解决问题

参考

  1. https://doc.webpack-china.org...
  2. http://engineering.invisionap...
  3. https://segmentfault.com/a/11...
相关文章
相关标签/搜索