Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

Arman19941113
Copy link
Contributor

@Arman19941113 Arman19941113 commented Sep 12, 2025

This vnode with the v-once directive down here will be condensed into a "static vnode", so it causes a compile error.

<template>
    <div v-once>{{ msg }}</div>
    <span class="foo">foo</span>
    <span class="foo">foo</span>
    <span class="foo">foo</span>
    <span class="foo">foo</span>
</template>

v-once nodes should not be stringified. This PR is to fix it.

See live demo

Summary by CodeRabbit

  • Bug Fixes

    • Corrected handling of v-once within otherwise static content, preventing it from being stringified. Ensures v-once sections render once as expected and avoids potential rendering inconsistencies.
  • Tests

    • Added test coverage for scenarios combining eligible static content with v-once to validate correct behavior.

Copy link

coderabbitai bot commented Sep 12, 2025

Walkthrough

Adds early bailout in stringifyStatic to skip nodes with v-once, and introduces a unit test verifying eligible content handling with a v-once child. No public API or production signature changes.

Changes

Cohort / File(s) Summary
Transform Logic
packages/compiler-dom/src/transforms/stringifyStatic.ts
Added findDir import. Updated analyzeNode to detect v-once via findDir(node, 'once', true) and bail from stringification for such elements. Other behavior unchanged.
Tests
packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts
Added test "eligible content + v-once node" using compileWithStringify and snapshot assertion to cover v-once exclusion from static stringification.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant T as Template
    participant C as compileWithStringify
    participant TS as stringifyStatic Transform
    participant AN as analyzeNode
    participant FD as findDir('once', true)

    T->>C: Provide template with static content and v-once node
    C->>TS: Run stringifyStatic transform
    TS->>AN: analyzeNode(node)
    AN->>FD: Check for v-once directive
    alt v-once present
        AN-->>TS: Bail out (do not include in static chunk)
        TS->>C: Node rendered via normal path
    else no v-once
        AN-->>TS: Eligible for static stringification
        TS->>C: Add to static stringified chunk
    end
    C-->>T: Generated render code
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix(compiler-dom): nodes with v-once shouldn't be stringified" succinctly and accurately captures the primary change—preventing stringification of nodes with v-once in the compiler-dom transform. It is concise, specific to the affected module, and clear for teammates scanning the commit history.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Poem

I nibble through strings with careful delight,
Skip the once-marked leaves in the moonlit night.
Static twigs bundled, dynamic left free—
A tidy burrow of render’d HTML tree.
Thump-thump! Tests pass; my whiskers agree.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 101 kB 38.5 kB 34.6 kB
vue.global.prod.js 159 kB 58.6 kB 52.1 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.6 kB 18.2 kB 16.7 kB
createApp 54.6 kB 21.3 kB 19.4 kB
createSSRApp 58.9 kB 23 kB 21 kB
defineCustomElement 59.6 kB 22.8 kB 20.9 kB
overall 68.8 kB 26.4 kB 24.2 kB

Copy link

pkg-pr-new bot commented Sep 12, 2025

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@13878

@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@13878

@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@13878

@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@13878

@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@13878

@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@13878

@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@13878

@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@13878

@vue/shared

npm i https://pkg.pr.new/@vue/shared@13878

vue

npm i https://pkg.pr.new/vue@13878

@vue/compat

npm i https://pkg.pr.new/@vue/compat@13878

commit: 0714cd2

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/compiler-dom/src/transforms/stringifyStatic.ts (1)

217-221: Good early bail for v-once; also bail when v-once appears in descendants.

Current check prevents stringifying the node that directly bears v-once. For robustness, also bail during the subtree walk so a parent isn’t stringified when any descendant has v-once (e.g., nested v-once inside an otherwise eligible wrapper).

Suggested change inside walk():

function walk(node: ElementNode): boolean {
  // Bail if this element (or any visited descendant) has v-once
  if (findDir(node, 'once', true)) {
    return bail()
  }
  const isOptionTag = node.tag === 'option' && node.ns === Namespaces.HTML
  // ...
}

Would you like me to add a focused test covering a nested v-once descendant to ensure we never stringify across it?

packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts (1)

529-537: Nice regression test; consider asserting AST shape and add a nested v-once case.

Snapshot is fine, but a small AST-level assertion will more precisely guarantee that only the span group is stringified and the v-once node remains a VNODE_CALL.

Example assertion (inline with this test):

// ensure first child (v-once) stays as VNODE_CALL and second becomes CREATE_STATIC
expect(ast.cached).toMatchObject([
  {
    type: NodeTypes.JS_CACHE_EXPRESSION,
    value: {
      type: NodeTypes.JS_ARRAY_EXPRESSION,
      elements: [
        { codegenNode: { type: NodeTypes.VNODE_CALL } },
        { type: NodeTypes.JS_CALL_EXPRESSION, callee: CREATE_STATIC }
      ]
    }
  }
])

Optionally add a second test for a nested v-once descendant to guard against stringifying a wrapper that contains v-once.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75220c7 and 0714cd2.

⛔ Files ignored due to path filters (1)
  • packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (2)
  • packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts (1 hunks)
  • packages/compiler-dom/src/transforms/stringifyStatic.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/compiler-dom/src/transforms/stringifyStatic.ts (1)
packages/compiler-core/src/utils.ts (1)
  • findDir (282-297)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Redirect rules
  • GitHub Check: Header rules
  • GitHub Check: Pages changed
🔇 Additional comments (1)
packages/compiler-dom/src/transforms/stringifyStatic.ts (1)

20-22: Import of findDir is correct and minimal.

Brings in the exact utility needed for directive detection without expanding public surface. No further action.

@edison1105 edison1105 added ready to merge The PR is ready to be merged. scope: compiler 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels Sep 12, 2025
@edison1105
Copy link
Member

/ecosystem-ci run

@vue-bot
Copy link
Contributor

vue-bot commented Sep 12, 2025

📝 Ran ecosystem CI: Open

suite result latest scheduled
primevue success success
pinia success success
nuxt success success
language-tools success success
test-utils success success
quasar success success
radix-vue success success
vant success success
router success success
vitepress success success
vue-i18n success success
vue-macros success success
vueuse success success
vue-simple-compiler success success
vuetify failure failure
vite-plugin-vue success success

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready to merge The PR is ready to be merged. scope: compiler
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants