zoukankan      html  css  js  c++  java
  • 利用DllPlugin性能优化

    介绍

    在用 Webpack 打包的时候,对于一些不经常更新的第三方库,比如 react,lodash,vue 我们希望能和自己的代码分离开,Webpack 社区有两种方案
    CommonsChunkPlugin
    DLLPlugin
    对于 CommonsChunkPlugin,webpack 每次打包实际还是需要去处理这些第三方库,只是打包完之后,能把第三方库和我们自己的代码分开。而 DLLPlugin 则是能把第三方代码完全分离开,即每次只打包项目自身的代码。Dll这个概念是借鉴了Windows系统的dll,一个dll包,就是一个纯纯的依赖库,它本身不能运行,是用来给你的app引用的

    使用

    添加配置文件

    要使用 DLLPlugin,需要额外新建一个配置文件webpack.dll.js,该配置文件用来打包生成第三方库。
    webpack.dll.js

    const webpack = require('webpack')
    const path = require('path')
    module.exports = {
      mode: 'production',
      entry: {
        vendor: ['lodash'],
        react: ['react']
      },
      output: {
        filename: '[name].dll.js',
        path: path.resolve(__dirname, './dll'),
        library: '[name]',
        // libraryTarget: 'umd' // 将入口文件的返回值以什么类型的方式导出,umd比较全,包括amd、cmd、window
      },
      plugins: [
        new webpack.DllPlugin({
          name: '[name]',
          path: path.join(__dirname, './dll/[name].manifest.json')
        })
      ]
    }
    

    然后运行 命令行运行"webpack --config webpack-dll.js"
    生成打包后的文件

    接下来就是,这么在业务代码里使用打包好的第三方模块的事情了。

    修改配置文件webpack-common.js

    关键代码如下:

    const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
    ....
      plugins: [
        new AddAssetHtmlWebpackPlugin({//将打包好的dll文件挂载到html中
          filepath: path.resolve(__dirname, './dll/react.dll.js')
        }),
        new AddAssetHtmlWebpackPlugin({
          filepath: path.resolve(__dirname, './dll/vendor.dll.js')
        }),
        new webpack.DllReferencePlugin({
          manifest: path.resolve(__dirname, './dll/vendor-manifest.json')
        }),
        new webpack.DllReferencePlugin({
          manifest: path.resolve(__dirname, './dll/react-manifest.json')
        })
      ],
    

    浏览器控制台,可以看到第三方模块,已经作为全局变量,引入到了入口文件中。

    但是每次在webpack.dll.js新加第三方模块,都要在webpack-common.js里添加DllReferencePlugin等,比较麻烦,我们可以用node写一个文件循环,自己读取文件数量,自动修改plugin
    关键代码如下:

    const fs = require('fs')
    const files = fs.readdirSync(path.resolve(__dirname, '../dll'));
    const plugins = [
      new HtmlWebpackPlugin({
        template: './src/index.html'
      }),
      new CleanWebpackPlugin(),
      new BundleAnalyzerPlugin(),
      new webpack.ProvidePlugin({
        _: 'lodash'
      }),
    ]
    files.forEach(file => {
      if (/.*.dll.js/.test(file)) {
        plugins.push(new AddAssetHtmlWebpackPlugin({//将打包好的dll文件挂载到html中
          filepath: path.resolve(__dirname, '../dll', file)
        }))
      }
      if (/.*.manifest.json/.test(file)) {
        plugins.push(new webpack.DllReferencePlugin({//分析第三方模块是否已经在dll文件里,如果里面有就不用再node_modules在分析打包了
          manifest: path.resolve(__dirname, '../dll', file)
        }))
      }
    })
    

    总结整体流程

    通过dllPlugin生成manifets.json和vendor.js,vendor.js会自执行返回一个加载函数vendor(名字可配置),通过闭包将模块存储在内存中,注意vendor是一个全局变量。
    webpack通过DllReferencePlugin在打包的时候分析业务代码中使用了哪些第三方模块,哪些模块是不需要打包进业务代码中,而是去vendor.js中获取。
    vendor中获取的模块是通过调用全局函数vendor(id)来进行引入。

    补充

    CommonsChunkPlugin 插件每次打包的时候还是会去处理一些第三方依赖库,只是它能把第三方库文件和我们的代码分开掉,生成一个独立的js文件。但是它还是不能提高打包的速度。

    DLLPlugin 它能把第三方库代码分离开,并且每次文件更改的时候,它只会打包该项目自身的代码。所以打包速度会更快。

    DLLPlugin 这个插件是在一个额外独立的webpack设置中创建一个只有dll的bundle,也就是说我们在项目根目录下除了有webpack.config.js,还会新建一个webpack.dll.config.js文件。webpack.dll.config.js作用是把所有的第三方库依赖打包到一个bundle的dll文件里面,还会生成一个名为 manifest.json文件。
    该manifest.json的作用是用来让 DllReferencePlugin 映射到相关的依赖上去的。

    DllReferencePlugin 这个插件是在webpack.config.js中使用的,该插件的作用是把刚刚在webpack.dll.config.js中打包生成的dll文件引用到需要的预编译的依赖上来。什么意思呢?就是说在webpack.dll.config.js中打包后比如会生成 vendor.dll.js文件和vendor-manifest.json文件,vendor.dll.js文件包含所有的第三方库文件,vendor-manifest.json文件会包含所有库代码的一个索引,当在使用webpack.config.js文件打包DllReferencePlugin插件的时候,会使用该DllReferencePlugin插件读取vendor-manifest.json文件,看看是否有该第三方库。vendor-manifest.json文件就是有一个第三方库的一个映射而已。

    所以说 第一次使用 webpack.dll.config.js 文件会对第三方库打包,打包完成后就不会再打包它了,然后每次运行 webpack.config.js文件的时候,都会打包项目中本身的文件代码,当需要使用第三方依赖的时候,会使用 DllReferencePlugin插件去读取第三方依赖库。所以说它的打包速度会得到一个很大的提升。

  • 相关阅读:
    ZOJ3213-Beautiful Meadow
    ZOJ3256-Tour in the Castle
    ZOJ3466-The Hive II
    hdu3377-Plan
    fzu1977-Pandora Adventure
    ural1519-Formula 1
    poj2914-Minimum Cut
    51nod-1220-约数之和
    51nod-1222-最小公倍数计数
    【html】【6】div浮动float
  • 原文地址:https://www.cnblogs.com/superlizhao/p/13634525.html
Copyright © 2011-2022 走看看