webpack打包时会将第三方包和业务代码一起打包,实际上第三方包不经常变化,不需要每次都参与打包。
如果把第三方包打包成一个库,供项目使用,那么打包第三方包的操作只需要在依赖包发生变化时进行一次即可。并且将第三方包提取出来,业务代码的打包速度也会提高。

打包DLL

例如一般react项目都会用到react和react-dom两个包,可以把它们提取成一个库,提供react项目使用,这样打包该项目的时候react和react-dom就不会参与打包了。
webpack 提供了一个插件:DllPlugin,可以把多个包打包成一个库。

  1. // webpack.dll.js 打包dll的配置文件
  2. const path = require('path')
  3. const webpack = require('webpack')
  4. const TerserPlugin = require('terser-webpack-plugin')
  5. module.exports = {
  6. mode: "production",
  7. entry: {
  8. react: ['react', 'react-dom'], // 将react和react-dom打包成一个库,这里有多少个数组就会生成多少个库文件
  9. jquery: ['jquery']
  10. },
  11. output: {
  12. path: path.resolve(__dirname, 'dll'),
  13. filename: 'dll_[name].js',
  14. library: 'dll_[name]'
  15. },
  16. optimization: {
  17. minimizer: [
  18. new TerserPlugin({
  19. extractComments: false // 不生成库的LICENCE文件
  20. }),
  21. ],
  22. },
  23. plugins: [
  24. new webpack.DllPlugin({
  25. name: 'dll_[name]',
  26. path: path.resolve(__dirname, './dll/[name].manifest.json')
  27. })
  28. ]
  29. }

生成的库:
image.png
manifest.json 用来指示库的位置索引。
比如react的库的内容如下:
image.png

使用DLL

webpack提供的另外一个插件:DllReferencePlugin 可以加载已经打包的库。

  1. plugins: [
  2. new HtmlWebpackPlugin({
  3. title: 'copyWebpackPlugin',
  4. template: './public/index.html'
  5. }),
  6. new webpack.DllReferencePlugin({
  7. context: resolveApp('./'), // 指定上下文,和manifest.json对应的库文件的位置,如果在同一个文件夹,写 ./
  8. manifest: resolveApp('./dll/react.manifest.json') // 指定manifest.json的路径
  9. }),
  10. ]
  1. 这样webpack打包就不会将react一并打包,但是这样打包生成的index.html文件并不会引用库文件,需要另外的插件:AddAssetHtmlPlugin 将库文件添加到index.htmlscript标签。
  1. plugins: [
  2. new HtmlWebpackPlugin({
  3. title: 'copyWebpackPlugin',
  4. template: './public/index.html'
  5. }),
  6. new webpack.DllReferencePlugin({
  7. context: resolveApp('./'), // 指定上下文,和manifest.json对应的库文件的位置,如果在同一个文件夹,写 ./
  8. manifest: resolveApp('./dll/react.manifest.json') // 指定manifest.json的路径
  9. }),
  10. new AddAssetHtmlPlugin({
  11. outputPath: 'js', // 输出到 js 文件夹
  12. filepath: resolveApp('./dll/dll_react.js') // 库文件路径
  13. })
  14. ]

image.png
发现生成的index.html,引用的库文件总是放在一个auto文件夹,但这个文件夹事实上并不存在,在这个例子中dll_react.js放在了js文件夹中,可能是 bug。所以把AddAssetHtmlPlugin配置的输出文件夹也改成auto会比较好,否则要去手动更改index.html。