体积瘦身TinyVue打包优化与按需加载实践

体积瘦身!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 做体积瘦身,核心思路就三条:

  1. 只引入需要的组件------自动导入最省心,手动引入最精准
  2. 裁掉不需要的模式------TINY_MODE + customStyle 双管齐下砍掉移动端
  3. 合理管理依赖 ------pnpm 工程注意提升策略,版本号用 ~ 更稳妥

做到这三条,你的打包体积就能从"胖子"变成"瘦子",用户打开页面的速度也能快上一个档次。毕竟,谁愿意等一个胖子跑完马拉松呢?

下次打包体积又膨胀了,别急着骂组件库------先看看自己是不是又把整个自助餐厅搬回家了。


🏠 TinyVue 官网:opentiny.design 📦 GitHub 仓库:github.com/opentiny/ti...

相关推荐
英勇无比的消炎药2 小时前
一套代码多端运行TinyVue响应式开发
vue.js·响应式设计
SwJieJie2 小时前
Webpack vs Vite 构建工程化实战(Vue 项目深度解析)
前端·vue.js·webpack·node.js
云水一下2 小时前
Vue.js从零到精通系列(八):项目实战——构建一个完整的电商后台管理系统
前端·javascript·vue.js
Csvn2 小时前
Vue3 响应式陷阱:解构赋值后页面不动了?Proxy 的"隐形成员"在搞鬼
前端·vue.js
i220818 Faiz Ul2 小时前
药店管理|基于springboot + vue药店管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·美食分享系统
daols883 小时前
vue vxe-table 复制数据到 Excel:支持带表头复制
vue.js·excel·vxe-table
代码不加糖15 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty15 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚16 小时前
软件测试期末考试
vue.js