Compilation Pipeline
Overview
Nexa's SFC compiler transforms .nexa files into plain JavaScript through a three-stage pipeline:
.nexa file
↓
parse() → { template, script, style }
↓
transform() → { templateAST, transformedAST, scopedCSS }
↓
codegen() → JavaScript + CSSStage 1: Parse
The SFC parser extracts <template>, <script>, and <style> sections using regex-based section detection. The template is further parsed into an AST of elements, text nodes, expressions, slots, and directives.
Stage 2: Transform
The template AST is transformed to prepare it for code generation:
v-ifandv-showdirectives are extractedv-forexpressions are parsed into item/index/list- Scoped style selectors are prefixed with a unique
data-v-xxxattribute - Dynamic attributes (
:attr) and event bindings (@event) are normalized
Stage 3: Codegen
The transformed AST is emitted as JavaScript render functions. A component like:
html
<template>
<div class="counter">
<p>Count: {{ count.value }}</p>
<button @click="increment">+1</button>
</div>
</template>Compiles to:
js
export default defineComponent({
setup(props, { emit, slots }) {
return { count, increment }
},
render(ctx) {
const { count, increment } = ctx
return h('div', { class: 'counter' }, [
h('p', null, ['Count: ', count.value]),
h('button', { onClick: increment }, ['+1']),
])
},
})Vite Plugin & HMR
The vite-plugin-nexa integrates the compiler into Vite's dev server and build pipeline. It handles:
- Compilation: Transforming
.nexafiles during the dev server's request phase. - HMR Bridge: Injects a lightweight HMR client into components.
- Hot Updates: Using the
handleHotUpdatehook, it identifies changes and triggers surgical updates.
How HMR Works in Nexa
When a .nexa file is updated:
- Vite notifies the browser that the module has changed.
- The browser downloads the new version of the component.
- The injected HMR code calls
reloadComponent(hmrId, newDefinition). - The Nexa Runtime finds all active instances of that component and updates their
renderfunction. - A re-patching is triggered without re-running
setup(), preserving the component's state (Signals).