vue-doctor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Vue Doctor Skill

Vue Doctor Skill

Diagnose Vue.js / Nuxt projects for health issues and auto-fix them. One command runs four engines in parallel (oxlint, eslint-plugin-vue, custom Vue rules, knip) and returns a 0–100 health score with actionable diagnostics.
诊断Vue.js / Nuxt项目的健康问题并自动修复。一条命令即可并行运行四个引擎(oxlint、eslint-plugin-vue、自定义Vue规则、knip),并返回0-100的健康评分及可执行的诊断结果。

When to use

使用场景

  • The user asks to check, diagnose, audit, or fix a Vue/Nuxt project
  • Reviewing Vue components for anti-patterns before a commit or PR
  • Gating a build on code health in CI
  • The user says "run vue-doctor" or "check my Vue project"
  • 用户需要检查、诊断、审计或修复Vue/Nuxt项目
  • 在提交代码或创建PR前检查Vue组件中的反模式
  • 在CI流程中基于代码健康度控制构建
  • 用户提出"运行vue-doctor"或"检查我的Vue项目"需求

Pick the right command

选择合适的命令

GoalCommand
Auto-fix issues (agents — start here)
npx vue-doctor@latest . --json
Human-readable scan
npx vue-doctor@latest . --verbose
Only changed files (fast PR check)
npx vue-doctor@latest . --diff main --json
CI gate (fail under a threshold)
npx vue-doctor@latest . --min-score 80
Score only
npx vue-doctor@latest . --score
--no-dead-code
and
--no-lint
skip those engines.
--diff
automatically skips dead-code analysis (it needs the whole project).
目标命令
自动修复问题(Agent推荐首选)
npx vue-doctor@latest . --json
人类可读格式扫描结果
npx vue-doctor@latest . --verbose
仅检查变更文件(快速PR检查)
npx vue-doctor@latest . --diff main --json
CI门禁(低于阈值则构建失败)
npx vue-doctor@latest . --min-score 80
仅获取评分
npx vue-doctor@latest . --score
--no-dead-code
--no-lint
参数可跳过对应引擎。
--diff
参数会自动跳过死代码分析(该分析需要完整项目)。

Auto-fix workflow (for AI / coding agents)

自动修复工作流(适用于AI/编码Agent)

Always use
--json
— it emits a stable, parseable document with no colors or spinner noise. Do not parse the human/
--fix
output.
  1. Run
    npx vue-doctor@latest . --json
    (add
    --diff main
    to scope to the PR).
  2. Parse the JSON. Each entry in
    diagnostics[]
    has:
    file
    ,
    line
    ,
    column
    ,
    severity
    ,
    category
    ,
    rule
    ,
    message
    ,
    fix
    .
  3. For each diagnostic, open
    file
    at
    line:column
    , apply the
    fix
    guidance (see the rule table below), and edit the code.
  4. Fix
    severity: "error"
    items first, then
    warning
    .
  5. Re-run
    --json
    and confirm
    score.value
    went up and
    summary.errors
    dropped.
请始终使用
--json
参数
——它会输出稳定、可解析的文档,不包含颜色或加载动画干扰信息。请勿解析人类可读格式/
--fix
参数的输出。
  1. 运行
    npx vue-doctor@latest . --json
    (添加
    --diff main
    参数可限定为PR范围内的文件)。
  2. 解析JSON结果。
    diagnostics[]
    中的每个条目包含:
    file
    (文件)、
    line
    (行号)、
    column
    (列号)、
    severity
    (严重程度)、
    category
    (类别)、
    rule
    (规则)、
    message
    (提示信息)、
    fix
    (修复方案)。
  3. 针对每个诊断结果,打开对应
    file
    文件并定位到
    line:column
    位置,按照
    fix
    中的指导方案(参考下方规则表)修改代码。
  4. 优先修复
    severity: "error"
    级别的问题,再处理
    warning
    级别的问题。
  5. 重新运行
    --json
    命令,确认
    score.value
    提升且
    summary.errors
    数量减少。

JSON shape

JSON结果结构

json
{
  "schema": "vue-doctor/diagnosis@1",
  "score": { "value": 82, "label": "Great" },
  "project": { "framework": "nuxt3", "vueVersion": "^3.4.0", "typescript": true },
  "summary": { "total": 5, "errors": 1, "warnings": 4, "byCategory": { "Reactivity": 2 } },
  "diagnostics": [
    {
      "file": "src/components/User.vue",
      "line": 12, "column": 1,
      "severity": "error",
      "category": "Reactivity",
      "rule": "vue-doctor/reactivity-destructure-props",
      "message": "Destructuring props loses reactivity in Vue 3",
      "fix": "Use toRefs(props) or access props.xxx directly"
    }
  ],
  "diff": null,
  "elapsedMs": 1240
}
json
{
  "schema": "vue-doctor/diagnosis@1",
  "score": { "value": 82, "label": "Great" },
  "project": { "framework": "nuxt3", "vueVersion": "^3.4.0", "typescript": true },
  "summary": { "total": 5, "errors": 1, "warnings": 4, "byCategory": { "Reactivity": 2 } },
  "diagnostics": [
    {
      "file": "src/components/User.vue",
      "line": 12, "column": 1,
      "severity": "error",
      "category": "Reactivity",
      "rule": "vue-doctor/reactivity-destructure-props",
      "message": "Destructuring props loses reactivity in Vue 3",
      "fix": "Use toRefs(props) or access props.xxx directly"
    }
  ],
  "diff": null,
  "elapsedMs": 1240
}

Exit codes (CI / scripting)

退出码(适用于CI/脚本)

  • 0
    — completed (and, if
    --min-score
    was set, score met the threshold)
  • 1
    — score below
    --min-score
    , or the scan failed (no Vue project, etc.)
bash
npx vue-doctor@latest . --min-score 80   # exits 1 if health < 80
  • 0
    — 执行完成(若设置了
    --min-score
    ,则表示评分达到阈值)
  • 1
    — 评分低于
    --min-score
    阈值,或扫描失败(如未检测到Vue项目等)
bash
npx vue-doctor@latest . --min-score 80   # exits 1 if health < 80

Score interpretation

评分解读

  • 80–100 (Great): healthy project, minor optimizations only
  • 50–79 (Needs work): several issues to address
  • 0–49 (Critical): major problems needing urgent attention
  • 80–100分(优秀): 项目健康,仅需少量优化
  • 50–79分(待改进): 存在多个需要解决的问题
  • 0–49分(严重): 存在重大问题,需紧急处理

Diagnostic categories

诊断类别

Reactivity · Performance · Security · Correctness · Accessibility · Architecture · Best Practices · Nuxt · Dead Code
响应式 · 性能 · 安全 · 正确性 · 可访问性 · 架构 · 最佳实践 · Nuxt · 死代码

Rule → fix reference

规则→修复方案参考

RuleHow to fix
reactivity-destructure-props
Use
toRefs(props)
or access
props.xxx
directly
reactivity-reactive-reassign
Use
Object.assign(state, newData)
instead of
state = newData
reactivity-ref-no-value
Add
.value
when reading/writing refs in
<script>
pinia-no-store-to-refs
Wrap with
storeToRefs()
:
const { count } = storeToRefs(store)
pinia-direct-state-mutation
Use store actions or
$patch()
correctness-mutating-props
Emit an event to the parent, or copy the prop into local
ref
/
computed
perf-giant-component
Extract sub-components to get the file under 300 lines
perf-v-for-method-call
Replace the in-template method call with a
computed
perf-v-if-with-v-for
Move
v-if
to a wrapper
<template>
, or pre-filter with a
computed
a11y-img-no-alt
Add an
alt
attribute (
alt=""
for decorative images)
security-v-html
Sanitize HTML (e.g. DOMPurify) or use
{{ }}
interpolation
nuxt-fetch-in-mounted
Move
useFetch
/
useAsyncData
to the top level of
<script setup>
nuxt-no-navigate-to-in-setup
return navigateTo('/path')
from setup
arch-mixed-api-styles
Migrate to Composition API with
<script setup>
规则修复方法
reactivity-destructure-props
使用
toRefs(props)
或直接访问
props.xxx
reactivity-reactive-reassign
使用
Object.assign(state, newData)
替代
state = newData
reactivity-ref-no-value
<script>
中读取/写入refs时添加
.value
pinia-no-store-to-refs
使用
storeToRefs()
包裹:
const { count } = storeToRefs(store)
pinia-direct-state-mutation
使用store的actions或
$patch()
方法
correctness-mutating-props
向父组件触发事件,或将prop复制到本地
ref
/
computed
perf-giant-component
提取子组件,将文件行数控制在300行以内
perf-v-for-method-call
将模板中的方法调用替换为
computed
属性
perf-v-if-with-v-for
v-if
移到包裹用的
<template>
上,或提前用
computed
过滤数据
a11y-img-no-alt
添加
alt
属性(装饰性图片使用
alt=""
security-v-html
对HTML进行 sanitize 处理(例如使用DOMPurify)或使用
{{ }}
插值语法
nuxt-fetch-in-mounted
useFetch
/
useAsyncData
移到
<script setup>
的顶层
nuxt-no-navigate-to-in-setup
在setup中返回
navigateTo('/path')
arch-mixed-api-styles
迁移到使用
<script setup>
的Composition API

Node.js API

Node.js API

For programmatic use in custom scripts:
typescript
import { diagnose } from "@healerlab/vue-doctor/api";

const result = await diagnose("./path/to/vue-project");
console.log(result.score);       // { score: 82, label: "Great" }
console.log(result.diagnostics); // Array<Diagnostic>
用于自定义脚本中的程序化调用:
typescript
import { diagnose } from "@healerlab/vue-doctor/api";

const result = await diagnose("./path/to/vue-project");
console.log(result.score);       // { score: 82, label: "Great" }
console.log(result.diagnostics); // Array<Diagnostic>

Configuration

配置

Users can ignore rules/files via
.vue-doctorrc
in the project root:
json
{
  "ignore": {
    "rules": ["vue/no-v-html"],
    "files": ["src/generated/**"]
  }
}
用户可通过项目根目录下的
.vue-doctorrc
文件忽略指定规则/文件:
json
{
  "ignore": {
    "rules": ["vue/no-v-html"],
    "files": ["src/generated/**"]
  }
}