Core compiler for Vue.js template compilation and transformation
—
Vue Compiler Core provides a comprehensive set of utility functions for AST manipulation, type checking, identifier analysis, and common compiler operations.
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);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');
}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"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');
}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;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);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 }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');
}Functions for working with Babel AST nodes and JavaScript analysis.
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));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);System for managing Vue runtime helper functions.
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;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);Functions for handling Vue 2.x compatibility features.
/**
* 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.'
);
}// 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;
}// 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