美文网首页
DllPlugin配置分割你的第三方库

DllPlugin配置分割你的第三方库

作者: zhCN_超 | 来源:发表于2017-12-14 10:34 被阅读165次

前言

很久没有写分享了,期间一直在开发自己的小站,先已上线,更多功能在开发中,欢迎大家访问,如果打开是个美女,说明有点问题,我在整改,过段时间再来访问吧。传送门

首页-M1994.png
下载站点-M1994.png

主题

问题

小站利用React全家桶开发,在上线之后,发现第三方bundle(2Mb左右)下载用了近20秒。
最初发现的问题是nginx压缩配置gzip没有添加application/javascript这个MIME类型,但是仍然花了近5秒。

解决过程

初始

起初,我的配置文件(webpack.dll.js)内容如下:

const path = require('path');
const webpack = require('webpack');

const vendors = [
  'react',
  'antd',
  'lodash'
  ... // 其他第三方库
]

const config = {
  entry: { vendors },
  output: {
    filename: '[name].dll.js',
    library: '[name]_library', // 与 DllPlugin 的 name 保持一致
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.resolve('dll', '[name].manifest.json'),
      name: '[name]_library', // 这里的命名要遵循变量命名规范,它是最终的包变量名
    })
    // prod 添加你的 Uglifyjs 插件
  ]
}

这个配置文件独立于你应用的webpack.dev.jswebpack.prod.js等配置文件
PS:只附关键代码,项目根目录为project,更多配置参数请参见官网

运行这个配置文件之后,这样会在/project/dll目录中生成两个文件:

  • vendors.dll.js
  • vendors.manifest.json

我们需要在inedx.html页面(也在项目根目录下)中将vendors.dll.js引入

<script src="/dll/vendors.dll.js"></script>

在你的webpack.dev.jswebpack.prod.js配置的plugins属性中添加:

const manifestFile = path.relove('dll, 'vendors.manifest.json'); // manifest.json 文件地址
const config = {
  ... // 其他配置
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: manifestFile
    })
  ... // 其它 plugin
  ]
}

改进1

考虑到浏览器并发请求数默认为6个,我开始拆分第三方包(webpack.dll.js):

const Libs = {
  ui: [
    'antd'
  ],
  base: [
    'lodash'
  ],
  frame: [
    'react'
  ]
}
const config = {
  entry: { ...Libs },
  ... // 其他配置
}

运行之后,会生成三个.js.manifest.json文件,同样你需要将.js引用加入到你的index.js页面:

<script src="/dll/ui.dll.js"></script>
<script src="/dll/base.dll.js"></script>
<script src="/dll/frame.dll.js"></script>

而在你的webpack.dev.jswebpack.prod.js中,你需要多次调用DllReferencePlugin插件:

const manifestFileUi = path.relove('dll, 'ui.manifest.json');
const manifestFileBase = path.relove('dll, 'base.manifest.json');
const manifestFileFrame = path.relove('dll, 'frame.manifest.json');
const config = {
  ... // 其他配置
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: manifestFileUi
    }),
    new webpack.DllReferencePlugin({
      manifest: manifestFileBase
    }),
    new webpack.DllReferencePlugin({
      manifest: manifestFileFrame
    })
  ... // 其它 plugin
  ]
}

建议根据 Libs 变量写个函数循环生成

改进2

我发现antdlodash打包出来仍然很大,那么就按需加载(webpack.dll.js):

const Libs = {
  ui: [
    'antd/es/button',
    'antd/es/input',
    ... // 其他你项目中用到的 UI 组件
  ],
  base: [
    'lodash/fp/get',
    'lodash/fp/set',
    ... // 其他你项目中用到的函数
  ]
  ... // frame
}

最终的加载时间为1秒左右

问题

lodash按需加载的话,它使用方法改变如下:

// 之前
import _ from 'lodash';
_.get(...);

// 之后
import get from 'lodash/fp/get;
get(...)

但是第二种方法总是返回undefined,所以我改回了第一种使用方法,但是仍然是按需打包,问题有待查找。

结束

先这么多,有问题欢迎留言。

相关文章

网友评论

      本文标题:DllPlugin配置分割你的第三方库

      本文链接:https://www.haomeiwen.com/subject/uwehwxtx.html