基于antd3.x项目的打包优化

2,283 阅读2分钟

记一次组件优化,本次优化基于项目使用antd@3.24.0

1.webpack-bundle-analyzer

作用:

用来可视化打包后的,各个文件大小,便于找到主要的优化项。

使用方式:

import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';

...
// webpack config
plugins: [
  new BundleAnalyzerPlugin({ analyzerPort: 8919 })
],

2.按需引入antd

看上面的打包分析,首先优化antd的组件引入。

原因: 目前是全部引入的状态。

解决方案:

// webpack config

module: {
  rules: [
    {
          test: /\.(jsx?|tsx?)$/,
          ...
          use: [
            {
              loader: 'babel-loader',
              options: {
                ...
                plugins: [ 
                  [require('babel-plugin-import'), { libraryName: "antd-mobile", style: true }],
                  
                  // 以下新增:
                  [require('babel-plugin-import'), { libraryName: "antd", style: true }, 'babek-plugin-import-antd'], // 新增,因为用了同样的插件,所以要传入第三个参数作为别名
                ]
              }
            },
          ]
        }
  ]
}

效果对比: 打包antd引入的大小由 2.17M 降至 498K

修改前打包

修改后打包

3.按需引入@ant-design-icon

原因:

如果使用到antd-icon,整个icon文件就都会打包进来。

该项目中虽然并没有使用到icon,但仍然被打包了进来。

是因为我们使用的组件中有用到icon。

通过查代码发现,<Select />组件有用到一个默认的icon-down。

那我们就单独写一个出口文件替换@ant-design/icons/lib/dist,导出我们需要的icon。

解决方案:

// webpack打包文件
resolve: {
      extensions: ['.js', '.jsx', '.json', '.less', '.ts', '.tsx'],
      alias: {
        ...
        // 以下新增,主要是在引入icon的时候将引入文件替换为我们自己写的一个文件,里面只引入我们想要的icon
        '@ant-design/icons/lib/dist$': PathUtils.uniformResolve(componentDir, 'icons.js')
      }
    },
// icons.js
// 这里重新定义__esModule字段的原因是因为,在antd-icon的加载逻辑中,有Object.keys()去遍历引入的icon文件,__esModule在我们这种改法中成为了可枚举的值,所以重新定义,防止报错
Object.defineProperty(exports, "__esModule", { value: true, enumerable:false });

export {
  default as DownOutline
} from '@ant-design/icons/lib/outline/DownOutline';

效果对比:

打包antd-icon的引入由548K将为20K

修改前打包

修改后打包

4.压缩moment.js

原因: moment.js也是antd中引入的库,即使我们使用按需引入,也没有将这个库打掉。

moment大的主要原因是因为里面有各种语言包,我们只留中文,其他都打掉。

解决方案:

// webpack配置
import webpack from 'webpack';

plugins: [
  new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/),
]

效果对比: moment从672K降到174K

修改前打包

修改后打包

5.特别大的less文件

原因:

本地的less文件特别大的原因主要是因为,为了重置antd主题样式。引入了antd库的两个less文件

其他问题点:

这种全局覆盖的写法,在没有其他使用antd项目引入的情况下,是可行的。

这个项目因为是个H5编辑平台的组件,因为H5编辑平台也同样使用antd,就会在插入组件的时候,将平台代码冲掉。平台的主题颜色也会被组件的主题色覆盖。

所以一是建议在组件开发中使用antd-mobile,二是在使用全局样式覆盖的时候,要注意,外面套一层独特的class,防止覆盖。

解决方案:

因为这个项目使用的组件较少,主要是表单组件,我就采用了手工写样式,去进行主题色的覆盖,将上面三个less全都去掉。

效果:

两个less文件由914K降到9K

修改前打包:

修改后打包:

6.前后对比 整体index.js大小由7.65M降为3.46M

修改前:

修改后: