Skip to content

Svelte 与 Vue 编译模型对比

Svelte 提供了一个有用的参考视角:

如果把更多工作继续前置到编译阶段,组件库和框架本身的边界会发生什么变化?

这对读 Vue 文档很有价值,因为 Vue 本身就强调“编译器不是附属品”。

但 Vue 和 Svelte 对“编译器应该做到哪一步”的答案并不相同。

基本差异

Vue 是“编译器 + 运行时”协作的框架。

Svelte 更接近“编译器把组件变成命令式更新代码”的框架。

这个差异会一路影响到源码写法、运行时模型和组件分发:

  • 为什么 Vue 仍然有清晰的运行时、VNode、组件实例和响应式系统。
  • 为什么 Svelte 经常被描述为“没有虚拟 DOM”。
  • 为什么 Svelte 组件源码和最后产物之间的距离更远。
  • 为什么 Vue 的模板、JSX、h() 可以汇聚到同一套运行时协议上。

差异表

维度VueSvelte
基本定位渐进式框架,编译期和运行期协作编译优先框架,把更多工作前置到构建阶段
模板结果编译成 render 函数、VNode 创建调用和 patch 提示编译成更直接的 DOM 创建与更新代码
运行时角色运行时仍然承担组件、响应式、调度和 DOM patch运行时更轻,很多组件更新逻辑已在编译期生成
更新心智响应式依赖触发 render effect,再 patch VNode状态赋值触发编译器生成的更新逻辑
优化方式Patch Flag、Block Tree、静态提升等编译提示配合运行时编译阶段尽量确定更新路径,减少通用 diff 成本
组件源码分发通常建议预编译为 JS / CSS / d.ts 再发布源码语法依赖 Svelte 编译器,分发时更要考虑消费方编译链

编译阶段做的事不同

Vue 编译模板时,会生成运行时能消费的渲染函数。这个渲染函数通常仍会创建 VNode,并把动态信息交给运行时 patch。

可以粗略理解为:

txt
Vue template
  -> render function
  -> VNode
  -> runtime patch
  -> DOM

Svelte 的路线更激进。它会在编译时分析组件里的模板、状态和赋值关系,生成更直接操作 DOM 的代码。

可以粗略理解为:

txt
Svelte component
  -> compiled imperative update code
  -> DOM

所以 Svelte 的“编译本质”不是把模板翻译成虚拟 DOM 协议,而是尽量把组件更新逻辑提前展开成具体代码。

响应式心智也不同

Vue 的响应式关键来自运行时依赖追踪:

  • 读取响应式数据时 track
  • 修改响应式数据时 trigger
  • 触发对应的 render effect、computed、watch 等副作用

Svelte 传统写法里的响应式更偏编译期分析:

  • 赋值语句是重要信号
  • $: 这类响应式声明会在编译阶段被分析
  • 编译器据此生成更新代码

这也是为什么 Svelte 看起来更像“写普通变量也能响应”,而 Vue 需要显式使用 ref()reactive() 或编译宏把响应式边界说明清楚。

对组件库设计的影响

Svelte 对组件库的启发,不只是“运行时更轻”,而是它会改变组件库作者对分发形态的判断:

  • 如果组件能力强依赖编译器,发布源码还是发布预编译产物就会更敏感。
  • 如果样式、状态和 DOM 更新都在编译阶段深度耦合,组件库的可组合边界要更早设计清楚。
  • 如果运行时抽象更少,组件库就更依赖清晰的源码约定和构建约定。

反过来看 Vue,组件库通常会更强调:

  • 保持 vue 为 peer dependency。
  • 输出稳定的 ESM / CJS / CSS / 类型声明。
  • 不把过多编译要求转嫁给消费方。
  • 用运行时协议承接模板、JSX、h() 等不同输入形式。

可借鉴点

  • 更激进的编译期优化策略
  • 组件样式隔离与输出体积之间的权衡
  • 对“框架成本”与“开发体验”的另一种平衡方式
  • 更早思考源码分发、预编译分发和消费方构建链之间的责任边界

对 Vue 的启发

它帮助我们反过来思考:

  • 哪些能力更适合在编译期解决
  • 哪些能力必须留在运行时
  • 组件库是否应该继续变得更“源码导向”
  • Vue 的“编译器 + 运行时”协作是不是比“纯编译优先”更适合渐进式采用

接着读

  1. Vue 编译器介绍
  2. 自定义编译时指令
  3. Vue 3 响应式系统的实现原理
  4. 组件的构建
  5. 下个时代的组件库

Released under the CC BY-NC-SA 4.0 License.