Webpack Dllplugin分离依赖包

424 阅读3分钟

使用场景:

当项目的依赖包整体很大的时候, 常用的依赖不常改动的时候, 就可以使用Dllplugin技术, 将一些公共的依赖包提前打包好, 这样在后续开发和build打包的时候, 都不需要再对这些包重新编译, 极大的提高了构建速度.

这种技术涉及到两个插件:

  1. DllPlugin
  2. DllReferencePlugin

使用步骤:

1. 创建webpack.dll.config.js配置文件.

const path = require('path')
const webpack = require('webpack')
const paths = require('./paths')
const getClientEnvironment = require('./env')

const publicPath = paths.servedPath
const publicUrl = publicPath.slice(0, -1)
const env = getClientEnvironment(publicUrl)

const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

module.exports = {
  // 需要分离的依赖包
  entry: {
    // c1 就是 name
    dll: [
      'antd/lib/modal',
      'antd/lib/tabs',
      'antd/lib/table',
      'antd/lib/popover',
      'antd/lib/checkbox',
      'antd/lib/button'
    ],
  },
  output: {
    path: resolveApp('public'),
    filename: 'static/js/[name].js', // 分离出来的包名
    library: '[name]_library', // 必须与下面 webpack.DllPlugin 配置里面的name保持一致
    publicPath: publicPath
  },
  module: {
    rules: [
      {
        test: /\.svg/,
        use: ['file-loader']
      }
    ]
  },
  // 
  plugins: [
    new webpack.DllPlugin({
      // 映射关系文件名
      path: path.resolve(resolveApp('public'), 'static/js/[name]-manifest.json'),
      name: '[name]_library', // 与 output.library 名保持一致
      context: resolveApp('public')
    }),
  ]
}

这个文件里面会定义:

  1. 配置需要分离的依赖包
  2. 定义依赖包打包之后的文件名
  3. 定义打包之后的 manifest 文件名, manifest 文件里面的内容有一个映射关系, 提供给 DllReferencePlugin 映射到相关的依赖上去.

创建完这个文件之后, 就可以定义一条script语句:

"scripts": {
    "dll": "NODE_ENV=production webpack --config config/webpack.config.dll.js --progress -p"
}

2. 然后运行:

npm run dll

就会生成2个文件:

  1. dll.js
  2. dll-manifest.json

这里生成的两个文件:

  • dll-manifest.json 是一个索引库, 存放的是对应的依赖在dll.js文件中的位置.
  • dll.js 是一个纯依赖库, 本身无法运行, 只作为插件使用

3. 在 webpack.config.js 添加plugin配置

plugins: [
  ......其他配置
  new webpack.DllReferencePlugin({
    context: paths.appPublic,
    manifest: require(path.resolve(resolveApp('public'), 'static/js/dll-manifest.json'))
  }),
]

添加的就是 manifest 文件的路径, 告诉webpack哪个依赖可以去dll.js文件中直接拿. 拿不到的再去node_modules

4.在 html 文件中引入

这里的引入就把dll.js当成一个普通的js文件引入就行, 按照项目路径实际引入

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

5. 注意:

Dllplugin打出来的包会受到依赖版本的影响, 任意的版本变动, 都会导致打包的文件失效. 所以在多人开发的时候, 要使用同一套node_modules, 最好是一个人构建好, 然后把node_modules文件夹压缩下, 然后发给其他的开发同事.

6. 小结:

DllPlugin适合项目依赖非常多的情况, 可以极大的缩短打包的时间, 我们的二项目之前打包一般在20s左右, 运用这个技术之后, 打包时间缩短到了7s左右. 所以, 如果你的项目也有打包很慢的情况, 可以考虑使用这种分离依赖包的形式.

另外, 打包出来的dll.js文件是可以放到cdn的, 而且这个文件基本不会修改, 所以不会每次打包都导致cdn回源. 也能优化网页的访问速度, 提升用户体验.