Skip to content

feature: support Vue Vapor mode #293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 52 commits into
base: main
Choose a base branch
from
Open

feature: support Vue Vapor mode #293

wants to merge 52 commits into from

Conversation

ShenQingchuan
Copy link
Member

@ShenQingchuan ShenQingchuan commented Jul 14, 2025

Description

Please read Vue 3.6 (alpha) release notes about vapor mode to learn more details of background information.

Tasks

  • Compiler changes
  • Language service support
  • Vapor interop E2E test demo
  • Documentation

Pending issues

⚠️⚠️ Still need to wait for an official release to replace current patches ⚠️⚠️
Wait for vuejs/core#13623 to be solved

  • nodeTransforms needs to be refactored because TransformContext is different now
  • transformSrcset is not implemented for now
  • Fix Vue Vine useVibe unit test case failed

Assets

Summary by CodeRabbit

  • New Features

    • Vapor mode for Vine components (vine.vapor and 'use vapor') with Vapor ↔ Virtual DOM interop, Volar support, SSR handling, and automatic asset import resolution (including srcset) plus hashed asset imports.
  • Documentation

    • Added Vapor mode docs in English and Chinese with usage examples.
  • Tests

    • New unit, E2E, snapshot, typecheck and lint tests covering Vapor interop and asset handling.
  • Chores

    • Workspace/dependency updates, editor/syntax/theme tweaks, tooling and script improvements, added e2e route/plugin.

Copy link

netlify bot commented Jul 14, 2025

Deploy Preview for vue-vine ready!

Name Link
🔨 Latest commit 5274062
🔍 Latest deploy log https://app.netlify.com/projects/vue-vine/deploys/689c3d663cffc80007767a80
😎 Deploy Preview https://deploy-preview-293--vue-vine.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

coderabbitai bot commented Jul 14, 2025

Walkthrough

Add Vapor-mode support: detect vine.vapor and 'use vapor', propagate isVapor in component context, branch template compilation between SSR/Vapor/VDOM, track/hash asset imports (including srcset), refactor language-service global-types handling, update docs, tests, e2e fixtures, workspace metadata, and tooling.

Changes

Cohort / File(s) Summary
Compiler: Vapor detection & core types
packages/compiler/src/analyze.ts, packages/compiler/src/types.ts, packages/compiler/src/constants.ts, packages/compiler/src/babel-helpers/ast.ts
Add isVapor detection (tagged vine.vapor or 'use vapor'), new helper isVaporVineCompFn, extend VineCompFnCtx with isVapor, add DEFINE_VAPOR_COMPONENT_HELPER, and refactor tagged-template/component detection.
Compiler: Template composition & transforms
packages/compiler/src/template/compose.ts, packages/compiler/src/template/import-usage-check.ts, packages/compiler/src/template/transform-asset-url.ts, packages/compiler/src/template/transform-srcset.ts, packages/compiler/src/template/transform-negative-bool.ts
Add multi-mode compile path (SSR / Vapor / VDOM), unify compiler options, return optional parsed AST and imports, centralized compile options and error reporting, handle Vapor AST shape, safer optional chaining, switch some imports to @vue/compiler-core, implement hash-based import naming, and add transformSrcset.
Compiler: Transform pipeline integration
packages/compiler/src/transform/steps.ts
Conditionally include Vapor helper in import specs, use defineVaporComponent for Vapor comps, adjust inline setup return generation for Vapor mode.
Compiler: Tests
packages/compiler/tests/analyze.spec.ts, packages/compiler/tests/transform.spec.ts
Add analyze test for vine.vapor detection (isVapor), add Volar-suffix tests and asset/srcset transform tests.
Vapor compiler patch
patches/@vue__compiler-vapor.patch
Patch compiler-vapor to track imports in IR/context, treat asset imports specially in gen, generate ES import statements, escape template strings, and update type declarations.
Language service & global types
packages/language-service/src/vine-ctx.ts, packages/language-service/src/virtual-code.ts, packages/language-service/src/injectTypes.ts, packages/language-server/src/utils.ts, packages/language-server/src/index.ts, packages/language-service/tests/virtual-code.spec.ts, packages/language-service/src/shared.ts
Rename compile→analyze entry, set volar: true, introduce getDefaultVueCompilerOptions, refactor setupGlobalTypes to resolver form with host abstraction, namespace generated VLS identifiers, and adjust path/type handling.
Template parser / ESLint / parser & VSCode
packages/eslint-parser/src/template/utils/process-vine-template-node.ts, packages/vscode-ext/syntaxes/vine-inject.json, packages/vscode-ext/themes/rocking-vine.json
Add isVineTemplateNode to detect vine and vine.vapor, update VSCode injection regex to accept optional .vapor, and add theme token color for vapor-tag scope.
E2E: app, fixtures, router, tests
packages/e2e-test/src/app.vine.ts, packages/e2e-test/src/router.ts, packages/e2e-test/src/main.ts, packages/e2e-test/src/fixtures/vapor-interop.vine.ts, packages/e2e-test/src/fixtures/transform-asset-url.vine.ts, packages/e2e-test/tests/basic.spec.ts, packages/e2e-test/tests/check.spec.ts
Add Vapor interop route and plugin usage, new Vapor/interop fixtures, extend transform-asset-url fixture, add E2E interop test, and add type/lint-check test suite.
E2E utils & types
packages/e2e-test/utils/evaluator.ts, packages/e2e-test/utils/test-utils.ts, packages/e2e-test/utils/types.ts, packages/e2e-test/tsconfig.json
Generalize evaluator return to `string
Workspace & packages metadata
pnpm-workspace.yaml, packages/compiler/package.json, packages/vue-vine/package.json
Update workspace defines/patches, add @vue/compiler-core and @vue/compiler-vapor to catalog and compiler package, adjust version aliases, and switch vue peer dep to catalog alias.
Docs
packages/docs/src/specification/overview.md, packages/docs/src/zh/specification/overview.md, packages/docs/src/.vitepress/config.ts
Add "Vapor mode" documentation (EN/ZH) explaining vine.vapor and 'use vapor', and include 'vue' in required languages config.
Tooling & misc
scripts/vscode-ext-pack.js, eslint.config.js, .gitattributes, packages/e2e-test/package.json
Add --minor/--major bump flags, broaden docs ignore pattern, add .gitattributes enforcing LF, and add check-types / check-lint scripts plus devDependency for e2e-test.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as build pipeline
  participant Analyzer as analyze.ts
  participant Composer as compose.ts
  participant CompilerCore as @vue/compiler-core
  participant CompilerVapor as @vue/compiler-vapor

  Caller->>Analyzer: buildVineCompFnCtx(fnNode, tplNode)
  Analyzer-->>Caller: VineCompFnCtx { isVapor, bindings, ... }

  Caller->>Composer: compileVineTemplate(ctx, { ssr?, volar? })
  alt ssr
    Composer->>CompilerCore: compileSSR(options)
    CompilerCore-->>Composer: result
  else isVapor
    Composer->>CompilerVapor: compileVapor(options)
    CompilerVapor-->>Composer: { code, ast, imports }
    Composer->>Composer: merge imports & AST
  else VDOM
    Composer->>CompilerCore: compileVDOM(options)
    CompilerCore-->>Composer: result
  end
  Composer-->>Caller: { code, templateParsedAst?, imports? }
Loading
sequenceDiagram
  participant LS as Language Server
  participant Utils as getDefaultVueCompilerOptions
  participant Inject as setupGlobalTypes
  participant TS as ts.System

  LS->>Utils: request options (ts.System)
  Utils->>Inject: setupGlobalTypes(vueOptions, TS)
  Inject-->>Utils: returns globalTypesPath resolver
  Utils-->>LS: vueCompilerOptions with globalTypesPath
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • Vapor mode support #292: Vapor-mode RFC — this PR implements vine.vapor / 'use vapor' detection and pipeline changes aligned with that issue.

Possibly related PRs

Poem

I hop through vine tags, vapor on my tail,
I mark imports with hashes, follow every trail.
Templates split — SSR, VDOM, or new,
Tests and docs cheer softly as features accrue.
A rabbit smiles and says: compile on, crew! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/vine-vapor

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

pkg-pr-new bot commented Jul 14, 2025

Open in StackBlitz

@vue-vine/compiler

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/compiler@293

create-vue-vine

npm i https://pkg.pr.new/vue-vine/vue-vine/create-vue-vine@293

@vue-vine/eslint-config

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/eslint-config@293

@vue-vine/eslint-parser

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/eslint-parser@293

@vue-vine/eslint-plugin

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/eslint-plugin@293

@vue-vine/language-server

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/language-server@293

@vue-vine/language-service

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/language-service@293

@vue-vine/nuxt

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/nuxt@293

vue-vine-tsc

npm i https://pkg.pr.new/vue-vine/vue-vine/vue-vine-tsc@293

@vue-vine/vite-plugin

npm i https://pkg.pr.new/vue-vine/vue-vine/@vue-vine/vite-plugin@293

vue-vine

npm i https://pkg.pr.new/vue-vine/vue-vine@293

commit: 5274062

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: 1

🧹 Nitpick comments (2)
packages/compiler/src/babel-helpers/ast.ts (1)

149-163: Consider optimizing redundant type checks

The function performs isTaggedTemplateExpression check twice when evaluating vine.vapor templates.

 export function isVineTaggedTemplateString(node: Node | null | undefined): node is TaggedTemplateExpression {
   if (!isTaggedTemplateExpression(node)) {
     return false
   }
 
   // vine`...` or vine.vapor`...`
   if (isIdentifier(node.tag) && node.tag.name === 'vine') {
     return true
   }
-  if (isVineVaporTaggedTemplateString(node)) {
-    return true
-  }
+  // Check for vine.vapor`...`
+  if (isMemberExpression(node.tag)
+      && isIdentifier(node.tag.object)
+      && node.tag.object.name === 'vine'
+      && isIdentifier(node.tag.property)
+      && node.tag.property.name === 'vapor') {
+    return true
+  }
 
   return false
 }

This avoids the redundant isTaggedTemplateExpression check while maintaining the same logic.

packages/compiler/src/template/compose.ts (1)

181-193: Track the TODO for Vapor node transforms

The Vapor compilation path currently has empty node transforms with a TODO comment. This should be tracked for implementation.

Would you like me to create an issue to track the implementation of Vapor mode node transforms?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a19493 and 5da89b0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • packages/compiler/package.json (1 hunks)
  • packages/compiler/src/analyze.ts (2 hunks)
  • packages/compiler/src/babel-helpers/ast.ts (1 hunks)
  • packages/compiler/src/constants.ts (1 hunks)
  • packages/compiler/src/template/compose.ts (5 hunks)
  • packages/compiler/src/transform/steps.ts (3 hunks)
  • packages/compiler/src/types.ts (2 hunks)
  • packages/compiler/tests/analyze.spec.ts (1 hunks)
  • packages/e2e-test/src/app.vine.ts (1 hunks)
  • packages/e2e-test/src/fixtures/vapor-interop.vine.ts (1 hunks)
  • packages/e2e-test/src/main.ts (2 hunks)
  • packages/e2e-test/src/router.ts (2 hunks)
  • packages/e2e-test/tests/basic.spec.ts (1 hunks)
  • packages/eslint-parser/src/template/utils/process-vine-template-node.ts (2 hunks)
  • packages/language-service/src/vine-ctx.ts (1 hunks)
  • packages/language-service/src/virtual-code.ts (1 hunks)
  • packages/vscode-ext/syntaxes/vine-inject.json (1 hunks)
  • packages/vue-vine/types/macros.d.ts (1 hunks)
  • pnpm-workspace.yaml (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.vine.ts

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • .cursor/rules/vue-vine-repo-rules.mdc
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件支持 HMR
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/compiler/package.json (4)
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
packages/e2e-test/src/main.ts (7)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
packages/compiler/src/constants.ts (7)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
packages/e2e-test/src/app.vine.ts (2)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/language-service/src/vine-ctx.ts (10)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 Volar.js 封装的 API 创建 VSCode Language Server,载入 TypeScript plugin
packages/language-service/src/virtual-code.ts (11)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 Babel 作为 AST 解析器
pnpm-workspace.yaml (4)
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 Volar.js 封装的 API 创建 VSCode Language Server,载入 TypeScript plugin
packages/e2e-test/src/router.ts (7)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
packages/vue-vine/types/macros.d.ts (9)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
packages/compiler/src/types.ts (10)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 Volar.js 封装的 API 创建 VSCode Language Server,载入 TypeScript plugin
packages/vscode-ext/syntaxes/vine-inject.json (6)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
packages/compiler/tests/analyze.spec.ts (6)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
packages/eslint-parser/src/template/utils/process-vine-template-node.ts (6)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
packages/compiler/src/transform/steps.ts (9)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
packages/compiler/src/analyze.ts (9)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
packages/e2e-test/src/fixtures/vapor-interop.vine.ts (9)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
packages/compiler/src/babel-helpers/ast.ts (6)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
packages/compiler/src/template/compose.ts (11)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 Babel 作为 AST 解析器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
🧬 Code Graph Analysis (5)
packages/e2e-test/src/router.ts (1)
packages/e2e-test/src/fixtures/vapor-interop.vine.ts (1)
  • VaporTestContainer (34-42)
packages/eslint-parser/src/template/utils/process-vine-template-node.ts (2)
packages/eslint-parser/src/ast/nodes.ts (1)
  • Node (22-29)
packages/eslint-plugin/src/rules/format/format-vine-style-indent.ts (1)
  • TaggedTemplateExpression (50-81)
packages/compiler/src/transform/steps.ts (1)
packages/compiler/src/constants.ts (2)
  • DEFINE_VAPOR_COMPONENT_HELPER (4-4)
  • DEFINE_COMPONENT_HELPER (3-3)
packages/e2e-test/tests/basic.spec.ts (1)
packages/e2e-test/utils/test-utils.ts (1)
  • runTestAtPage (158-168)
packages/compiler/src/analyze.ts (1)
packages/compiler/src/babel-helpers/ast.ts (1)
  • isVineVaporTaggedTemplateString (135-147)
🔇 Additional comments (28)
packages/e2e-test/src/main.ts (1)

2-2: LGTM! Proper Vue plugin integration.

The vaporInteropPlugin import and usage follows Vue's standard plugin pattern and is correctly positioned in the plugin chain.

Also applies to: 14-14

packages/e2e-test/src/app.vine.ts (1)

19-19: LGTM! Route entry follows existing conventions.

The new Vapor Interop route entry maintains consistency with the existing route structure and naming patterns.

packages/compiler/package.json (1)

38-38: LGTM! Dependencies added correctly for Vapor support.

The new Vue compiler dependencies use the consistent catalog versioning approach and are appropriately placed in the dependencies section.

Also applies to: 41-41

packages/compiler/src/constants.ts (1)

4-4: LGTM! Constant follows existing naming conventions.

The DEFINE_VAPOR_COMPONENT_HELPER constant maintains consistency with the existing helper pattern and provides a clear identifier for Vapor component definition.

packages/language-service/src/virtual-code.ts (1)

255-257: LGTM! Reasonable workaround for alpha stage dependency mismatch.

The ts-expect-error comment appropriately addresses the temporary dependency incompatibility during Vue Vapor's alpha stage. The explanation is clear and the workaround is justified.

packages/e2e-test/src/router.ts (1)

12-12: LGTM! Vapor interop test route properly integrated.

The new import and route for the Vapor interop test container follow the established patterns and are correctly implemented.

Also applies to: 37-37

packages/language-service/src/vine-ctx.ts (1)

13-13: LGTM! Correctly updates compiler context for Volar integration.

The change from envMode: 'module' to volar: true aligns with the new VineCompilerOptions.volar flag and improves Volar virtual code generation consistency.

packages/compiler/src/types.ts (2)

82-82: LGTM! Proper type definition for Volar configuration.

The optional volar flag correctly extends the compiler options to support Volar-specific behavior.


228-228: LGTM! Essential type extension for Vapor mode support.

The isVapor boolean property is correctly added as a required field to track Vapor template compilation mode.

packages/compiler/src/analyze.ts (2)

95-95: LGTM! Proper import of Vapor template detection helper.

The import follows established patterns and enables Vapor mode detection during analysis.


1197-1197: LGTM! Correct Vapor mode detection integration.

The isVapor flag is properly set using the helper function to detect vine.vapor tagged template strings. This integrates well with the component context building process.

packages/compiler/tests/analyze.spec.ts (1)

527-539: LGTM! Well-structured test for Vapor template analysis.

The test correctly verifies that vine.vapor tagged templates are properly detected and marked with the isVapor flag. The implementation follows the existing test patterns and provides adequate coverage for the core functionality.

packages/vscode-ext/syntaxes/vine-inject.json (1)

8-8: LGTM! Correctly extends syntax highlighting for Vapor templates.

The regex pattern properly uses a non-capturing group to match both vine and vine.vapor tagged templates, with appropriate escaping of the dot character. This ensures consistent syntax highlighting across both template variants.

packages/vue-vine/types/macros.d.ts (1)

77-80: LGTM! Well-designed type definition that maintains backward compatibility.

The updated type definition correctly extends vine to support both the original callable signature and the new vapor method, while ensuring both return the same VueVineComponent type. This provides type safety for both template variants without breaking existing code.

packages/eslint-parser/src/template/utils/process-vine-template-node.ts (2)

94-111: LGTM! Excellent refactoring with comprehensive Vapor support.

The new isVineTemplateNode type guard function correctly identifies both vine and vine.vapor tagged templates. The implementation properly checks for the different AST node structures (identifier vs member expression) and improves code organization by extracting the logic into a reusable function.


123-123: LGTM! Clean replacement with the new type guard function.

The inline condition was appropriately replaced with the new isVineTemplateNode function call, improving code maintainability while extending support to Vapor templates.

packages/e2e-test/tests/basic.spec.ts (1)

227-241: LGTM! Comprehensive e2e test for Vapor interoperability.

The test effectively validates the interoperability between Vapor and Virtual DOM components by:

  • Verifying proper rendering of both component types
  • Testing user interactions in Virtual DOM components
  • Testing state management in Vapor components

This provides good coverage of the core interop functionality and follows the established testing patterns.

packages/compiler/src/transform/steps.ts (3)

17-17: LGTM!

Import addition is consistent with existing pattern.


78-80: LGTM!

Conditional import follows the established pattern for other helpers.


778-785: LGTM!

Component wrapper generation correctly selects the appropriate helper based on the Vapor flag.

packages/e2e-test/src/fixtures/vapor-interop.vine.ts (3)

3-13: LGTM!

Standard Virtual DOM component implementation follows established patterns.


15-32: LGTM!

Vapor component correctly uses the new vine.vapor template syntax and includes slot for interop testing.


34-42: LGTM!

Container effectively demonstrates Vapor/Virtual DOM interoperability through component composition.

packages/compiler/src/babel-helpers/ast.ts (1)

135-147: LGTM!

Vapor template detection correctly identifies the vine.vapor member expression pattern.

packages/compiler/src/template/compose.ts (4)

24-32: LGTM!

Helper function properly handles both configuration formats for the negative boolean transform.


48-75: LGTM!

Shared compiler options and conditional AST parsing are well-structured.


77-128: LGTM!

Mode-specific compilation functions follow a consistent pattern and properly delegate to respective compilers.


351-358: LGTM!

AST extraction correctly handles Vapor's different node structure while maintaining compatibility.

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: 2

🧹 Nitpick comments (3)
pnpm-workspace.yaml (1)

165-168: Fix YAML key ordering issue

The static analysis indicates that patchedDependencies should be placed before onlyBuiltDependencies to maintain the specified key order.

Apply this diff to fix the ordering:

 onlyBuiltDependencies:
   - '@parcel/watcher'
   - '@tailwindcss/oxide'
   - '@vscode/vsce-sign'
   - esbuild
   - keytar
   - playwright-chromium
   - simple-git-hooks
   - unrs-resolver
   - vue-demi
 
-patchedDependencies:
-  '@vue/compiler-core@3.6.0-alpha.1': patches/@vue__compiler-core@3.6.0-alpha.1.patch
-  '@vue/compiler-vapor': patches/@vue__compiler-vapor.patch
-
-shellEmulator: true

Add this after line 153:

patchedDependencies:
  '@vue/compiler-core@3.6.0-alpha.1': patches/@vue__compiler-core@3.6.0-alpha.1.patch
  '@vue/compiler-vapor': patches/@vue__compiler-vapor.patch

onlyBuiltDependencies:
  - '@parcel/watcher'
  # ... rest of the list

shellEmulator: true
patches/@vue__compiler-core@3.6.0-alpha.1.patch (1)

95-98: Good defensive programming in the patch

The null check for the root parameter prevents potential runtime errors. However, patching external dependencies should be well-documented.

Consider adding a comment in the patch file explaining why this patch is necessary:

 function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = /* @__PURE__ */ Object.create(null)) {
+  // Added by Vue Vine: Handle cases where root might be undefined in Vapor mode compilation
+  if (!root) {
+    return;
+  }

Also, ensure there's documentation in the project README or CONTRIBUTING guide about these patches and when they can be removed (e.g., when Vue 3.6 stable includes this fix).

packages/compiler/src/template/compose.ts (1)

114-120: Document the Volar-Vapor incompatibility.

The condition vineCompFnCtx.isVapor && !volar indicates that Volar doesn't support Vapor mode. Consider adding a comment explaining this limitation and tracking when it can be removed.

 const compile = (
   ssr
     ? (compileSSR as TemplateCompileFn)
-    : vineCompFnCtx.isVapor && !volar
+    : vineCompFnCtx.isVapor && !volar  // TODO: Volar doesn't support Vapor mode yet
       ? (compileVapor as TemplateCompileFn)
       : compileVDOM
 )
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 813eb16 and 95a7018.

⛔ Files ignored due to path filters (2)
  • packages/language-service/tests/__snapshots__/virtual-code.spec.ts.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • packages/compiler/src/analyze.ts (2 hunks)
  • packages/compiler/src/babel-helpers/ast.ts (1 hunks)
  • packages/compiler/src/template/compose.ts (5 hunks)
  • packages/compiler/src/template/import-usage-check.ts (1 hunks)
  • packages/compiler/src/template/transform-asset-url.ts (5 hunks)
  • packages/compiler/src/template/transform-negative-bool.ts (2 hunks)
  • packages/compiler/src/types.ts (2 hunks)
  • packages/e2e-test/src/fixtures/vapor-interop.vine.ts (1 hunks)
  • packages/e2e-test/tests/basic.spec.ts (1 hunks)
  • packages/language-service/src/vine-ctx.ts (1 hunks)
  • packages/language-service/tests/virtual-code.spec.ts (1 hunks)
  • packages/vue-vine/package.json (1 hunks)
  • patches/@vue__compiler-core@3.6.0-alpha.1.patch (1 hunks)
  • patches/@vue__compiler-vapor.patch (1 hunks)
  • pnpm-workspace.yaml (3 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/vue-vine/package.json
  • packages/language-service/tests/virtual-code.spec.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/language-service/src/vine-ctx.ts
  • packages/e2e-test/tests/basic.spec.ts
  • packages/compiler/src/analyze.ts
  • packages/compiler/src/types.ts
  • packages/e2e-test/src/fixtures/vapor-interop.vine.ts
  • packages/compiler/src/babel-helpers/ast.ts
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
patches/@vue__compiler-core@3.6.0-alpha.1.patch (2)
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
packages/compiler/src/template/transform-negative-bool.ts (9)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
packages/compiler/src/template/transform-asset-url.ts (9)
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
patches/@vue__compiler-vapor.patch (8)
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
packages/compiler/src/template/compose.ts (11)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 Babel 作为 AST 解析器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
pnpm-workspace.yaml (4)
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 Volar.js 封装的 API 创建 VSCode Language Server,载入 TypeScript plugin
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 装载其他 VSCode 的语言服务插件,例如 createCssService / createEmmetService
🧬 Code Graph Analysis (1)
packages/compiler/src/template/transform-negative-bool.ts (1)
packages/compiler/src/types.ts (1)
  • VineCompilerOptions (81-98)
🪛 GitHub Check: lint_and_typecheck
pnpm-workspace.yaml

[failure] 165-165:
Expected mapping keys to be in specified order. 'patchedDependencies' should be before 'onlyBuiltDependencies'

⏰ 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). (1)
  • GitHub Check: test (lts/*, windows-latest)
🔇 Additional comments (8)
packages/compiler/src/template/import-usage-check.ts (1)

38-38: Good defensive programming practice!

The change from non-null assertion to optional chaining prevents potential runtime errors when templateParsedAst is undefined or null, which aligns with the Vapor mode support where the parsed AST may be optional.

packages/compiler/src/template/transform-negative-bool.ts (1)

5-6: Well-structured plugin factory function

The migration from @vue/compiler-dom to @vue/compiler-core aligns with the Vapor mode support, and the new getTransformNegativeBoolPlugin function provides a clean abstraction for handling the transform options.

Also applies to: 61-69

patches/@vue__compiler-vapor.patch (2)

17-19: Verify the intentional use of loose equality

The change from ast === null to ast == null will now match both null and undefined. Please confirm this is intentional for handling both cases in Vapor mode.

If this change is intentional to handle both null and undefined cases, consider adding a comment to clarify:

-  if (ast == null) {
+  // Handle both null and undefined AST nodes in Vapor mode
+  if (ast == null) {

26-28: Well-implemented asset import handling

The optional chaining for expToVariableMap.get(exp)?.map prevents errors, and the new genAssetImports function properly handles the asset imports feature with appropriate null checks.

Also applies to: 36-50

packages/compiler/src/template/transform-asset-url.ts (1)

82-89: Good refactoring of parameter passing.

The change to pass imports and bindingMetadata as explicit parameters improves modularity and testability of the getImportsExpressionExp function.

Also applies to: 106-107

packages/compiler/src/template/compose.ts (3)

21-27: Good consolidation of compiler options.

The extraction of common compiler options into a shared constant improves maintainability and ensures consistency across different compilation modes.


313-318: Good handling of Vapor AST structure differences.

The conditional extraction of the inner node ensures consistent AST shape across different compilation modes, with clear documentation of the difference.


437-444: Vapor asset imports are default-only—no changes needed

Verified via the Vite documentation that non-JSON assets (images, styles, etc.) are always emitted as default imports in the Vapor compiler. Named imports apply only to JSON files and aren’t relevant here. The existing logic correctly assumes defaultSpecifier for all asset imports, so no additional guards or defensive checks are required.

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

♻️ Duplicate comments (1)
packages/compiler/tests/transform.spec.ts (1)

456-516: Excellent test coverage for volar template-suffix fix!

This test comprehensively addresses the previous review comment about needing targeted tests for the SHOULD_ADD_SUFFIX_REGEXP behavior. The test cases cover all the edge cases mentioned in the previous review:

✅ Incomplete opening tags (<div, <MyComp)
✅ Self-closing tags (should not be suffixed)
✅ Extra < characters elsewhere
✅ Multiline templates
✅ Both volar: true and volar: false scenarios

The test structure is well-organized with clear positive and negative test cases, and the helper function ensures consistent test execution.

🧹 Nitpick comments (3)
packages/compiler/src/template/compose.ts (3)

114-120: Consider refactoring for better readability.

The compiler selection logic is correct but could be more readable with a clearer structure.

Consider refactoring to improve readability:

-    const compile = (
-      ssr
-        ? (compileSSR as TemplateCompileFn)
-        : vineCompFnCtx.isVapor && !volar
-          ? (compileVapor as TemplateCompileFn)
-          : compileVDOM
-    )
+    const compile = (() => {
+      if (ssr) {
+        return compileSSR as TemplateCompileFn
+      }
+      if (vineCompFnCtx.isVapor && !volar) {
+        return compileVapor as TemplateCompileFn
+      }
+      return compileVDOM
+    })()

139-141: Consider adding type guards for safer import extraction.

The import extraction logic is correct but could benefit from type guards to ensure type safety.

Consider adding type guards:

-      const imports = vineCompFnCtx.isVapor
-        ? ((codegenResult as VaporCodegenResult).ast).imports
-        : (codegenResult as VDOMCodegenResult).ast.imports
+      const imports = vineCompFnCtx.isVapor
+        ? ('imports' in (codegenResult as VaporCodegenResult).ast ? ((codegenResult as VaporCodegenResult).ast).imports : undefined)
+        : (codegenResult as VDOMCodegenResult).ast.imports

437-444: Consider adding type checking for import expression nodes.

The import tracking logic is correct but could benefit from type checking to ensure the expression is a SimpleExpressionNode.

Consider adding type checking:

       if (vineCompFnCtx.isVapor && imports) {
         for (const assetImport of imports) {
+          if (assetImport.exp.type !== 4) { // NodeTypes.SIMPLE_EXPRESSION
+            continue
+          }
           mergedImportsMap.set(assetImport.path, {
             type: 'defaultSpecifier',
             localName: (assetImport.exp as SimpleExpressionNode).content,
           })
         }
       }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6bb2def and 482532c.

⛔ Files ignored due to path filters (2)
  • packages/compiler/tests/__snapshots__/transform.spec.ts.snap is excluded by !**/*.snap
  • packages/language-service/tests/__snapshots__/virtual-code.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (3)
  • packages/compiler/src/template/compose.ts (5 hunks)
  • packages/compiler/tests/transform.spec.ts (1 hunks)
  • pnpm-workspace.yaml (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pnpm-workspace.yaml
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/compiler/tests/transform.spec.ts (6)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
packages/compiler/src/template/compose.ts (11)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 Babel 作为 AST 解析器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
⏰ 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: test (lts/*, macos-latest)
  • GitHub Check: test (lts/*, ubuntu-latest)
  • GitHub Check: test (lts/*, windows-latest)
🔇 Additional comments (6)
packages/compiler/src/template/compose.ts (6)

2-10: LGTM! Import statements properly support Vapor mode integration.

The import additions are well-structured and include all necessary types and functions for Vapor mode compilation support.


20-20: LGTM! Regex pattern correctly identifies incomplete opening tags.

The positive lookbehind pattern effectively matches incomplete opening tags at the end of template strings for the volar environment fix.


47-66: LGTM! Helper function efficiently handles conditional AST parsing.

The early return optimization and conditional parser selection based on Vapor mode are well-implemented.


68-76: LGTM! Type definitions provide excellent type safety for compilation results.

The intersection types effectively combine different result types while maintaining flexibility for additional properties.


122-160: LGTM! Enhanced error handling provides better debugging capabilities.

The nested try-catch structure ensures comprehensive error catching with detailed error information for debugging.


309-318: LGTM! AST handling correctly addresses Vapor mode structural differences.

The type guard 'node' in ast safely detects Vapor mode AST and extracts the required RootNode from the RootIRNode structure.

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: 1

♻️ Duplicate comments (1)
packages/compiler/src/template/compose.ts (1)

21-21: Add tests for the SHOULD_ADD_SUFFIX_REGEXP fix

As mentioned in the previous review, there's still no test coverage for the SHOULD_ADD_SUFFIX_REGEXP logic that adds a trailing > for Volar compatibility. This fix needs comprehensive testing to ensure it doesn't cause unintended side effects.

The previous review suggested creating tests in packages/compiler/src/template/compose.spec.ts. Please add these test cases to ensure the regex behaves correctly in all scenarios.

Also applies to: 101-103

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 262bcdc and 2f77366.

⛔ Files ignored due to path filters (1)
  • packages/compiler/tests/__snapshots__/transform.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (4)
  • packages/compiler/src/template/compose.ts (5 hunks)
  • packages/compiler/src/template/transform-asset-url.ts (5 hunks)
  • packages/compiler/src/template/transform-srcset.ts (1 hunks)
  • packages/compiler/tests/transform.spec.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/compiler/tests/transform.spec.ts
  • packages/compiler/src/template/transform-asset-url.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/compiler/src/template/transform-srcset.ts (4)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
packages/compiler/src/template/compose.ts (11)
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有返回值为 tagged template string 且标签名为 `vine` 的函数将被视为组件函数
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: TypeScript Plugin 基于 Volar.js 的虚拟代码机制将 Vine 组件函数返回值上的 Vue 模板转换为虚拟代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: Vite 插件依赖 compiler 对 `.vine.ts` 文件中的 Vine 组件函数和样式代码进行转换
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 编译流程包括:读取文件内容、validate 校验文件、analyze 分析文件获取 Vine 组件函数上下文、transform 转换文件,将 Vine 组件函数转换为 Vue 组件对象的 JS 代码
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.680Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 @vue/compiler-dom 作为 Vue 模板的编译器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 通过 ESLint 规范化 Vue Vine 使用写法
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 使用 Babel 作为 AST 解析器
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-02T01:59:41.679Z
Learning: 项目主入口包导出核心方法(如 useDefaults)、Vite 插件、Slidev 插件
🧬 Code Graph Analysis (1)
packages/compiler/src/template/transform-srcset.ts (1)
packages/compiler/src/utils/template.ts (4)
  • isDataUrl (17-19)
  • isExternalUrl (12-14)
  • isRelativeUrl (6-9)
  • parseUrl (24-31)
⏰ 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: test (lts/*, macos-latest)
  • GitHub Check: test (lts/*, ubuntu-latest)
  • GitHub Check: test (lts/*, windows-latest)
🔇 Additional comments (2)
packages/compiler/src/template/compose.ts (2)

105-113: Well-structured transform integration

The integration of transformSrcset alongside transformAssetUrl is clean and follows the existing pattern. The conditional inclusion based on __enableTransformAssetsURL ensures backward compatibility.


115-121: Confirm Volar Exclusion for Vapor Mode

I wasn’t able to find any documentation or in-code comments explaining why Vapor mode is explicitly disabled when volar is true. This behavior will prevent users of the Volar IDE extension from leveraging Vapor mode compilation and could impact their development experience.

Please verify whether this condition is intentional. If so, consider adding a brief comment in packages/compiler/src/template/compose.ts (lines 115–121) to document the rationale. If not, you may want to adjust or remove the !volar check to allow Vapor mode under Volar.

• File: packages/compiler/src/template/compose.ts
Lines: 115–121

@vue-vine vue-vine deleted a comment from coderabbitai bot Jul 17, 2025
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: 1

🧹 Nitpick comments (1)
packages/vscode-ext/themes/rocking-vine.json (1)

613-615: Minor style nit – keep hex colour casing consistent

Most colour literals in the theme use upper-case hex (#FDC54DFF, #EB8888FF).
For consistency (and grep-ability), consider:

-        "foreground": "#bab699ff"
+        "foreground": "#BAB699FF"

(no functional change).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d751a2 and 89ce517.

⛔ Files ignored due to path filters (3)
  • packages/compiler/tests/__snapshots__/transform.spec.ts.snap is excluded by !**/*.snap
  • packages/language-service/tests/__snapshots__/virtual-code.spec.ts.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • eslint.config.js (1 hunks)
  • packages/compiler/src/analyze.ts (4 hunks)
  • packages/compiler/tests/transform.spec.ts (1 hunks)
  • packages/docs/src/.vitepress/config.ts (1 hunks)
  • packages/docs/src/specification/overview.md (1 hunks)
  • packages/docs/src/zh/specification/overview.md (1 hunks)
  • packages/e2e-test/src/fixtures/vapor-interop.vine.ts (1 hunks)
  • packages/e2e-test/tests/basic.spec.ts (1 hunks)
  • packages/vscode-ext/themes/rocking-vine.json (1 hunks)
  • pnpm-workspace.yaml (5 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/docs/src/.vitepress/config.ts
  • eslint.config.js
🚧 Files skipped from review as they are similar to previous changes (7)
  • packages/docs/src/specification/overview.md
  • packages/compiler/tests/transform.spec.ts
  • packages/docs/src/zh/specification/overview.md
  • packages/e2e-test/tests/basic.spec.ts
  • packages/e2e-test/src/fixtures/vapor-interop.vine.ts
  • pnpm-workspace.yaml
  • packages/compiler/src/analyze.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
🪛 Biome (1.9.4)
packages/vscode-ext/themes/rocking-vine.json

[error] 611-616: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 616-616: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

⏰ 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: test (lts/*, ubuntu-latest)
  • GitHub Check: test (lts/*, windows-latest)
  • GitHub Check: test (lts/*, macos-latest)

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 (1)
packages/e2e-test/utils/evaluator.ts (1)

127-146: Well-implemented image loading checker with a minor improvement opportunity.

The method correctly checks both complete and naturalWidth properties for reliable image load detection. The error handling is appropriate.

Apply the static analysis suggestion for better null safety:

-        await pageCtx.waitForFunction((selector) => {
-          const img = document.querySelector(selector) as HTMLImageElement
-          // An image is considered loaded if it's "complete" and has a natural width > 0.
-          return img && img.complete && img.naturalWidth > 0
-        }, selector)
+        await pageCtx.waitForFunction((selector) => {
+          const img = document.querySelector(selector) as HTMLImageElement
+          // An image is considered loaded if it's "complete" and has a natural width > 0.
+          return img?.complete && img.naturalWidth > 0
+        }, selector)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1794bf5 and a0e806b.

📒 Files selected for processing (2)
  • packages/e2e-test/tests/basic.spec.ts (2 hunks)
  • packages/e2e-test/utils/evaluator.ts (5 hunks)
🧠 Learnings (2)
📓 Common learnings
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/e2e-test/utils/evaluator.ts (1)

Learnt from: ShenQingchuan
PR: #265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the satisfies operator (e.g., (6 satisfies NodeTypes.ATTRIBUTE)) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.

🧬 Code Graph Analysis (1)
packages/e2e-test/utils/evaluator.ts (1)
packages/e2e-test/utils/types.ts (2)
  • Nil (4-4)
  • EvaluateResult (28-28)
🪛 Biome (1.9.4)
packages/e2e-test/utils/evaluator.ts

[error] 139-139: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/e2e-test/tests/basic.spec.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/e2e-test/utils/evaluator.ts (1)

Learnt from: ShenQingchuan
PR: #265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the satisfies operator (e.g., (6 satisfies NodeTypes.ATTRIBUTE)) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.

🧬 Code Graph Analysis (1)
packages/e2e-test/utils/evaluator.ts (1)
packages/e2e-test/utils/types.ts (2)
  • Nil (4-4)
  • EvaluateResult (28-28)
🪛 Biome (1.9.4)
packages/e2e-test/utils/evaluator.ts

[error] 139-139: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ 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: test (lts/*, ubuntu-latest)
  • GitHub Check: test (lts/*, macos-latest)
  • GitHub Check: test (lts/*, windows-latest)
🔇 Additional comments (4)
packages/e2e-test/utils/evaluator.ts (4)

2-2: LGTM! Import additions align with type system updates.

The new type imports are necessary for the refactored evaluator methods and return types.


17-17: Good type system improvement.

Expanding the return type to support boolean and null values makes the evaluator more versatile and type-safe.


29-38: Excellent refactoring to switch-case structure.

This improves code readability and maintainability while preserving the original logic. The switch-case is more appropriate for handling enumerated evaluation types.


56-88: Consistent return type improvements across evaluator methods.

Standardizing all evaluator methods to return EvaluateResult creates a unified, predictable API that's easier to work with.

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: 1

🧹 Nitpick comments (1)
packages/e2e-test/src/fixtures/vine-emits.vine.ts (1)

25-39: Consider improving type safety for event parameter.

The parent component correctly handles events from child components, but the event parameter in onEvent uses any type which reduces type safety.

Consider using a more specific type or union type for better type safety:

-  const onEvent = (event: any) => {
+  const onEvent = (event: string) => {
     console.log('accept event', event)
     count.value++
   }

Alternatively, if you need to handle different event types, use a union type like string | number or create a proper interface.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3fcf56f and 4a2d31b.

📒 Files selected for processing (4)
  • packages/e2e-test/src/app.vine.ts (1 hunks)
  • packages/e2e-test/src/fixtures/vine-emits.vine.ts (1 hunks)
  • packages/e2e-test/src/router.ts (2 hunks)
  • packages/e2e-test/tests/basic.spec.ts (3 hunks)
📓 Path-based instructions (1)
**/*.vine.ts

📄 CodeRabbit Inference Engine (.cursor/rules/vue-vine-repo-rules.mdc)

**/*.vine.ts: Vine 仅会处理文件名后缀为 .vine.ts 的文件
.vine.ts 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 vine 的字符串”,都将被视为一个组件函数

Files:

  • packages/e2e-test/src/fixtures/vine-emits.vine.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/e2e-test/src/fixtures/vine-emits.vine.ts (3)

Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 .vine.ts 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 vine 的字符串”,都将被视为一个组件函数

Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 .vine.ts 的文件

Learnt from: ShenQingchuan
PR: #265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the satisfies operator (e.g., (6 satisfies NodeTypes.ATTRIBUTE)) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.

🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/e2e-test/src/app.vine.ts
  • packages/e2e-test/src/router.ts
  • packages/e2e-test/tests/basic.spec.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.vine.ts

📄 CodeRabbit Inference Engine (.cursor/rules/vue-vine-repo-rules.mdc)

**/*.vine.ts: Vine 仅会处理文件名后缀为 .vine.ts 的文件
.vine.ts 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 vine 的字符串”,都将被视为一个组件函数

Files:

  • packages/e2e-test/src/fixtures/vine-emits.vine.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#283
File: packages/vscode-ext/package.json:105-110
Timestamp: 2025-06-17T14:54:18.385Z
Learning: The Vue Vine VSCode extension uses tsdown as a bundler that statically analyzes and includes all imported dependencies in the final bundle, regardless of whether they are listed in dependencies or devDependencies in packages/vscode-ext/package.json. Runtime dependencies can safely be placed in devDependencies since they will be bundled into the extension output.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数
Learnt from: ShenQingchuan
PR: vue-vine/vue-vine#265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the `satisfies` operator (e.g., `(6 satisfies NodeTypes.ATTRIBUTE)`) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件
packages/e2e-test/src/fixtures/vine-emits.vine.ts (3)

Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 .vine.ts 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 vine 的字符串”,都将被视为一个组件函数

Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 .vine.ts 的文件

Learnt from: ShenQingchuan
PR: #265
File: packages/compiler/src/template/transform-negative-bool.ts:13-14
Timestamp: 2025-05-26T13:09:15.829Z
Learning: In Vue Vine codebase, prefer using hardcoded numeric values with the satisfies operator (e.g., (6 satisfies NodeTypes.ATTRIBUTE)) instead of direct enum references. This reduces production bundle size by avoiding enum object embedding while maintaining TypeScript type checking functionality.

⏰ 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: test (lts/*, windows-latest)
  • GitHub Check: test (lts/*, macos-latest)
  • GitHub Check: test (lts/*, ubuntu-latest)
🔇 Additional comments (2)
packages/e2e-test/src/fixtures/vine-emits.vine.ts (2)

3-13: LGTM! Proper typed emits implementation.

The component correctly demonstrates typed emits using the generic signature with event name and payload type. The template properly calls the emits function with the correct parameters.


15-23: LGTM! Proper named emits implementation.

The component correctly demonstrates named emits using an array of event names. The implementation follows Vue Vine conventions properly.

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: 2

🧹 Nitpick comments (1)
packages/language-service/src/virtual-code.ts (1)

210-211: Good use of @ts-expect-error; add a concrete upstream issue link.

@ts-expect-error is correct here to guard against drift, but the comment should include a specific issue URL to aid future cleanup.

Proposed comment tweak (edit the existing line):

-            // @ts-expect-error - vue language tools upstream issue
+            // @ts-expect-error - tracked upstream in vue language tools: <insert issue URL/ID>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5410ef5 and e3f74ef.

⛔ Files ignored due to path filters (2)
  • packages/language-service/tests/__snapshots__/virtual-code.spec.ts.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/compiler/package.json (1 hunks)
  • packages/language-service/src/virtual-code.ts (3 hunks)
  • packages/vue-vine/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/vue-vine/package.json
  • packages/compiler/package.json
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-20T18:38:22.094Z
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : 在 `.vine.ts` 文件中,所有函数只要满足条件:“返回值是一个 tagged template string 且标签名必须是 `vine` 的字符串”,都将被视为一个组件函数

Applied to files:

  • packages/language-service/src/virtual-code.ts
📚 Learning: 2025-07-20T18:38:22.094Z
Learnt from: CR
PR: vue-vine/vue-vine#0
File: .cursor/rules/vue-vine-repo-rules.mdc:0-0
Timestamp: 2025-07-20T18:38:22.094Z
Learning: Applies to **/*.vine.ts : Vine 仅会处理文件名后缀为 `.vine.ts` 的文件

Applied to files:

  • packages/language-service/src/virtual-code.ts
⏰ 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: test (lts/*, macos-latest)
  • GitHub Check: test (lts/*, ubuntu-latest)
  • GitHub Check: test (lts/*, windows-latest)
🔇 Additional comments (1)
packages/language-service/src/virtual-code.ts (1)

123-139: Use path for file references and tighten relative-path logic

I searched packages/language-service for /// <reference types= usages and found none—so this is the sole triple-slash reference needing adjustment.

--- a/packages/language-service/src/virtual-code.ts
+++ b/packages/language-service/src/virtual-code.ts
@@ -123,16 +123,17 @@ export function generateVirtualCode(vineFileCtx: VineFileContext) {
   const globalTypesPath = vueCompilerOptions.globalTypesPath(vineFileCtx.fileId)
   if (globalTypesPath) {
     let relativePath = relative(
       dirname(vineFileCtx.fileId),
       globalTypesPath,
     )
-    if (
-      relativePath !== globalTypesPath
-      && !relativePath.startsWith('.')
-      && !relativePath.startsWith('..')
-    ) {
-      relativePath = `./${relativePath}`
-    }
+    // Only add "./" for truly relative paths
+    if (
+      !isAbsolute(relativePath)
+      && !relativePath.startsWith('.')
+      && !relativePath.startsWith('..')
+    ) {
+      relativePath = `./${relativePath}`
+    }
     // Normalize to POSIX separators
     relativePath = relativePath.replace(/\\/g, '/')
-    tsCodeSegments.push(`/// <reference types="${relativePath}" />\n`)
+    // Use `path` for file-based triple-slash refs (not `types`)
+    tsCodeSegments.push(`/// <reference path="${relativePath}" />\n`)
   }

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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd862d5 and 530e482.

📒 Files selected for processing (1)
  • packages/e2e-test/utils/test-utils.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/e2e-test/utils/test-utils.ts (1)
packages/e2e-test/utils/types.ts (1)
  • EvaluateResult (28-28)
⏰ 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: test (lts/*, windows-latest)
  • GitHub Check: test (lts/*, ubuntu-latest)
  • GitHub Check: test (lts/*, macos-latest)
🔇 Additional comments (2)
packages/e2e-test/utils/test-utils.ts (2)

114-118: Tiered backoff looks good and should reduce flakiness

The progressive delays (200ms → 100ms → 50ms) balance initial HMR/reload latency with tighter polling later. This is a sensible improvement.


2-2: No boolean-returning pollers in untilUpdated call sites

All inspected calls to untilUpdated in packages/e2e-test use string-returning pollers (e.g. getTextContent, getColor, getDisplayStyle). No inline boolean pollers were found, so the widened EvaluateResult type does not introduce unexpected behavior with existing usages. No further changes are required.

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: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e7fb61 and 5274062.

📒 Files selected for processing (1)
  • packages/e2e-test/tests/basic.spec.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/e2e-test/tests/basic.spec.ts (1)
packages/e2e-test/utils/test-utils.ts (1)
  • runTestAtPage (224-234)
⏰ 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). (5)
  • GitHub Check: e2e_tests (hmr, windows-latest)
  • GitHub Check: e2e_tests (hmr, macos-latest)
  • GitHub Check: e2e_tests (basic, windows-latest)
  • GitHub Check: unit_tests (lts/*, windows-latest)
  • GitHub Check: unit_tests (lts/*, macos-latest)

Comment on lines +38 to +42
expect(await evaluator.getAssetUrl('.test-transform-asset-url img[alt="sample"]')).toBe('/src/assets/sample.jpg')
expect(await evaluator.getAssetUrl('.test-transform-asset-url img[alt="placeholder"]')).toBe('https://placehold.co/200x100')

expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]')).toBe(true)
expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]')).toBe(true)
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Good selectors; guard against image-load flakiness (use polling and avoid remote dependency).

Splitting into alt-specific selectors is clearer. Two suggestions:

  • Poll for image load instead of asserting immediately to avoid flakiness on slow CI (especially for the remote image).
  • Prefer hosting/mocking the placeholder image locally (or fulfilling via Playwright route) to remove external network dependency in tests.

Apply this minimal change to poll until the images are loaded:

-        expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]')).toBe(true)
-        expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]')).toBe(true)
+        await untilUpdated(() => evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]'), true)
+        await untilUpdated(() => evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]'), true)

Optionally, intercept the remote URL in the test setup and fulfill with a small in-repo image to avoid external network calls.

Run this script to confirm the fixture alt attributes and helper presence:


🏁 Script executed:

#!/bin/bash
# Verify fixture markup and evaluator helper presence
rg -n 'alt="sample"|alt="placeholder"' packages/e2e-test/src/fixtures/transform-asset-url.vine.ts
rg -n "isImageLoaded" packages/e2e-test/utils

Length of output: 562


Use polling for image load assertions and mock external asset

The fixture and helper exist as expected, but direct expect calls can flake on CI when loading remote images. Update your test to:

  • Poll until isImageLoaded returns true using untilUpdated
  • Intercept the placeholder URL in your test setup and fulfill it with a small local asset

Changes in packages/e2e-test/tests/basic.spec.ts:

-        expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]')).toBe(true)
-        expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]')).toBe(true)
+        await untilUpdated(() => evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]'), true)
+        await untilUpdated(() => evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]'), true)

Tip: In your Playwright test setup, use page.route('https://placehold.co/200x100', route => route.fulfill({ path: 'path/to/local-placeholder.jpg' })) to eliminate external network dependency.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
expect(await evaluator.getAssetUrl('.test-transform-asset-url img[alt="sample"]')).toBe('/src/assets/sample.jpg')
expect(await evaluator.getAssetUrl('.test-transform-asset-url img[alt="placeholder"]')).toBe('https://placehold.co/200x100')
expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]')).toBe(true)
expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]')).toBe(true)
expect(await evaluator.getAssetUrl('.test-transform-asset-url img[alt="sample"]')).toBe('/src/assets/sample.jpg')
expect(await evaluator.getAssetUrl('.test-transform-asset-url img[alt="placeholder"]')).toBe('https://placehold.co/200x100')
- expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]')).toBe(true)
- expect(await evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]')).toBe(true)
+ await untilUpdated(() => evaluator.isImageLoaded('.test-transform-asset-url img[alt="sample"]'), true)
+ await untilUpdated(() => evaluator.isImageLoaded('.test-transform-asset-url img[alt="placeholder"]'), true)
🤖 Prompt for AI Agents
In packages/e2e-test/tests/basic.spec.ts around lines 38 to 42, the test
directly asserts image load and checks an external placeholder URL which can
flake on CI; update the test to poll until isImageLoaded returns true (use the
existing untilUpdated helper to retry the assertion) and in the test setup
intercept the external placeholder URL with page.route(...) and fulfill it with
a small local asset so the test does not depend on the network; ensure the
expectations use untilUpdated to wait for true before asserting and add a route
handler that fulfills 'https://placehold.co/200x100' with a local image path.

Comment on lines +259 to +281
it('should work in vapor interop mode', runTestAtPage(
'/vapor-interop',
browserCtx,
async () => {
expect(await evaluator.getTextContent('.test-vapor-comp h3')).toBe('Vapor Component in Virtual DOM component')
expect(await evaluator.getTextContent('.test-vdom-comp h3')).toBe('Virtual DOM Component in Vapor slot')

await browserCtx.page?.fill('.test-vdom-comp input', 'hello')
expect(await evaluator.getTextContent('.test-vdom-comp p')).toBe('hello')

expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 0')
await browserCtx.page?.click('.test-vapor-comp button')
expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 1')

expect(await evaluator.getTextContent('.test-another-vapor-comp span')).toBe('Another Vapor Component')

expect(await evaluator.getAssetUrl('img[alt="sample-img-in-vapor-comp"]')).toBe('/src/assets/sample.jpg')
expect(await evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]')).toBe(true)

expect(await evaluator.getAssetUrl('img[alt="remote-img-as-placeholder"]')).toBe('https://placehold.co/200x100')
expect(await evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]')).toBe(true)
},
))
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Solid Vapor interop coverage; tighten reliability (no optional chaining on critical actions; poll image loads).

The test covers VDOM↔Vapor interop well. For reliability:

  • Use non-null assertion on page to fail fast instead of optional chaining.
  • Poll for image loads to avoid timing issues (network and rendering).

Apply these targeted changes:

-      await browserCtx.page?.fill('.test-vdom-comp input', 'hello')
+      await browserCtx.page!.fill('.test-vdom-comp input', 'hello')
       expect(await evaluator.getTextContent('.test-vdom-comp p')).toBe('hello')

       expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 0')
-      await browserCtx.page?.click('.test-vapor-comp button')
+      await browserCtx.page!.click('.test-vapor-comp button')
       expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 1')

       expect(await evaluator.getTextContent('.test-another-vapor-comp span')).toBe('Another Vapor Component')

       expect(await evaluator.getAssetUrl('img[alt="sample-img-in-vapor-comp"]')).toBe('/src/assets/sample.jpg')
-      expect(await evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]')).toBe(true)
+      await untilUpdated(() => evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]'), true)

       expect(await evaluator.getAssetUrl('img[alt="remote-img-as-placeholder"]')).toBe('https://placehold.co/200x100')
-      expect(await evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]')).toBe(true)
+      await untilUpdated(() => evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]'), true)

If flakiness persists due to the remote placeholder, consider intercepting the request and fulfilling with a local fixture.

Quick verification of route and fixture selectors:


🏁 Script executed:

#!/bin/bash
# Check that the /vapor-interop route and expected alt attrs exist
rg -n "/vapor-interop" packages/e2e-test/src/router.ts
rg -n 'alt="sample-img-in-vapor-comp"|alt="remote-img-as-placeholder"' packages/e2e-test/src/fixtures/vapor-interop.vine.ts

Length of output: 498


Here’s a quick check for the proposed utilities:

If untilUpdated isn’t found, you’ll need to import or define it (e.g. from your E2E utils or switch to Playwright’s page.waitForFunction()).

Once that’s resolved, apply these edits to tighten failure visibility and stabilize image assertions:

Replace optional chaining with non-null assertions:

- await browserCtx.page?.fill('.test-vdom-comp input', 'hello')
+ await browserCtx.page!.fill('.test-vdom-comp input', 'hello')

- await browserCtx.page?.click('.test-vapor-comp button')
+ await browserCtx.page!.click('.test-vapor-comp button')

Poll for asset load completion:

- expect(await evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]')).toBe(true)
+ await untilUpdated(() => evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]'), true)

- expect(await evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]')).toBe(true)
+ await untilUpdated(() => evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]'), true)

If you don’t already have untilUpdated, either:

  • Import it from your E2E utils (e.g. import { untilUpdated } from '../utils';),
  • Or replace with Playwright’s page.waitForFunction().

🏁 Script executed:

#!/bin/bash
# Does `untilUpdated` exist anywhere in the codebase?
rg -n "untilUpdated" -t ts

Length of output: 2376


Tighten E2E actions & stabilize image loads

To surface missing‐page errors and avoid flaky image assertions, apply these changes in packages/e2e-test/tests/basic.spec.ts:

  • Replace optional chaining on browserCtx.page

    - await browserCtx.page?.fill('.test-vdom-comp input', 'hello')
    + await browserCtx.page!.fill('.test-vdom-comp input', 'hello')
    
    - await browserCtx.page?.click('.test-vapor-comp button')
    + await browserCtx.page!.click('.test-vapor-comp button')
  • Poll for asset loads with the existing untilUpdated helper

    - expect(await evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]')).toBe(true)
    + await untilUpdated(() => evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]'), true)
    
    - expect(await evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]')).toBe(true)
    + await untilUpdated(() => evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]'), true)

Note: untilUpdated is already defined in packages/e2e-test/utils/test-utils.ts and imported at the top of this spec. If you still see flakiness on the remote placeholder, consider intercepting its request or serving a local fixture for consistent network behavior.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('should work in vapor interop mode', runTestAtPage(
'/vapor-interop',
browserCtx,
async () => {
expect(await evaluator.getTextContent('.test-vapor-comp h3')).toBe('Vapor Component in Virtual DOM component')
expect(await evaluator.getTextContent('.test-vdom-comp h3')).toBe('Virtual DOM Component in Vapor slot')
await browserCtx.page?.fill('.test-vdom-comp input', 'hello')
expect(await evaluator.getTextContent('.test-vdom-comp p')).toBe('hello')
expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 0')
await browserCtx.page?.click('.test-vapor-comp button')
expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 1')
expect(await evaluator.getTextContent('.test-another-vapor-comp span')).toBe('Another Vapor Component')
expect(await evaluator.getAssetUrl('img[alt="sample-img-in-vapor-comp"]')).toBe('/src/assets/sample.jpg')
expect(await evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]')).toBe(true)
expect(await evaluator.getAssetUrl('img[alt="remote-img-as-placeholder"]')).toBe('https://placehold.co/200x100')
expect(await evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]')).toBe(true)
},
))
it('should work in vapor interop mode', runTestAtPage(
'/vapor-interop',
browserCtx,
async () => {
expect(await evaluator.getTextContent('.test-vapor-comp h3')).toBe('Vapor Component in Virtual DOM component')
expect(await evaluator.getTextContent('.test-vdom-comp h3')).toBe('Virtual DOM Component in Vapor slot')
await browserCtx.page!.fill('.test-vdom-comp input', 'hello')
expect(await evaluator.getTextContent('.test-vdom-comp p')).toBe('hello')
expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 0')
await browserCtx.page!.click('.test-vapor-comp button')
expect(await evaluator.getTextContent('.test-vapor-comp p')).toBe('Count: 1')
expect(await evaluator.getTextContent('.test-another-vapor-comp span')).toBe('Another Vapor Component')
expect(await evaluator.getAssetUrl('img[alt="sample-img-in-vapor-comp"]')).toBe('/src/assets/sample.jpg')
await untilUpdated(() => evaluator.isImageLoaded('img[alt="sample-img-in-vapor-comp"]'), true)
expect(await evaluator.getAssetUrl('img[alt="remote-img-as-placeholder"]')).toBe('https://placehold.co/200x100')
await untilUpdated(() => evaluator.isImageLoaded('img[alt="remote-img-as-placeholder"]'), true)
},
))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant