前提

1. 同一个技术,都是react,或者都是vue。

2. 会webpack的dll配置。

 

思考

发现各个应用之间,第三方的包都是很多的,假如我们在主应用把这些包抽取出来,后面子应用引入,可以极大地减少子应用包的大小。

 

解决方法

一开始想使用externals来解决这问题,但是发现有一部分插件是不支持umd格式的,所以废弃了这个方案。

后面想到了webpack的dll打包,可以打包抽取不支持umd格式的插件,完美的解决了问题。

 

开始配置

直接上代码

const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');

// rc-系列插件
const rcs = ['rc-table', 'rc-select', 'rc-switch', 'rc-picker', 'rc-trigger', 'rc-tree-select', 'rc-menu', 'rc-field-form', 'rc-animate', 'rc-input-number', 'rc-tooltip', 'rc-virtual-list', 'rc-dialog', 'rc-pagination', 'rc-dropdown', 'rc-checkbox', 'rc-resize-observer']
module.exports = {
  mode: 'production',
  entry: {
    react: ['react', 'react-dom', 'react-router-dom'],
    rc: rcs,
    echarts: ['echarts'],
    xlsx: ['xlsx'],
    vendor: ['axios', 'moment']
  },
  output: {
    filename: 'dll.[name].js',
    path: path.resolve(__dirname, '../dll'),
    // 全局变量名称
    library: '[name]_library'
  },
  plugins: [
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: [path.resolve(__dirname, '../dll/**/*')]
    }),
    new webpack.DllPlugin({
      // 和library 一致,输出的manifest.json中的name值
      name: '[name]_library',
      // path 指定manifest.json文件的输出路径
      path: path.resolve(__dirname, '../dll/[name]-manifest.json'),
    }),
    new BundleAnalyzerPlugin(),
  ]
}

这里抽取了react+react-dom+react-router-dom为一个js,抽取了rc系列为一个js,抽取了echarts为一个js,抽取了xlsx为一个js,最后抽取axios+moment为一个js。
rc系列:antd的实现都是基于这些插件的。
xlsx:是一个读取exlcel表格数据的插件。
echarts:是百度的canvas插件。

 

出现的问题

1. 抽取了出来的rc.js中存在了react+react-dom+react-router-dom的代码,所以我们引入的时候就可以忽略这个react.js。
2. 引入的时候需要注意顺序,我是引入按照rc,xlsx,echarts,vendor顺序来的。记得rc需要放在第一步。(这个跟先引入react想法一致。)

 

主应用配置

  // 插件
  plugins: [
    // 导入'
    ...['vendor', 'echarts', 'xlsx', 'rc'].map(item => new Webpack.DllReferencePlugin({
      manifest: path.join(__dirname, `../dll/${item}-manifest.json`)
    })),
    ...['vendor', 'echarts', 'xlsx', 'rc'].map(item => new AddAssetHtmlWebpackPlugin({
      filepath: path.resolve(__dirname, `../dll/dll.${item}.js`),
      outputPath: 'static/dll',
      publicPath: `${pathName}/static/dll`,
      hash: true
    }))
  ].filter(Boolean),

dll的基本配置,注意按照顺序即可。(plugins是从后往前插入的,类似于递归,所以我们需要逆序)

 

子应用配置

// 插件
  plugins: [
    // 导入
    ...['vendor', 'echarts', 'xlsx', 'rc'].map(item => new Webpack.DllReferencePlugin({
      manifest: path.join(__dirname, `../../cstmr-paltform-base/dll/${item}-manifest.json`)
    }))
  ].filter(Boolean),

这里其实只需要使用DllReferencePlugin就可以了,告诉webpack来源,并且忽略打包即可。(记住这里忽略了dll.react.js
这里发现其实引用文件的路径是可以超出本项目的吗,这里就是跨项目了。

 

打包

打包完即可上线

Logo

前往低代码交流专区

更多推荐