当前位置: 首页 > 工具软件 > library-app > 使用案例 >

create-react-app使用dllplugin抽取antd作为公共模块

有翰海
2023-12-01

首先说说,为什么要使用dllplugin?
在项目开发中,我们会遇到很多的依赖,体积不小,而且他们都是公共模块,基本上不会有变动,所以考虑是不是可以把这部分公共的模块抽取出来,作为静态的资源,不需要每次都打包这块
虽然有CommonsChunkPlugin插件可以抽取公共模块,但是有如下缺点

  1. 每次打包都会重新构建公共模块
  2. 只要其中的模块有微小的变动,打包出来的公共文件就不一样,简单说,换台机器,同样是vendor.js,但是文件的内容是不一样的,每次发布,会增加cdn服务器的压力

于是dllplugin横空出世,它可以抽取你想要分离的公共模块生成一个js文件,然后在以后的开发和打包的过程中,都可以直接用预先编译好的js文件,也就是说,公共的依赖,不会每次都打包

使用如下

  1. 在创建文件config/webpack.config.dll,内容如下

    const path = require('path')
    const webpack = require('webpack')
    const paths = require('./paths')
    const getClientEnvironment = require('./env')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    const publicPath = paths.servedPath
    const publicUrl = publicPath.slice(0, -1)
    const env = getClientEnvironment(publicUrl)
    
    module.exports = {
      entry: {
        vendor: [
          'antd'
        ]
      },
      output: {
        path: paths.appPublic,
        filename: 'static/js/[name].js',
        library: '[name]_library', // same with webpack.DllPlugin name option
        publicPath: publicPath
      },
      plugins: [
        new webpack.DllPlugin({
          path: path.resolve(paths.appPublic, 'static/js/[name]-manifest.json'),
          name: '[name]_library',
          context: paths.appPublic
        }),
      ]
    }
    
    
  2. 添加下面内容到webpack的plugins中

    new webpack.DllReferencePlugin({
      context: paths.appPublic,
      manifest: require(path.resolve(paths.appPublic, 'static/js/vendor-manifest.json'))
    }),
    
  3. 接下来就可以愉快的玩耍了,在开发和打包的过程中,在遇到antd组件的时候,都不会从nodemodule中取,而是直接从vendor.js里面取,构建速度从20s降低到11秒,提升不小,还可以配置其他,进一步提升

  4. 但是这样有一个问题,那就是打包出来的完整的antd文件很大,超过2M,所以继续优化,在dll中按需引入antd组件,然后再拆分react相关公共模块,完整如下

    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)
    
    module.exports = {
      entry: {
        vendor: [
          'antd/lib/form',
          'antd/lib/steps',
          'antd/lib/input',
          'antd/lib/row',
          'antd/lib/col',
          'antd/lib/button',
          'antd/lib/message',
          'antd/lib/icon',
          'antd/lib/cascader',
          'antd/lib/checkbox',
          'antd/lib/modal',
          'antd/lib/upload',
          'antd/lib/progress',
        ],
        cm1: [
          'react',
          'react-router-dom',
          'axios',
          'mobx',
          'mobx-react',
        ]
      },
      output: {
        path: paths.appPublic,
        filename: 'static/js/[name].shop.js',
        library: '[name]_library', // same with webpack.DllPlugin name option
        publicPath: publicPath
      },
      plugins: [
        new webpack.DllPlugin({
          path: path.resolve(paths.appPublic, 'static/js/[name]-manifest.json'),
          name: '[name]_library',
          context: paths.appPublic
        }),
      ]
    }
    
    
  5. webpack配置文件中plugin配置为

plugins: [
	new webpack.DllReferencePlugin({
      context: paths.appPublic,
      manifest: require(path.resolve(paths.appPublic, 'static/js/vendor-manifest.json'))
	}),
    new webpack.DllReferencePlugin({
      context: paths.appPublic,
      manifest: require(path.resolve(paths.appPublic, 'static/js/cm1-manifest.json'))
    }),
]

 类似资料: