体积瘦身!TinyVue 打包优化与按需加载实践
你有没有这样的经历------项目刚启动时,打包体积只有几百KB,轻轻松松上线。随着功能越来越多,组件库像吃货一样疯狂吞体积,突然有一天 npm run build 的输出让你血压飙升:"这玩意儿怎么比我还胖?"
别慌,今天咱们就来聊聊怎么给 TinyVue 做"减肥手术",让它从"重量级选手"变成"轻量级冠军"。
先看看问题出在哪
TinyVue 是一个同时支持 Vue 2 和 Vue 3 的企业级组件库,组件丰富是好事,但如果你把整个组件库一股脑儿全引进来,打包体积就会像过年吃饺子一样------一发不可收拾。
完整引入的方式:
js
import { Button, Input, Grid, Tree, Modal, DatePicker, ... } from '@opentiny/vue'
看起来很方便,但你实际上可能只用了其中5个组件,却把50多个组件的代码都塞进了产物包。这就像你只想吃一根薯条,却把整桶全买了------钱包很受伤。
方案一:自动导入------懒人的福音(强烈推荐)
如果你跟我一样,写代码时最讨厌手动 import(毕竟 Ctrl+C 和 Ctrl-V 才是程序员的真爱),那自动导入方案绝对是你的心头好。
配置步骤如下:
bash
npm install @opentiny/unplugin-tiny-vue unplugin-auto-import unplugin-vue-components -D
然后在 vite.config.js 中配置:
js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import TinyVue from '@opentiny/unplugin-tiny-vue/vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [TinyVue()]
}),
Components({
resolvers: [TinyVue()]
})
]
})
这样配置之后,你在模板中直接写 <tiny-button>、<tiny-input> 就行,不需要手动 import,插件会自动帮你搞定。就像请了个秘书,你只需要说"我要按钮",秘书就把按钮递到你手上。
更妙的是,只引入你用到的组件,没用到的连打包的机会都没有------tree-shaking 的最佳拍档。
方案二:按需加载插件------精准裁剪
如果你觉得自动导入太"全自动"了,想要更多控制权,TinyVue 还提供了专门的按需加载插件 @opentiny/vue-vite-import:
bash
npm install @opentiny/vue-vite-import -D
js
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import TinyVueImport from '@opentiny/vue-vite-import'
export default defineConfig({
plugins: [
vue(),
TinyVueImport([
{
libraryName: '@opentiny/vue',
// 支持三种模式:pc | mobile | mobile-first
customStyle: 'pc'
}
])
]
})
注意那个 customStyle 参数------TinyVue 同时支持 PC端、移动端和移动优先三种模式。如果你的项目是 PC端的(大多数企业项目都是),设为 'pc' 就只会加载 PC端样式,移动端的代码直接被摇掉。
这就像去自助餐厅,你只拿自己爱吃的菜,不碰那些看一眼就饱的沙拉------体积瞬间缩减。
方案三:TINY_MODE 配置------釜底抽薪
上面说的 customStyle 是样式层面的裁剪,但如果你想在逻辑层面也砍掉移动端代码,就需要用到 TINY_MODE 环境变量。
非移动端项目在 Vite 配置中这样写:
js
// vite.config.js
export default defineConfig({
define: {
'process.env': {
TINY_MODE: 'pc'
}
}
})
Webpack 项目则在 webpack.config.js 中配置:
js
// webpack.config.js
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.TINY_MODE': JSON.stringify('pc')
})
]
}
这样一来,TinyVue 内部所有涉及移动端判断的代码分支(类似 if (mode === 'mobile')),在打包阶段就会被静态分析工具直接裁掉。这不是减肥,这是截肢------把不需要的部分彻底断掉。
效果非常显著,尤其对于大型项目来说,光是砍掉移动端那套逻辑和样式,体积就能缩减一大截。
方案四:单组件引入------手动控刀
如果你不想用插件,也可以手动单组件引入,虽然麻烦一点,但效果同样出色:
js
// 只引入 Button 组件
import TinyButton from '@opentiny/vue-button'
import '@opentiny/vue-button/theme' // 引入样式
// 在组件中使用
export default {
components: { TinyButton }
}
html
<template>
<tiny-button type="primary">点我</tiny-button>
</template>
这种方式的优点是极度精准------你引入什么就打包什么,没有任何多余代码。缺点是每个组件都要手动写两行 import,容易累到手抽筋。
但对比完整引入:
js
import TinyVue from '@opentiny/vue' // 把整个组件库全搬进来
手动单组件引入至少能让体积减少 60%~80%。就像从"全屋搬家"变成"只带必需品"------行李箱从三个变成一个。
方案五:tiny-vue-simple.mjs------精选套餐
从 v3.17.0 开始,TinyVue 提供了一个新的选择:tiny-vue-simple.mjs。
这不是完整组件库,而是常用组件的精选集合------把最频繁使用的组件打包在一起,体积比完整版小得多。
js
// 使用精选集合
import { Button, Input, Select, Table, Form } from '@opentiny/vue/simple'
如果你项目用的组件都在这个精选集合里,直接用它就行,不用再折腾按需加载。就像点餐厅的"人气TOP10套餐"------不用自己一个个选,店家已经帮你挑好了最热门的。
pnpm 工程的特殊注意事项
pnpm 的严格依赖管理机制会导致 TinyVue 组件找不到依赖------这就像你把食材锁在不同房间,厨师(组件)做饭时发现酱油(依赖)隔壁才有,但门锁着不让进。
解决方案有两种:
方案A:在 package.json 中声明每个组件依赖
json
{
"dependencies": {
"@opentiny/vue-button": "~3.12.0",
"@opentiny/vue-input": "~3.12.0",
"@opentiny/vue-grid": "~3.12.0",
"@opentiny/vue-common": "~3.12.0",
"@opentiny/vue-renderless": "~3.12.0",
"@opentiny/vue-theme": "~3.12.0"
}
}
方案B:在 .npmrc 中提升所有 opentiny 包
ini
# .npmrc
public-hoist-pattern[]=@opentiny/*
方案B更简洁,直接把所有 opentiny 相关包提升到根目录的 node_modules,让任何组件都能找到自己的依赖。就像把所有食材放在开放式厨房------谁需要随时取用。
版本号的小窍门
推荐在 package.json 中使用 ~ 前缀而非 ^ 前缀:
json
{
"dependencies": {
"@opentiny/vue": "~3.12.0"
}
}
~3.12.0 表示允许 3.12.x 的版本更新,但不允许跨到 3.13.0。而 ^3.12.0 允许跨小版本升级,可能引入意想不到的变化。
这就像你同意朋友帮你点外卖,但只允许换同一家餐厅的不同口味,不允许换餐厅------稳妥。
实战效果对比
在一个典型的中大型项目中(使用了约20个 TinyVue 组件),各种方案的打包体积对比大致如下:
| 引入方式 | 打包体积(估算) | 便捷性 | 推荐指数 |
|---|---|---|---|
| 完整引入 | ~2MB+ | 最高 | ⭐ |
| 手动单组件引入 | ~400-600KB | 低 | ⭐⭐⭐ |
| 按需加载插件 | ~400-600KB | 中 | ⭐⭐⭐⭐ |
| 自动导入(推荐) | ~400-600KB | 最高 | ⭐⭐⭐⭐⭐ |
| tiny-vue-simple.mjs | ~800KB左右 | 高 | ⭐⭐⭐⭐ |
加上 TINY_MODE 配置裁掉移动端代码后,体积还能进一步缩减 20%~30%。
总结一下
给 TinyVue 做体积瘦身,核心思路就三条:
- 只引入需要的组件------自动导入最省心,手动引入最精准
- 裁掉不需要的模式------TINY_MODE + customStyle 双管齐下砍掉移动端
- 合理管理依赖 ------pnpm 工程注意提升策略,版本号用
~更稳妥
做到这三条,你的打包体积就能从"胖子"变成"瘦子",用户打开页面的速度也能快上一个档次。毕竟,谁愿意等一个胖子跑完马拉松呢?
下次打包体积又膨胀了,别急着骂组件库------先看看自己是不是又把整个自助餐厅搬回家了。
🏠 TinyVue 官网:opentiny.design 📦 GitHub 仓库:github.com/opentiny/ti...