3

以一个vue全家桶为例

  entry: {
    vendor: [
    'vue/dist/vue.esm.js',
    'vue-router',
    'vuex'
    ]
  }

图1为在生产环境中未使用DllPlugin生成的chunk.js文件

图片描述

图2为在生产环境中使用DllPlugin生成的.dll.js文件

图片描述

图3为在开发环境中未使用DllPlugin生成的.esm运行时文件

图片描述

可以看到,三个文件中都有isUnknownElement这个方法,这说明使用DllPlugin生成的.dll.js文件的内容既为.esm运行时文件的内容(另外这里的.esm运行时文件相当于一个polyfill,内置了一些方法,用于解析webpack编译vue后生成的.js、.css等文件)

在生产环境下,当不使用DllPlugin时,每次编译都会把.esm运行时文件编译到chunk.js中。使用DllPlugin后,只要在index.html中主入口文件前加载这个dll.js文件,就能拿到esm运行时文件的内容,省去了每次编译vue全家桶的时间

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>dll-test</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="./static/js/vendor.dll.js"></script>
    <script src="./main.js"></script>
  </body>
</html>

使用场景:
1.对于像vue,react全家桶这样组合,推荐使用DllPlugin。因为这些框架普遍比较大,而且经常需要组合在一起使用。使用DllPlugin在时间上会有比较不错的收益

2.对于lodash、jquery这样的第三方库,不推荐使用DllPlugin。jquery推荐使用expose-loader+ProvidePlugin。lodash-es按功能模块导入,并配置babel-plugin-lodash、lodash-webpack-plugin选项可以实现Tree Shaking

Dll文件里只适合放置不常改动的代码,比如说第三方库(谁也不会有事无事就升级一下第三方库吧),尤其是本身就庞大或者依赖众多的库。
对于代码优化。DllPlugin&DllReferencePlugin更适合react和vue这样的框架的套餐系列。框架不能像jquery可以通过expose-loader+providePlugin实现cdn加载。因为框架内套餐个数多,如果使用expose-loader+providePlugin方案,那么每次providePlugin声明和externals引入脚本的个数非常多,浪费HTTP请求。也不能通过CommonsChunkPlugin提取公共代码,因为套餐打包后的大小太大。如果参与打包,将会非常缓慢。
DllPlugin&DllReferencePlugin这一方案,实际上也是属于公共代码提取的范畴,但与CommonsChunkPlugin不一样的是,它不仅仅是把公用代码提取出来放到一个独立的文件供不同的页面来使用,它更重要的一点是:把公用代码和它的使用者(业务代码)从编译这一步就分离出来

djalejandro
375 声望10 粉丝

工具用的再好,不如徒手代码来的巧


2

引用和评论

2 条评论
头像
黄先森

请问:若我使用vue-cli2构建项目,然后将vue、vue-router采用cdn的方式引入。那我再使用DllPlugin&DllReferencePlugin时,是否多余了?因为采用cdn引入,则打包后的文件就不含vue、vue-router了。那是否意味着DllPlugin&DllReferencePlugin 和 cdn 只能选其中一种?

2019-07-26
djalejandro(作者)

@黄先森 首先vue、vue-router这样的框架和插件针对开发环境和生产环境做了不同的优化,而这种优化是需要vue、vue-router本身参与编译的。比如,你的mode为production,vue的一些不需要的功能会shaking掉(具体是哪些google下吧,记得在webpack官网看到的)。其次,你说的DllPlugin&DllReferencePlugin是为了解决每次都要重新编译vue、vue-router的问题。原则上,只要你使用的版本没有变化,不建议每次都编译vue、vue-router。至于编译出来的dll文件其实就相当于你使用cdn引入的文件(index.html文件通过脚本引入dll恰似用cdn引入js)。但是相比cdn来说,做了些优化(就是对开发环境和生产环境做了不同的优化)。所以不是只能选一种,你都用也不报错,但是没必要。开发中建议把vue全家桶(vue、vuex、vue-router)打包为一个dll文件,然后放到cdn上。因为你会发现你用到的全家桶会越来越多,如果vue、vuex、vue-router每个文件都使用cdn不但麻烦,而且不易维护(比如vue升级了,难道cdn还要去手动更新吗)

2019-08-03