前端项目打包优化


前言

一个umijs项目,打包后发现体积过大,想优化, 看到各种博客上的优化手段是基于webpack的,于是我花了几天把项目转成webpack5的, 优化打包后比原来还大.... 最终还是在原来的umijs基础上进行了优化.

打包分析

umi项目在package.json加一个脚本语句 "analyze": "cross-env ANALYZE=1 umi build", 执行yarn analyze 即可在ANALYZE server上得到依赖包分析图

 "scripts": {
    "start": "cross-env UMI_ENV=dev umi dev",
    "build": "cross-env UMI_ENV=prod umi build",
    "analyze": "cross-env ANALYZE=1 umi build",
    "postinstall": "umi generate tmp",
    "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
    "test": "umi-test",
    "test:coverage": "umi-test --coverage"
  },

webpack需要安装 webpack-bundle-analyzer 插件 并在配置文件中配置 new BundleAnalyzerPlugin().
此图是优化后的

针对性优化(antd echart lodash momentjs)

经过分析发现, antd echart lodash momentjs四个依赖包占的体积最大

antd

umijs对antd组件库有良好支持, 使用插件集@umijs/preset-react或@umijs/plugin-antd整合antds组件库就自动是按需引入, 在webpack下需要使用bebel插件 babel-plugin-import 并在webpack.config.js(这个更靠谱)或babelrc配置

echart

echartc5的按需引入在官网有示例 实例

// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。 
import * as echarts from 'echarts/core';
// 引入柱状图图表,图表后缀都为 Chart
import { BarChart } from 'echarts/charts';
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  DatasetComponentOption,
  TransformComponent
} from 'echarts/components';
// 标签自动布局,全局过渡动画等特性
import { LabelLayout, UniversalTransition } from 'echarts/features';
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from 'echarts/renderers';

// 注册必须的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  BarChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer
]);

// 接下来的使用就跟之前一样,初始化图表,设置配置项
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption({
  // ...
});

实测对项目整体打包体积的优化用处不大, 采取了定制echarts.min.js的方式 定制地址
echarts4的体积比echart5小, 页面生成echarts.min.js加入到项目的public文件夹
在document.ejs引入

<script src="<%= context.config.publicPath +'echarts.min.js'%>" > </script>

在.umirc.js添加配置

 externals: {
    echarts: 'echarts'
  },

使用示例: echart组件封装

import React, { useEffect, useState, useRef } from 'react'
import echarts from 'echarts'

const Echarts = (props) => {
  const { option } = props
  const [chart, setChart] = useState()
  const domRef = useRef()

  useEffect(() => {
    const instance = echarts.init(domRef.current)
    const chartResize = () => {
      instance.resize()
    }
    setChart(instance)
    window.addEventListener('resize', chartResize)
    return () => {
      window.removeEventListener('resize', chartResize)
    }
  }, [])
  useEffect(() => {
    if (chart) {
      chart.setOption(option)
    }
  }, [option])
  return <div ref={domRef} style={{ height: '100%', width: '100%' }} />
}

export default Echarts

lodash

 代码中的全部引入改为部分引入  
```
import _ from 'lodash'
改为
import { extend, omit, difference } from 'lodash'
```

devDependencies中安装两个插件 babel-plugin-lodash 和 lodash-webpack-plugin
.umirc.js中配置

const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
export default defineConfig({
 ...
  extraBabelPlugins: ['lodash'],
  chainWebpack: (config, { webpack }) => {
    if (process.env.NODE_ENV === 'production') {  // 生产模式开启
      config.plugin('LodashModuleReplacementPlugin').use(
        new LodashModuleReplacementPlugin()
      ); // 压缩lodash
    }
  },
 })

momentjs

moment的体积也是很大,使用webpack.IngorePlugin插件忽略其locale能很好的压缩体积
.umirc.js中配置

const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
export default defineConfig({
 ...
  extraBabelPlugins: ['lodash'],
  chainWebpack: (config, { webpack }) => {
    if (process.env.NODE_ENV === 'production') {  // 生产模式开启
      config.plugin('igncore').use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/))
      config.plugin('LodashModuleReplacementPlugin').use(
        new LodashModuleReplacementPlugin()
      ); // 压缩lodash
    }
  },
 })

也可以使用dayjs替换moment, dayjs体积非常小. antd组件库有使用到moment,也需要进行替换 官方文档操作说明


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM