Vue复杂度

caiuswang2026-10-26查看 178复制 717

Vue 3 SFC 的复杂度阈值 - <script>/<script setup> 块的圈复杂度(每个函数和聚合)加上定制模板指标(嵌套深度、指令密度、条件/循环分支、元素计数、绑定计数)。由通用 BundleEngine 在每次 .vue 编辑时强制执行。

Download (.md)

📘如何使用这个技能

  1. 1
    复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
  2. 2
    打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
  3. 3
    粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
  4. 4
    直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景

💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。

SKILL.md5015 chars
---
title: "vue-complexity"
description: "Complexity thresholds for Vue 3 SFCs — cyclomatic complexity of the <script>/<script setup> block (per-function and aggregate) plus bespoke template metrics (nesting depth, directive density, conditional/loop branches, element count, binding count). Enforced by the generic BundleEngine on every .vue edit."
procedure: vue-complexity
source_repos: [regin]
manual: true
---

# vue-complexity

Use this skill when writing or editing `.vue` files — or the `.js`/`.ts`
composables and utils a component's logic is extracted into — in this repo.
regin runs a complexity rule bundle on every such edit and warns when the code
crosses the configured thresholds. Keep edits under these limits, or split the
component / function.

The JS/TS check exists so that splitting a god-component into a composable
*actually* reduces complexity instead of relocating it to an unchecked file.

## What is measured

Three families. The `.vue` script + template are parsed from the SFC by
`@vue/compiler-sfc`; the JS/TS check runs on raw module files.

### Script (`<script>` / `<script setup>`)

Cyclomatic complexity is computed over the script block with `@babel/parser`.
Because `<script setup>` puts logic at module top level (outside any function),
the bundle reports BOTH a per-function score and a whole-script aggregate — the
aggregate is what catches an over-loaded `setup` that per-function tools miss.

| Rule | Metric | Threshold |
|------|--------|-----------|
| `vue.script.cyclomatic-function` | max per-function cyclomatic complexity | 15 |
| `vue.script.cyclomatic-module` | whole-script aggregate cyclomatic complexity | 130 |
| `vue.script.function-length` | longest function, in lines | 60 |
| `vue.script.surface-area` | top-level reactive decls + functions | 45 |

`surface-area` is the **god-component** signal the cyclomatic checks miss: many
*simple* refs and functions for many unrelated concerns keep per-function CC low
while the component is still far too large to navigate. `useX()` composable
calls are excluded from the count, so the fix — grouping related state + logic
into composables — directly lowers the score. (Calibration anecdote: the
`SessionTraceView.vue` god-component scored 89; extracting its concerns into
composables dropped it to 17.)

### Template (`<template>`)

No off-the-shelf tool computes these; they are bespoke metrics over the
`@vue/compiler-dom` template AST.

| Rule | Metric | Threshold |
|------|--------|-----------|
| `vue.template.max-depth` | element nesting depth | 10 |
| `vue.template.directive-density` | total `v-*` directives | 130 |
| `vue.template.conditional-loop` | `v-if`/`v-else-if`/`v-for` branches | 45 |
| `vue.template.node-count` | template element count | 180 |
| `vue.template.binding-count` | `{{ }}` interpolations + bound attrs | 100 |

### JS / TS modules (`composables/`, `utils/`, `src/`)

Only **per-function** cyclomatic complexity — the same `@babel/parser` analysis
as the SFC script check, run on raw `.js`/`.ts` files.

| Rule | Metric | Threshold |
|------|--------|-----------|
| `js.script.cyclomatic-function` | max per-function cyclomatic complexity | 15 |

Length and module-aggregate are intentionally **not** applied to JS modules: a
composable's `useX()` wrapper spans the whole file, so those metrics would
false-positive on every composable. Per-function CC is wrapper-safe — the
wrapper is mostly declarations (low CC), so only branchy *inner* functions trip
it. So a long composable is fine; a complex *function* inside it is not.

Thresholds are calibrated to roughly the 90th–95th percentile of this repo's
own `frontend/src/**/*.vue` files (see `references/calibration.json`), so they
flag genuine outliers — not the median component.

## How to apply

When a warning fires, reduce the offending metric rather than suppressing it:

- **High script complexity** → extract helpers, collapse nested conditionals,
  or move logic into a composable (`use*`) / plain module.
- **High template complexity** → extract inner blocks into child components or
  slots; push branching into `computed` state.

## Verify locally

Recompute the metrics for the whole frontend and re-derive thresholds:

```bash
cd ~/.local/share/regin/patterns/vue-complexity
node references/calibrate.mjs /path/to/repo/frontend/src
```

Run a single checker against one file (the runner's JSON-stdin contract):

```bash
echo '{"file_path":"/abs/path/Foo.vue","rule":{"checker":"template_max_depth","options":{"threshold":10}}}' \
  | node bin/vue-complexity-runner.mjs
```

A relative `file_path` is resolved against `repo_root`, not the shell's cwd — so
the same payload measures whichever checkout you name:

```bash
echo '{"repo_root":"/path/to/repo","file_path":"frontend/src/Foo.vue","rule":{"checker":"template_max_depth","options":{"threshold":10}}}' \
  | node bin/vue-complexity-runner.mjs
```

A target that doesn't exist exits `2` with the resolved path on stderr rather
than reporting zero matches.
来源:skillsdirectory

评论0

登录后参与评论

还没有评论,来抢沙发吧