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

utilities.mddocs/

Utilities and Helpers

Vue Compiler Core provides a comprehensive set of utility functions for AST manipulation, type checking, identifier analysis, and common compiler operations.

Capabilities

AST Node Utilities

Functions for working with and analyzing AST nodes.

/**
 * Type guard for static expression nodes
 * @param p - AST node to check
 * @returns True if node is a static simple expression
 */
function isStaticExp(p: JSChildNode): p is SimpleExpressionNode;

/**
 * Checks if a template child node is text or interpolation
 * @param node - Node to check
 * @returns True if node is TextNode or InterpolationNode
 */
function isText(node: TemplateChildNode): node is TextNode | InterpolationNode;

/**
 * Type guard for v-slot directive
 * @param p - Element prop to check
 * @returns True if prop is a v-slot directive
 */
function isVSlot(p: ElementNode['props'][0]): p is DirectiveNode;

Usage Examples:

import { isStaticExp, isText, isVSlot } from "@vue/compiler-core";

// Check if expression is static
if (isStaticExp(expression)) {
  console.log('Static value:', expression.content);
}

// Filter text nodes from children
const textNodes = element.children.filter(isText);

// Find v-slot directives
const slotDirectives = element.props.filter(isVSlot);

Element and Directive Queries

Functions for finding and working with element attributes and directives.

/**
 * Finds a directive on an element node
 * @param node - Element node to search
 * @param name - Directive name or pattern to match
 * @param allowEmpty - Whether to match directives without expressions
 * @returns Found directive node or undefined
 */
function findDir(
  node: ElementNode,
  name: string | RegExp,
  allowEmpty?: boolean
): DirectiveNode | undefined;

/**
 * Finds a prop or attribute on an element node
 * @param node - Element node to search
 * @param name - Prop/attribute name to find
 * @param dynamicOnly - Only match dynamic props (v-bind)
 * @param allowEmpty - Whether to match props without values
 * @returns Found prop/attribute or undefined
 */
function findProp(
  node: ElementNode,
  name: string,
  dynamicOnly?: boolean,
  allowEmpty?: boolean
): ElementNode['props'][0] | undefined;

/**
 * Checks if directive argument is static and matches name
 * @param arg - Directive argument to check
 * @param name - Name to match against
 * @returns True if argument is static and matches
 */
function isStaticArgOf(arg: DirectiveNode['arg'], name: string): boolean;

/**
 * Checks if element has dynamic key v-bind
 * @param node - Element node to check
 * @returns True if has dynamic v-bind:key
 */
function hasDynamicKeyVBind(node: ElementNode): boolean;

Usage Examples:

import { findDir, findProp, isStaticArgOf, hasDynamicKeyVBind } from "@vue/compiler-core";

// Find v-if directive
const ifDir = findDir(element, 'if');
if (ifDir) {
  console.log('v-if condition:', ifDir.exp?.content);
}

// Find class attribute or v-bind:class
const classProp = findProp(element, 'class');

// Check if v-on argument is static 'click'
if (isStaticArgOf(onDirective.arg, 'click')) {
  console.log('Static click handler');
}

// Check for dynamic key binding
if (hasDynamicKeyVBind(element)) {
  console.log('Element has dynamic key');
}

Component and Asset Utilities

Functions for working with Vue components and assets.

/**
 * Checks if tag name refers to a core Vue component
 * @param tag - Tag name to check
 * @returns Symbol for core component or void
 */
function isCoreComponent(tag: string): symbol | void;

/**
 * Converts name to valid asset identifier
 * @param name - Asset name to convert
 * @param type - Type of asset (component, directive, filter)
 * @returns Valid JavaScript identifier
 */
function toValidAssetId(name: string, type: 'component' | 'directive' | 'filter'): string;

Usage Examples:

import { isCoreComponent, toValidAssetId } from "@vue/compiler-core";

// Check for core components
const coreSymbol = isCoreComponent('Teleport');
if (coreSymbol) {
  console.log('Teleport is a core component');
}

// Convert component name to valid identifier
const componentId = toValidAssetId('my-component', 'component');
// Result: "_component_my_component"

const directiveId = toValidAssetId('custom-directive', 'directive');
// Result: "_directive_custom_directive"

Expression Analysis

Functions for analyzing JavaScript expressions in templates.

/**
 * Checks if name is a simple JavaScript identifier
 * @param name - String to check
 * @returns True if valid simple identifier
 */
function isSimpleIdentifier(name: string): boolean;

/**
 * Checks if expression is a member access expression
 * @param exp - Expression node to check
 * @param context - Transform context
 * @returns True if expression is member access
 */
function isMemberExpression(exp: ExpressionNode, context: TransformContext): boolean;

/**
 * Checks if expression is a function expression
 * @param exp - Expression node to check  
 * @param context - Transform context
 * @returns True if expression is a function
 */
function isFnExpression(exp: ExpressionNode, context: TransformContext): boolean;

Usage Examples:

import { isSimpleIdentifier, isMemberExpression, isFnExpression } from "@vue/compiler-core";

// Validate identifier names
if (isSimpleIdentifier('userName')) {
  console.log('Valid identifier');
}

// Analyze expression types
if (isMemberExpression(expression, context)) {
  console.log('Member access: obj.prop');
}

if (isFnExpression(expression, context)) {
  console.log('Function expression');
}

Advanced Expression Analysis

Browser and Node.js specific expression analysis functions for different runtime environments.

/**
 * Browser-specific member expression checker (lexical analysis)
 * @param exp - Expression node to check
 * @returns True if expression is member access
 */
function isMemberExpressionBrowser(exp: ExpressionNode): boolean;

/**
 * Browser-specific function expression checker (lexical analysis)
 * @param exp - Expression node to check
 * @returns True if expression is a function
 */
function isFnExpressionBrowser(exp: ExpressionNode): boolean;

/**
 * Checks if node contains expressions that reference current context scope ids
 * @param node - Template child node, branch node, or expression to check
 * @param ids - Transform context identifiers map
 * @returns True if node references scope identifiers
 */
function hasScopeRef(
  node: TemplateChildNode | IfBranchNode | ExpressionNode | CacheExpression | undefined,
  ids: TransformContext['identifiers']
): boolean;

/**
 * Regular expression for parsing v-for alias syntax
 */
const forAliasRE: RegExp;

VNode and Prop Utilities

Functions for manipulating VNode calls and injecting properties.

/**
 * Injects a property into a VNode or RenderSlot call
 * @param node - VNode call or render slot call to modify
 * @param prop - Property to inject
 * @param context - Transform context
 */
function injectProp(
  node: VNodeCall | RenderSlotCall,
  prop: Property,
  context: TransformContext
): void;

/**
 * Extracts VNode call from memo expression or returns node directly
 * @param node - Block codegen node or memo expression
 * @returns The underlying VNode or RenderSlot call
 */
function getMemoedVNodeCall(
  node: BlockCodegenNode | MemoExpression
): VNodeCall | RenderSlotCall;

Usage Examples:

import { 
  hasScopeRef, 
  injectProp, 
  getMemoedVNodeCall,
  forAliasRE 
} from "@vue/compiler-core";

// Check scope references
if (hasScopeRef(expression, context.identifiers)) {
  console.log('Expression references scoped variables');
}

// Parse v-for syntax
const match = expression.match(forAliasRE);
if (match) {
  const [, LHS, RHS] = match;
  console.log('v-for alias:', LHS, 'in', RHS);
}

// Inject key property
const keyProperty = createProperty('key', createSimpleExpression('item.id'));
injectProp(vnodeCall, keyProperty, context);

// Extract VNode from memo
const actualVNode = getMemoedVNodeCall(memoOrVNode);

Position and Location Utilities

Functions for working with source code positions and locations.

/**
 * Advances position and returns new Position (immutable)
 * @param pos - Starting position
 * @param source - Source text being advanced through
 * @param numberOfCharacters - Number of characters to advance
 * @returns New Position object
 */
function advancePositionWithClone(
  pos: Position,
  source: string,
  numberOfCharacters?: number
): Position;

/**
 * Advances position in-place (mutable)
 * @param pos - Position to modify
 * @param source - Source text being advanced through  
 * @param numberOfCharacters - Number of characters to advance
 * @returns The same Position object (modified)
 */
function advancePositionWithMutation(
  pos: Position,
  source: string,
  numberOfCharacters?: number
): Position;

Usage Examples:

import { advancePositionWithClone, advancePositionWithMutation } from "@vue/compiler-core";

const startPos = { offset: 0, line: 1, column: 1 };
const source = "Hello\nWorld";

// Immutable advance
const newPos = advancePositionWithClone(startPos, source, 6);
console.log(newPos); // { offset: 6, line: 2, column: 1 }
console.log(startPos); // Still { offset: 0, line: 1, column: 1 }

// Mutable advance  
const pos = { offset: 0, line: 1, column: 1 };
advancePositionWithMutation(pos, source, 6);
console.log(pos); // { offset: 6, line: 2, column: 1 }

Assertion and Debugging

Utility functions for debugging and validation.

/**
 * Runtime assertion helper
 * @param condition - Condition that should be true
 * @param msg - Error message if assertion fails
 * @throws Error if condition is false
 */
function assert(condition: boolean, msg?: string): void;

Usage Examples:

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

// Validate assumptions during compilation
assert(node.type === NodeTypes.ELEMENT, 'Expected element node');
assert(directive.name === 'if', 'Expected v-if directive');

// Debug mode assertions
if (__DEV__) {
  assert(context.currentNode !== null, 'Current node should not be null');
}

Babel Integration Utilities

Functions for working with Babel AST nodes and JavaScript analysis.

Identifier Walking

Functions for traversing and analyzing JavaScript identifiers.

/**
 * Walks AST and calls callback for each identifier
 * @param root - Babel AST node to walk
 * @param onIdentifier - Callback for each identifier found
 * @param includeAll - Whether to include all identifiers or just references
 * @param parentStack - Stack of parent nodes
 * @param knownIds - Set of known identifier names
 */
function walkIdentifiers(
  root: Node,
  onIdentifier: (
    node: Identifier,
    parent: Node,
    parentStack: Node[],
    isReference: boolean,
    isLocal: boolean
  ) => void,
  includeAll?: boolean,
  parentStack?: Node[],
  knownIds?: Record<string, number>
): void;

/**
 * Checks if identifier is being referenced (not declared)
 * @param id - Identifier node
 * @param parent - Parent node
 * @param parentStack - Stack of ancestor nodes
 * @returns True if identifier is a reference
 */
function isReferencedIdentifier(
  id: Identifier,
  parent: Node | null,
  parentStack: Node[]
): boolean;

/**
 * Extracts all identifier nodes from a parameter pattern
 * @param param - Parameter node (can be pattern)
 * @param nodes - Array to collect identifiers into
 * @returns Array of identifier nodes
 */
function extractIdentifiers(
  param: Node,
  nodes?: Identifier[]
): Identifier[];

Usage Examples:

import { walkIdentifiers, isReferencedIdentifier, extractIdentifiers } from "@vue/compiler-core";

// Walk expression and collect references
const references = new Set<string>();
walkIdentifiers(babelAst, (id, parent, parentStack, isReference) => {
  if (isReference) {
    references.add(id.name);
  }
});

// Check specific identifier
if (isReferencedIdentifier(identifier, parent, parentStack)) {
  console.log('Identifier is being referenced');
}

// Extract parameter names
const params = extractIdentifiers(functionNode.params[0]);
console.log('Parameter names:', params.map(p => p.name));

Node Type Checking

Functions for checking Babel AST node types.

/**
 * Type guard for function nodes
 * @param node - Node to check
 * @returns True if node is any kind of function
 */
function isFunctionType(node: Node): node is Function;

/**
 * Type guard for static object properties
 * @param node - Node to check
 * @returns True if node is a static object property
 */
function isStaticProperty(node: Node): node is ObjectProperty;

/**
 * Unwraps TypeScript AST nodes to get underlying JavaScript
 * @param node - Potentially wrapped TS node
 * @returns Unwrapped JavaScript node
 */
function unwrapTSNode(node: Node): Node;

Usage Examples:

import { isFunctionType, isStaticProperty, unwrapTSNode } from "@vue/compiler-core";

// Check for function nodes
if (isFunctionType(node)) {
  console.log('Found function:', node.type);
}

// Filter static properties
const staticProps = objectExpression.properties.filter(isStaticProperty);

// Unwrap TypeScript annotations
const jsNode = unwrapTSNode(tsNode);

Runtime Helpers

System for managing Vue runtime helper functions.

Helper Symbols

Symbols representing Vue runtime helper functions.

// Core VNode creation helpers
const FRAGMENT: unique symbol;
const TELEPORT: unique symbol;
const SUSPENSE: unique symbol;
const KEEP_ALIVE: unique symbol;
const BASE_TRANSITION: unique symbol;

// VNode creation functions
const OPEN_BLOCK: unique symbol;
const CREATE_BLOCK: unique symbol;
const CREATE_ELEMENT_BLOCK: unique symbol;
const CREATE_VNODE: unique symbol;
const CREATE_ELEMENT_VNODE: unique symbol;
const CREATE_COMMENT: unique symbol;
const CREATE_TEXT: unique symbol;
const CREATE_STATIC: unique symbol;

// Component resolution
const RESOLVE_COMPONENT: unique symbol;
const RESOLVE_DYNAMIC_COMPONENT: unique symbol;
const RESOLVE_DIRECTIVE: unique symbol;
const RESOLVE_FILTER: unique symbol;

// Directive helpers
const WITH_DIRECTIVES: unique symbol;

// List rendering
const RENDER_LIST: unique symbol;
const RENDER_SLOT: unique symbol;
const CREATE_SLOTS: unique symbol;

// Utility helpers
const TO_DISPLAY_STRING: unique symbol;
const MERGE_PROPS: unique symbol;
const NORMALIZE_CLASS: unique symbol;
const NORMALIZE_STYLE: unique symbol;
const NORMALIZE_PROPS: unique symbol;
const GUARD_REACTIVE_PROPS: unique symbol;
const TO_HANDLERS: unique symbol;
const CAMELIZE: unique symbol;
const CAPITALIZE: unique symbol;
const TO_HANDLER_KEY: unique symbol;

// Optimization helpers
const SET_BLOCK_TRACKING: unique symbol;
const WITH_CTX: unique symbol;
const UNREF: unique symbol;
const IS_REF: unique symbol;
const WITH_MEMO: unique symbol;
const IS_MEMO_SAME: unique symbol;

// Deprecated helpers (kept for backwards compatibility)
const PUSH_SCOPE_ID: unique symbol;
const POP_SCOPE_ID: unique symbol;

Helper Management

Functions for working with runtime helpers.

/**
 * Maps helper symbols to their runtime names
 */
const helperNameMap: Record<symbol, string>;

/**
 * Registers additional runtime helpers
 * @param helpers - Map of helper symbols to names
 */
function registerRuntimeHelpers(helpers: Record<symbol, string>): void;

Usage Examples:

import { 
  CREATE_VNODE, 
  RESOLVE_COMPONENT, 
  helperNameMap, 
  registerRuntimeHelpers 
} from "@vue/compiler-core";

// Get helper name
const vnodeHelper = helperNameMap[CREATE_VNODE]; // "createVNode"
const resolveHelper = helperNameMap[RESOLVE_COMPONENT]; // "resolveComponent"

// Register custom helpers
const customHelpers = {
  [Symbol('CUSTOM_HELPER')]: 'customHelper'
};
registerRuntimeHelpers(customHelpers);

Vue 2.x Compatibility

Functions for handling Vue 2.x compatibility features.

Compatibility Checking

/**
 * Checks if a compatibility feature is enabled (without warnings)
 * @param key - Compatibility feature key  
 * @param context - Transform context
 * @returns True if feature is enabled
 */
function isCompatEnabled(
  key: CompilerDeprecationTypes,
  context: TransformContext | ParserContext
): boolean;

/**
 * Checks if a compatibility feature is enabled and warns if deprecated
 * @param key - Compatibility feature key
 * @param context - Transform context
 * @param loc - Source location for warning
 * @param args - Additional arguments for warning message
 * @returns True if feature is enabled
 */
function checkCompatEnabled(
  key: CompilerDeprecationTypes,
  context: TransformContext | ParserContext,
  loc: SourceLocation | null,
  ...args: any[]
): boolean;

/**
 * Issues a deprecation warning
 * @param key - Deprecation type
 * @param context - Transform context
 * @param message - Additional warning message
 */
function warnDeprecation(
  key: CompilerDeprecationTypes,
  context: TransformContext | ParserContext,
  message?: string
): void;

/**
 * Types of compiler deprecations for Vue 2.x compatibility
 */
enum CompilerDeprecationTypes {
  COMPILER_IS_ON_ELEMENT = "COMPILER_IS_ON_ELEMENT",
  COMPILER_V_BIND_SYNC = "COMPILER_V_BIND_SYNC",
  COMPILER_V_BIND_PROP = "COMPILER_V_BIND_PROP",
  COMPILER_V_BIND_OBJECT_ORDER = "COMPILER_V_BIND_OBJECT_ORDER",
  COMPILER_V_ON_NATIVE = "COMPILER_V_ON_NATIVE",
  COMPILER_V_IF_V_FOR_PRECEDENCE = "COMPILER_V_IF_V_FOR_PRECEDENCE",
  COMPILER_NATIVE_TEMPLATE = "COMPILER_NATIVE_TEMPLATE",
  COMPILER_INLINE_TEMPLATE = "COMPILER_INLINE_TEMPLATE",
  COMPILER_FILTER = "COMPILER_FILTER"
}

Usage Examples:

import { 
  checkCompatEnabled, 
  warnDeprecation, 
  CompilerDeprecationTypes 
} from "@vue/compiler-core";

// Check if filters are enabled (Vue 2.x feature)
if (checkCompatEnabled(CompilerDeprecationTypes.COMPILER_FILTER, context)) {
  // Process filter syntax
  processFilter(node, context);
} else {
  warnDeprecation(
    CompilerDeprecationTypes.COMPILER_FILTER,
    context,
    'Filters are removed in Vue 3. Use computed properties or methods instead.'
  );
}

Common Utility Patterns

Template Analysis

// Check if element has Vue directives
function hasDirectives(element: ElementNode): boolean {
  return element.props.some(prop => prop.type === NodeTypes.DIRECTIVE);
}

// Get all directive names on element
function getDirectiveNames(element: ElementNode): string[] {
  return element.props
    .filter((prop): prop is DirectiveNode => prop.type === NodeTypes.DIRECTIVE)
    .map(dir => dir.name);
}

// Check if element is a Vue component
function isComponent(element: ElementNode): boolean {
  return element.tagType === ElementTypes.COMPONENT;
}

Expression Validation

// Validate v-for expression format
function validateVForExpression(exp: string): boolean {
  const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
  return forAliasRE.test(exp);
}

// Check if expression uses reserved keywords
function hasReservedKeywords(exp: string): boolean {
  const reserved = ['arguments', 'eval', 'undefined', 'NaN', 'Infinity'];
  return reserved.some(keyword => exp.includes(keyword));
}

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