10.3 构建工具与生态:Vite 时代


文档摘要

10.3 构建工具与生态:Vite 时代 本节摘要:Vite 用"开发时原生模块按需编译、生产时 Rollup 打包"的双轨设计解决了 Webpack 时代的启动与热更新慢病。本节讲清它快的机理、常用配置项的心智模型、TypeScript 的接入姿势,以及一个现代 Vue 工程的标准目录与协作约定。 学习目标 阅读完本节,你应当能够: 解释 Vite 开发快而生产仍要打包的双轨原理; 看懂并按需修改 Vite 配置:别名、代理、分包; 在 Vue 工程里正确接入 TypeScript 而不流于形式; 按功能分层组织项目目录并落实团队约定。

10.3 构建工具与生态:Vite 时代

本节摘要:Vite 用"开发时原生模块按需编译、生产时 Rollup 打包"的双轨设计解决了 Webpack 时代的启动与热更新慢病。本节讲清它快的机理、常用配置项的心智模型、TypeScript 的接入姿势,以及一个现代 Vue 工程的标准目录与协作约定。

学习目标

阅读完本节,你应当能够:

  1. 解释 Vite 开发快而生产仍要打包的双轨原理;
  2. 看懂并按需修改 Vite 配置:别名、代理、分包;
  3. 在 Vue 工程里正确接入 TypeScript 而不流于形式;
  4. 按功能分层组织项目目录并落实团队约定。

一、Vite 为什么快

Webpack 开发模式的工作流:启动时从入口递归扫描、把所有模块打包成 bundle 再伺服——项目越大,冷启动越慢,改动一个文件也要经历模块重建链。Vite 的思路换轨:

开发时不打包。 启动只做入口分析(毫秒级);浏览器请求哪个模块,服务器现场编译哪个,原生 ES 模块按 import 关系按需加载。冷启动时间从"项目规模"变成"首屏模块数",热更新也精确到单模块失效。

生产时仍打包。 原生模块在网络上是瀑布式的(一个 import 一个请求),生产环境必须靠 Rollup 合并压缩与 tree-shaking——Vite 生产构建走 esbuild 预构建依赖加 Rollup 打包的组合。

预构建是中间的关键件:node_modules 里的依赖(常是 CommonJS)先被 esbuild 转成 ESM 并合并(把几百个小文件的依赖并成单文件,避免请求风暴),结果缓存起来,依赖不变不重建。理解这个三层结构(源码按需编译、依赖预构建、生产打包),配置报错时才有排查方位感。

二、配置的心智模型

日常会碰的配置就四类:

import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], // 插件:框架支持、压缩、检查都挂这里 resolve: { alias: { '@': '/src' } // 别名:import 深层模块不再 ../../../ }, server: { proxy: { '/api': { target: 'http://localhost:8080', // 代理:本地联调跨域的正解 changeOrigin: true } } }, build: { rollupOptions: { output: { manualChunks: { // 分包:大依赖独立成包利用缓存 vendor: ['vue', 'vue-router', 'pinia'], charts: ['echarts'] } } } } });

两条高频坑。代理配置改了必须重启开发服务器才生效(不是热更新的范围);manualChunks 切得过碎会让请求数暴涨,按"变化频率分层"切——框架层基本不变独立、图表库这类重组件独立、业务代码随发版变。

三、TypeScript 接入的正确姿势

Vue 3 源码本身用 TS 重写,类型推导在组合式 API 下尤其顺畅。接入的要点不在配置在写法:

import { ref, computed } from 'vue'; interface User { id: number; name: string; role: 'admin' | 'member'; } const user = ref<User | null>(null); // 泛型声明,user.value 自动带类型 const canEdit = computed(() => user.value?.role === 'admin'); function load(id: number): Promise<void> { return api.getUser(id).then((u) => { user.value = u; }); }

组件 props 的类型直接被 defineProps 泛型吃掉:

const props = defineProps<{ id: number; compact?: boolean }>();

真正要守的纪律是别用 any 装糊涂——接口层的类型定义一次,沿着数据流自然传播,比事后补类型便宜十倍。Volar 插件装上后,模板里的表达式也有类型检查,很多低级错误在编写期就划红线。

四、项目目录:按功能分层

两种流派的取舍先说结论:中小项目按类型分层够用,业务膨胀后按功能分模块

src/ ├── api/ 接口层:请求函数与类型定义,业务组件不直接碰请求库 ├── components/ 通用组件:跨业务复用 ├── composables/ 组合函数:逻辑复用(useSearch 等) ├── stores/ Pinia 仓库:按领域一个文件 ├── router/ 路由表与守卫 ├── views/ 页面组件:与路由对应 ├── utils/ 纯函数工具 └── main.ts 入口装配

按功能分模块是它在大项目里的演化形态——features/orders/ 下自含该领域的 api、components、store,业务边界物理隔离,删除一个模块就是删一个目录。分层的检验标准始终是耦合方向:api 层不许 import 组件、utils 不许 import 业务 store、依赖只能从上往下。

配套的工程化约定随手列出:代码风格交给格式化工具自动执行(不再人工评审缩进);提交前跑类型检查与单元测试(Vitest 对组合函数的测试不需要挂组件,普通函数式断言);接口类型与后端契约对齐(手写或由接口文档生成)。

五、技术选型的收束

生态全景在第 10.2 节的图里,这里只给决策收束:新项目无脑组合——Vue 3 加 Vite 加 Pinia 加 Vue Router 4 加 TypeScript 加 Vitest;老 Webpack 工程不必为迁移而迁移,构建工具的痛在大型冷启动场景才显著;SSR 需求直接上 Nuxt 而不是手搭(第 9 章的约束清单会吃掉你几周时间,Nuxt 已踩完这些坑)。

本节要点回顾

  • 双轨原理:开发按需编译免打包、生产 Rollup 照打包,预构建负责依赖转制合并;
  • 配置四类:插件、别名、代理(改动要重启)、分包(按变化频率切);
  • TS 姿势:接口类型定义一次自然传播,组合式 API 与泛型 props 是最顺的写法区;
  • 目录分层:类型分层起步、功能分模块演化,耦合方向单向是硬检验;
  • 选型收束:Vue3 加 Vite 加 Pinia 加 TS 是新项目默认解,SSR 需求走 Nuxt。

工具链就绪,最后一章收束为团队可执行的规范与安全清单。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U