本文档通过具体的项目代码示例,可视化展示 Vite 打包过程中每一步的代码转换,让你真正理解"代码是怎么变的"。
目录#
- 1. 项目结构示例
- 2. Vue SFC 文件的完整转换
- 3. TypeScript 文件的转换
- 4. CSS/SCSS 的处理流程
- 5. 静态资源的处理
- 6. 代码分割与 Chunk 生成
- 7. 最终产物结构
- 8. 完整构建流程图
1. 项目结构示例#
我们以一个典型的 Vue 3 + TypeScript 项目为例:
src/
├── main.ts # 入口文件
├── App.vue # 根组件
├── components/
│ ├── HelloWorld.vue # 普通组件
│ └── LazyComponent.vue # 懒加载组件
├── composables/
│ └── useCounter.ts # 组合式函数
├── styles/
│ ├── variables.scss # SCSS 变量
│ └── main.scss # 全局样式
├── assets/
│ ├── logo.png # 图片资源
│ └── icon.svg # SVG 图标
└── utils/
└── helpers.ts # 工具函数2. Vue SFC 文件的完整转换#
2.1 原始 Vue 文件#
<!-- src/components/HelloWorld.vue -->
<template>
<div class="hello-world">
<h1>{{ title }}</h1>
<p class="count">Count: {{ count }}</p>
<button @click="increment">+1</button>
<img :src="logoUrl" alt="Logo" />
</div>
</template>
<script setup lang="ts">
import { ref, computed } from "vue";
import { useCounter } from "@/composables/useCounter";
import logoUrl from "@/assets/logo.png";
interface Props {
title: string;
}
const props = defineProps<Props>();
const { count, increment } = useCounter();
const doubleCount = computed(() => count.value * 2);
</script>
<style scoped lang="scss">
@use "@/styles/variables" as *;
.hello-world {
padding: $spacing-md;
h1 {
color: $primary-color;
font-size: 24px;
}
.count {
color: #666;
}
button {
background: $primary-color;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background: darken($primary-color, 10%);
}
}
}
</style>2.2 阶段一:SFC 解析(@vitejs/plugin-vue)#
Vite 使用 @vue/compiler-sfc 将 .vue 文件拆分成三个部分:
// 解析后的 SFC 描述对象
{
filename: '/src/components/HelloWorld.vue',
source: '原始文件内容...',
template: {
type: 'template',
content: '<div class="hello-world">...</div>',
loc: { start: { line: 2 }, end: { line: 9 } },
attrs: {},
ast: { /* 模板 AST */ }
},
script: null, // 没有普通 script
scriptSetup: {
type: 'script',
content: "import { ref, computed } from 'vue'...",
loc: { start: { line: 11 }, end: { line: 23 } },
attrs: { setup: true, lang: 'ts' },
},
styles: [{
type: 'style',
content: '@use "@/styles/variables" as *;...',
loc: { start: { line: 25 }, end: { line: 50 } },
attrs: { scoped: true, lang: 'scss' },
scoped: true,
lang: 'scss'
}],
customBlocks: [],
cssVars: [],
slotted: false
}2.3 阶段二:Script 编译#
`
