CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue--compiler-core

Core compiler for Vue.js template compilation and transformation

Pending
Overview
Eval results
Files

transforms.mddocs/

Transform System

Vue Compiler Core's transform system provides a flexible plugin architecture for processing and modifying AST nodes. The system includes built-in transforms for Vue directives, structural elements, and optimizations, as well as extensibility for custom transforms.

Capabilities

Transform Context

The central context object that manages transformation state and provides utilities.

/**
 * Context object passed through all transformations
 */
interface TransformContext {
  /** Root AST node being transformed */
  root: RootNode;
  /** Map of runtime helpers to usage count */
  helpers: Map<symbol, number>;
  /** Set of component names referenced */
  components: Set<string>;
  /** Set of directive names referenced */
  directives: Set<string>;
  /** Array of hoisted expressions */
  hoists: (JSChildNode | null)[];
  /** Import statements needed */
  imports: ImportItem[];
  /** Cache for constant expressions */
  constantCache: WeakMap<TemplateChildNode, ConstantTypes>;
  /** Number of temporary variables */
  temps: number;
  /** Number of cached expressions */
  cached: number;
  /** Identifier tracking for scoping */
  identifiers: { [name: string]: number | undefined };
  /** Scope counters for different directive types */
  scopes: {
    vFor: number;
    vSlot: number;
    vPre: number;
    vOnce: number;
  };
  /** Current parent node */
  parent: ParentNode | null;
  /** Index of current node in parent's children */
  childIndex: number;
  /** Current node being processed */
  currentNode: RootNode | TemplateChildNode | null;
  /** Whether currently inside v-once */
  inVOnce: boolean;
  
  /** Add a runtime helper and return its name */
  helper(name: symbol): string;
  /** Remove a runtime helper */
  removeHelper(name: symbol): void;
  /** Get string representation of helper */
  helperString(name: symbol): string;
  /** Replace the current node */
  replaceNode(node: TemplateChildNode): void;
  /** Remove the current node */
  removeNode(node?: TemplateChildNode): void;
  /** Callback when node is removed */
  onNodeRemoved: (() => void) | undefined;
  /** Add identifiers to scope tracking */
  addIdentifiers(exp: ExpressionNode | string): void;
  /** Remove identifiers from scope tracking */
  removeIdentifiers(exp: ExpressionNode | string): void;
  /** Hoist an expression for static optimization */
  hoist(exp: string | JSChildNode | ArrayExpression): SimpleExpressionNode;
  /** Cache an expression */
  cache<T extends JSChildNode>(exp: T, isVNode?: boolean): CacheExpression | T;
}

/**
 * Creates a new transform context
 */
function createTransformContext(
  root: RootNode,
  options: TransformOptions
): TransformContext;

Transform Functions

Core functions for applying transformations to AST nodes.

/**
 * Traverses and transforms a single AST node and its children
 * @param node - AST node to process
 * @param context - Transform context
 */
function traverseNode(
  node: RootNode | TemplateChildNode,
  context: TransformContext
): void;

/**
 * Creates a structural directive transform
 * @param name - Directive name or pattern to match
 * @param fn - Transform function to apply
 * @returns Node transform function
 */
function createStructuralDirectiveTransform(
  name: string | RegExp,
  fn: StructuralDirectiveTransform
): NodeTransform;

Usage Examples:

import { 
  createTransformContext, 
  traverseNode, 
  createStructuralDirectiveTransform 
} from "@vue/compiler-core";

// Create transform context
const context = createTransformContext(ast, {
  nodeTransforms: [/* transforms */],
  directiveTransforms: {/* directive transforms */}
});

// Traverse and transform nodes
traverseNode(ast, context);

// Create custom structural directive transform
const customIfTransform = createStructuralDirectiveTransform(
  'custom-if', 
  (node, dir, context) => {
    // Transform logic here
  }
);

Transform Function Types

Type definitions for different kinds of transform functions.

/**
 * Node transform function signature
 */
type NodeTransform = (
  node: RootNode | TemplateChildNode,
  context: TransformContext
) => void | (() => void) | (() => void)[];

/**
 * Directive transform function signature
 */
type DirectiveTransform = (
  dir: DirectiveNode,
  node: ElementNode,
  context: TransformContext,
  augmentor?: (ret: DirectiveTransformResult) => DirectiveTransformResult
) => DirectiveTransformResult;

/**
 * Structural directive transform function signature
 */
type StructuralDirectiveTransform = (
  node: ElementNode,
  dir: DirectiveNode,
  context: TransformContext
) => void | (() => void);

/**
 * Hoist transform function signature
 */
type HoistTransform = (
  children: TemplateChildNode[],
  context: TransformContext,
  parent: ParentNode
) => void;

Built-in Directive Transforms

Pre-built transforms for Vue's core directives.

v-model Transform

Handles two-way data binding transformation.

/**
 * Transform for v-model directive
 */
const transformModel: DirectiveTransform;

Usage Examples:

// Template: <input v-model="value" />
// Transforms to: <input :modelValue="value" @update:modelValue="value = $event" />

// Custom v-model transform in directive transforms map
const directiveTransforms = {
  model: transformModel
};

v-on Transform

Handles event listener transformation.

/**
 * Transform for v-on directive
 */
const transformOn: DirectiveTransform;

Usage Examples:

// Template: <button v-on:click="handler" />
// Template: <button @click="handler" />
// Transforms to event listener binding

const directiveTransforms = {
  on: transformOn
};

v-bind Transform

Handles attribute and property binding.

/**
 * Transform for v-bind directive
 */
const transformBind: DirectiveTransform;

Usage Examples:

// Template: <div v-bind:class="classes" />
// Template: <div :class="classes" />
// Transforms to property binding

const directiveTransforms = {
  bind: transformBind
};

No-op Transform

Placeholder transform for directives that don't need processing.

/**
 * No-operation directive transform
 */
const noopDirectiveTransform: DirectiveTransform;

Structural Directive Processing

Functions for handling structural directives like v-if and v-for.

v-if Processing

Handles conditional rendering transformation.

/**
 * Processes v-if structural directive
 * @param node - Element node with v-if
 * @param branch - If branch node
 * @param context - Transform context
 */
function processIf(
  node: ElementNode,
  branch: IfBranchNode,
  context: TransformContext,
  processCodegen?: (node: IfNode, branch: IfBranchNode, isRoot: boolean) => () => void
): () => void;

Usage Examples:

// Template: <div v-if="condition">Content</div>
// Processes into conditional render structure

import { processIf } from "@vue/compiler-core";

// Used within node transforms to handle v-if
const ifTransform: NodeTransform = (node, context) => {
  if (node.type === NodeTypes.ELEMENT && hasDirective(node, 'if')) {
    return processIf(node, branch, context);
  }
};

v-for Processing

Handles list rendering transformation.

/**
 * Processes v-for structural directive
 * @param node - Element node with v-for
 * @param context - Transform context
 */
function processFor(
  node: ElementNode,
  context: TransformContext,
  processCodegen?: (forNode: ForNode, child: ElementNode, context: TransformContext) => (() => void) | undefined
): (() => void) | undefined;

/**
 * Creates parameters for v-for loops
 * @param parseResult - Parsed v-for expression
 * @param context - Transform context
 */
function createForLoopParams(
  parseResult: ForParseResult,
  context: TransformContext
): ExpressionNode[];

Usage Examples:

// Template: <li v-for="item in items" :key="item.id">{{ item.name }}</li>
// Processes into render list structure

import { processFor, createForLoopParams } from "@vue/compiler-core";

// Used within node transforms to handle v-for
const forTransform: NodeTransform = (node, context) => {
  if (node.type === NodeTypes.ELEMENT && hasDirective(node, 'for')) {
    return processFor(node, context);
  }
};

Expression Processing

Functions for handling JavaScript expressions within templates.

Expression Transform

Main transform for processing JavaScript expressions.

/**
 * Node transform for JavaScript expressions
 */
const transformExpression: NodeTransform;

/**
 * Processes JavaScript expressions in templates
 * @param node - Expression node to process
 * @param context - Transform context
 * @param asParams - Whether to treat as function parameters
 * @param asRawStatements - Whether to treat as raw statements
 * @param localVars - Local variable context
 */
function processExpression(
  node: SimpleExpressionNode,
  context: TransformContext,
  asParams?: boolean,
  asRawStatements?: boolean,
  localVars?: Record<string, number>
): ExpressionNode;

/**
 * Stringifies expressions for static analysis
 * @param exp - Expression to stringify
 */
function stringifyExpression(exp: ExpressionNode | string): string;

Usage Examples:

import { transformExpression, processExpression } from "@vue/compiler-core";

// Include in node transforms for expression processing
const nodeTransforms = [
  transformExpression, // Handles {{ expressions }} and directive values
  // ... other transforms
];

// Manual expression processing
const processedExp = processExpression(simpleExp, context);

Slot Processing

Functions for handling Vue slots and scoped slots.

Slot Building

Functions for constructing slot expressions.

/**
 * Builds slot expressions from v-slot directives
 * @param node - Element node with slots
 * @param context - Transform context
 * @param buildSlotFn - Function to build individual slots
 */
function buildSlots(
  node: ElementNode,
  context: TransformContext,
  buildSlotFn?: SlotFnBuilder
): SlotsExpression;

/**
 * Function signature for building individual slot functions
 */
type SlotFnBuilder = (
  slotProps: ExpressionNode | undefined,
  slotChildren: TemplateChildNode[],
  loc: SourceLocation
) => FunctionExpression;

/**
 * Processes slot outlet elements (<slot> tags)
 * @param node - Slot outlet node
 * @param context - Transform context
 * @returns Slot name and props information
 */
function processSlotOutlet(
  node: SlotOutletNode,
  context: TransformContext
): { slotName: string | ExpressionNode; slotProps: PropsExpression | undefined };

/**
 * Tracks v-for scope variables in slots
 */
const trackVForSlotScopes: NodeTransform;

/**
 * Tracks slot scope variables
 */
const trackSlotScopes: NodeTransform;

Usage Examples:

import { buildSlots, trackVForSlotScopes, trackSlotScopes } from "@vue/compiler-core";

// Include slot tracking in transforms
const nodeTransforms = [
  trackSlotScopes,
  trackVForSlotScopes,
  // ... other transforms
];

// Build slots for component
const slots = buildSlots(componentNode, context);

Element and Component Processing

Functions for processing element nodes and component resolution.

Element Transform

Main transform for element processing.

/**
 * Main node transform for element processing
 */
const transformElement: NodeTransform;

/**
 * Resolves component names to runtime references
 * @param node - Element node
 * @param context - Transform context
 * @param ssr - Whether in SSR mode
 */
function resolveComponentType(
  node: ElementNode,
  context: TransformContext,
  ssr?: boolean
): string | symbol;

/**
 * Builds props expression from attributes and directives
 * @param node - Element node
 * @param context - Transform context
 * @param props - Props array to process
 * @param ssr - Whether in SSR mode
 */
function buildProps(
  node: ElementNode,
  context: TransformContext,
  props?: ElementNode['props'],
  ssr?: boolean
): PropsExpression | undefined;

/**
 * Builds directive arguments array
 * @param props - Props array containing directives
 * @param context - Transform context
 */
function buildDirectiveArgs(
  props: ElementNode['props'],
  context: TransformContext
): DirectiveArguments | undefined;

/**
 * Type for props expressions
 */
type PropsExpression = ObjectExpression | CallExpression | ExpressionNode;

Slot Outlet Processing

Function for processing slot outlet elements.

/**
 * Processes slot outlet elements (<slot>)
 * @param node - Slot outlet element
 * @param context - Transform context
 */
function processSlotOutlet(
  node: ElementNode,
  context: TransformContext
): void;

Static Analysis

Function for determining constant types for optimization.

/**
 * Determines if a node can be statically analyzed and cached
 * @param node - AST node to analyze
 * @param context - Transform context
 */
function getConstantType(
  node: TemplateChildNode | TemplateChildNode[],
  context: TransformContext
): ConstantTypes;

Transform Result Types

Types for transform function results.

/**
 * Result of directive transform
 */
interface DirectiveTransformResult {
  /** Generated props */
  props: Property[];
  /** Whether this directive needs runtime */
  needRuntime?: boolean | symbol;
  /** SSR-specific properties */
  ssrTagParts?: TemplateLiteral['elements'];
}

/**
 * Import item for transform context
 */
interface ImportItem {
  /** Expression to import */
  exp: string | ExpressionNode;
  /** Path to import from */
  path: string;
}

Usage Patterns

Custom Node Transform

import { type NodeTransform, NodeTypes } from "@vue/compiler-core";

const customTransform: NodeTransform = (node, context) => {
  if (node.type === NodeTypes.ELEMENT && node.tag === 'custom-element') {
    // Transform custom elements
    node.tag = 'div'; // Replace with div
    return () => {
      // Exit function called after children are processed
      console.log('Custom element processed');
    };
  }
};

Custom Directive Transform

import { type DirectiveTransform } from "@vue/compiler-core";

const customDirectiveTransform: DirectiveTransform = (dir, node, context) => {
  if (dir.name === 'custom') {
    return {
      props: [
        // Generate props for the directive
        createObjectProperty('customProp', dir.exp || createSimpleExpression('true', true))
      ]
    };
  }
  return { props: [] };
};

Install with Tessl CLI

npx tessl i tessl/npm-vue--compiler-core

docs

ast-types.md

compilation.md

error-handling.md

index.md

transforms.md

utilities.md

tile.json