886 字
4 分钟
解决Vite打包和压缩后文件过大的问题

有时候我们打包vue项目的时候文件过大,如下所示:

dist/assets/index-DTbUeroO.js              1,861.42 kB │ gzip:   472.39 kB
dist/assets/index-B0ZUR7nd.js              3,782.18 kB │ gzip: 1,064.85 kB

vite build之后显示的 index-xxxx.js 文件是打包和压缩后的“代码块”(Chunk),它将多个你的源代码文件和第三方库合并在了一起。因此,你无法直接从这个文件名看出是哪些源文件导致的。 不过,我们有非常好的工具来分析它。

最推荐的方法是使用 rollup-plugin-visualizer。这个插件会在你每次 build 项目时,生成一个直观的、可交互的HTML文件,用图表清晰地展示出每个打包块(Chunk)中包含了哪些模块,以及每个模块所占的大小。

1、 安装依赖#

在你的项目根目录下,打开终端并运行以下命令来安装 rollup-plugin-visualizer:

npm install -D rollup-plugin-visualizer
# 或者使用 yarn
# yarn add -D rollup-plugin-visualizer
# 或者使用 pnpm
# pnpm add -D rollup-plugin-visualizer

2、配置 vite.config.js#

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { visualizer } from 'rollup-plugin-visualizer' // 1. 导入export default defineConfig({
plugins: [
vue(),
// 2. 添加 visualizer 插件
visualizer({
open: true, // 在默认浏览器中自动打开报告
gzipSize: true, // 显示 gzip 后的大小
brotliSize: true, // 显示 brotli 后的大小
filename: 'stats.html', // 分析报告的名称 可以生成到  'dist/stats.html dist目录下面
}),
],
// ... 其他配置
})

3、重新构建后打开stats.html#

这个页面看起来像一个矩形树图(Treemap),其中:最大的矩形块 代表你的两个大文件 (index-B0ZUR7nd.js 和 index-DTbUeroO.js)。在这些大矩形块内部,面积越大的小矩形,就代表占用空间越大的库或代码模块。将鼠标悬停在任何一个矩形上,你都可以看到它的详细信息,包括:

文件路径: 指向 node_modules 里的某个库,或者 src 目录下的某个业务文件。 大小: 它在整个包里所占的原始大小和压缩后的大小。

4、根据分析结果,常见的“元凶”和解决方案#

通过 stats.html 分析后,你很可能会发现以下几种情况:

  1. 某个第三方库体积过大 元凶示例: ECharts, Lodash, Moment.js, Ant Design Vue/Element Plus (全量引入)。 解决方案: 按需引入: 对于像 ECharts 或 UI 库,确保你使用了官方推荐的按需引入(On-demand Import)方式,而不是在 main.js 中全量 import 和 use。例如,使用 unplugin-vue-components 和 unplugin-auto-import 插件可以为 Element Plus/Ant Design Vue 等实现完美的按需引入。 替换为更轻量的库: Moment.js 是一个经典的例子,它体积很大且不再维护,可以考虑用 Day.js (API 兼容性高) 或 date-fns (更现代) 来替代。 正确地 Tree-shaking: 确保你引入的库是支持 Tree-shaking 的。例如,引入 Lodash 时,使用 import { debounce } from ‘lodash-es’ 而不是 import { debounce } from ‘lodash’,因为 lodash-es 是 ES Module 版本,更利于打包工具进行摇树优化。

  2. 路由页面没有使用懒加载

    表现: 在 stats.html 中,你会看到 src/views 或 src/pages 下的多个页面组件被打包进了主 index.js 文件。 解决方案: 在 vue-router 中使用动态导入(懒加载)来切分代码。

    修改前 (全部打包进主文件):

    import About from '../views/About.vue'
    const routes = [{ path: '/about', component: About }]

    修改后 (访问 /about 路由时才加载):

    const routes = [{
    path: '/about',
    component: () => import('../views/About.vue') // 使用动态 import()
    }]

    这样,About.vue 和它的依赖会被打包成一个独立的小文件,只有在用户访问 /about 页面时才会被下载。

解决Vite打包和压缩后文件过大的问题
https://www.liyunhe.cn/posts/frontend/rollup-plugin-visualizer/
作者
一心
发布于
2024-03-03
许可协议
CC BY-NC-SA 4.0