Vue复杂度
caiuswang2026-10-26查看 178复制 717
Vue 3 SFC 的复杂度阈值 - <script>/<script setup> 块的圈复杂度(每个函数和聚合)加上定制模板指标(嵌套深度、指令密度、条件/循环分支、元素计数、绑定计数)。由通用 BundleEngine 在每次 .vue 编辑时强制执行。
📘如何使用这个技能
- 1复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
- 2打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
- 3粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
- 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.