vuejs/core
compiler-dom
Active contributors: Evan You, daiwei, edison
Purpose
@vue/compiler-dom is the browser-flavored template compiler. It is a thin layer on top of @vue/compiler-core that:
- Configures HTML-aware parser options (entity decoding, void elements, raw text elements).
- Adds DOM-only
nodeTransforms(style attribute parsing, transition validation, HTML nesting validation). - Overrides
v-modelandv-onto produce DOM-aware code (vModelTextvsvModelCheckboxetc., event modifier wrappers). - Adds DOM-only directives (
v-html,v-text,v-show,v-cloak).
The package is small (~1,400 lines, 16 files). It is what the runtime-compiler full build (vue.global.js, vue.esm-browser.js) bundles, and what compiler-sfc invokes for the <template> block.
Directory layout
packages/compiler-dom/src/
├── index.ts # compile, parse, DOMNodeTransforms, DOMDirectiveTransforms
├── parserOptions.ts # HTML-specific parser options
├── runtimeHelpers.ts # additional symbolic ids (V_MODEL_TEXT, V_SHOW, …)
├── errors.ts # DOM-specific error codes
├── decodeHtmlBrowser.ts # HTML entity decoder (browser uses DOMParser; node uses entities)
├── htmlNesting.ts # the HTML "what can nest in what" tables
└── transforms/
├── transformStyle.ts # parses inline `style="..."` strings into objects
├── vHtml.ts # v-html → innerHTML
├── vText.ts # v-text → textContent
├── vModel.ts # rewrites v-model based on host element
├── vOn.ts # event modifier flags + DOM event handling
├── vShow.ts # v-show → withDirectives + vShow
├── Transition.ts # warns on multi-children <Transition>
├── stringifyStatic.ts # large hoisted static node → string template
├── ignoreSideEffectTags.ts # warn on <script>/<style> in template
└── validateHtmlNesting.ts # warn for invalid nesting (e.g., <p><div>)How it slots in
// packages/compiler-dom/src/index.ts
export const DOMNodeTransforms: NodeTransform[] = [
transformStyle,
...(__DEV__ ? [transformTransition, validateHtmlNesting] : []),
];
export const DOMDirectiveTransforms: Record<string, DirectiveTransform> = {
cloak: noopDirectiveTransform,
html: transformVHtml,
text: transformVText,
model: transformModel, // override compiler-core
on: transformOn, // override compiler-core
show: transformShow,
};
export function compile(src, options = {}) {
return baseCompile(
src,
extend({}, parserOptions, options, {
nodeTransforms: [
ignoreSideEffectTags,
...DOMNodeTransforms,
...(options.nodeTransforms || []),
],
directiveTransforms: extend(
{},
DOMDirectiveTransforms,
options.directiveTransforms || {}
),
transformHoist: __BROWSER__ ? null : stringifyStatic,
})
);
}The package also exports the parserOptions object so compiler-ssr can reuse it without inheriting the DOM-only transforms.
Why stringifyStatic
stringifyStatic (packages/compiler-dom/src/transforms/stringifyStatic.ts) is enabled only outside the browser build (!__BROWSER__). When cacheStatic decides to hoist a large fully-static subtree, this hoist transform converts the resulting vnode to a createStaticVNode("<div>…</div>", count) call: a single string set via innerHTML that creates many DOM nodes at once. This is much cheaper than constructing N vnodes during hydration.
It is browser-build-disabled because in the browser the compiler runs at runtime; emitting raw HTML strings would defeat the whole point of vnode equality optimizations and could clash with the user's templating environment.
Key abstractions
| Symbol | File | Description |
|---|---|---|
compile, parse |
packages/compiler-dom/src/index.ts |
DOM-flavored entries that wrap baseCompile/baseParse. |
parserOptions |
packages/compiler-dom/src/parserOptions.ts |
HTML-specific options: isPreTag, isVoidTag, getNamespace, decodeEntities. |
transformStyle |
packages/compiler-dom/src/transforms/transformStyle.ts |
Parses static style="…" strings into { key: val } objects so they can be diffed without reparsing every patch. |
transformModel |
packages/compiler-dom/src/transforms/vModel.ts |
Picks the right runtime vModelXxx directive based on <input type>, <textarea>, <select>. |
transformOn |
packages/compiler-dom/src/transforms/vOn.ts |
Emits _withModifiers/_withKeys wrappers for v-on.stop.prevent.self.once.passive.capture and key filters. |
validateHtmlNesting |
packages/compiler-dom/src/transforms/validateHtmlNesting.ts |
Dev-only check using the table in htmlNesting.ts to catch obvious mistakes like <p><div>. |
DOMErrorCodes, DOMErrorMessages |
packages/compiler-dom/src/errors.ts |
DOM-specific error codes; merged with core codes by compiler-sfc. |
Integration points
- Runs inside
vue(full builds) for runtime template compilation. - Runs inside
compiler-sfc.compileTemplatefor SFC templates. - Imported by
compiler-ssr, which reusesparserOptions,transformBind,transformOn,transformStyle, etc., but installs its own element/component transforms.
Entry points for modification
- New DOM directive? Add a transform in
transforms/, register inDOMDirectiveTransforms. - New element-level optimization? Add a
NodeTransformand register inDOMNodeTransforms. - HTML parsing edge case?
parserOptions.tsis the file; the underlying state machine lives incompiler-core'stokenizer.ts. - Nesting rule change? Update the table in
htmlNesting.ts.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.