105 lines
4.0 KiB
Markdown
105 lines
4.0 KiB
Markdown
|
|
# 最小验证(Validation)
|
|||
|
|
|
|||
|
|
在本仓库验证:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
pnpm i
|
|||
|
|
pnpm run serve
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
迁移到新仓库后,至少验证:
|
|||
|
|
|
|||
|
|
- 首页可渲染(Layout 正常)
|
|||
|
|
- 路由跳转正常
|
|||
|
|
- Pinia 与 i18n 可注入
|
|||
|
|
- Mock 请求可命中(开发环境)
|
|||
|
|
|
|||
|
|
建议附加:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
pnpm run lint
|
|||
|
|
pnpm run test:unit
|
|||
|
|
pnpm run build
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 文档/清单对账(防止漏登记模块)
|
|||
|
|
|
|||
|
|
对账 `library/components/*` 是否都已登记到 `AI-Coding/openspec-lite/manifest.yaml`:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
$repo = (Get-Location).Path;
|
|||
|
|
$componentDirs = Get-ChildItem -LiteralPath "$repo\library\components" -Directory | Select-Object -ExpandProperty Name | Sort-Object;
|
|||
|
|
$manifest = Get-Content -LiteralPath "$repo\AI-Coding\openspec-lite\manifest.yaml" -Raw;
|
|||
|
|
$manifestComponents = [regex]::Matches($manifest,'library/components/(?<name>Vab[^/]+)/') | ForEach-Object { $_.Groups['name'].Value } | Sort-Object -Unique;
|
|||
|
|
Compare-Object -ReferenceObject $componentDirs -DifferenceObject $manifestComponents
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
对账 `library/layouts/*` 子目录是否都被 `AI-Coding/openspec-lite/modules/layouts.yaml` 覆盖:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
$repo = (Get-Location).Path;
|
|||
|
|
$layoutDirs = Get-ChildItem -LiteralPath "$repo\library\layouts" -Directory | Select-Object -ExpandProperty Name | Sort-Object;
|
|||
|
|
$layoutsSpec = Get-Content -LiteralPath "$repo\AI-Coding\openspec-lite\modules\layouts.yaml" -Raw;
|
|||
|
|
$specDirs = [regex]::Matches($layoutsSpec,'library/layouts/(?<name>VabLayout[^/]+)/') | ForEach-Object { $_.Groups['name'].Value } | Sort-Object -Unique;
|
|||
|
|
Compare-Object -ReferenceObject $layoutDirs -DifferenceObject $specDirs
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
对账 `components.d.ts` 里自动导入的 `Vab*` 组件是否都被任一 module spec 覆盖(按源文件路径精确匹配):
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
$repo = (Get-Location).Path;
|
|||
|
|
$dtsPath = "$repo\library\build\vuePlugins\components.d.ts";
|
|||
|
|
$specDir = "$repo\AI-Coding\openspec-lite\modules";
|
|||
|
|
|
|||
|
|
$dts = Get-Content -LiteralPath $dtsPath -Raw;
|
|||
|
|
$specText = (Get-ChildItem -LiteralPath $specDir -Filter '*.yaml' | ForEach-Object { Get-Content -LiteralPath $_.FullName -Raw }) -join "`n---`n";
|
|||
|
|
|
|||
|
|
$imports = [regex]::Matches(
|
|||
|
|
$dts,
|
|||
|
|
"Vab[A-Za-z0-9_]+:\\s*typeof\\s+import\\('(?<p>[^']+)'\\)\\['default'\\]",
|
|||
|
|
[System.Text.RegularExpressions.RegexOptions]::Multiline
|
|||
|
|
) | ForEach-Object { $_.Groups['p'].Value } | Where-Object { $_ -like '*components*' } | ForEach-Object {
|
|||
|
|
$p = $_;
|
|||
|
|
$p = $p -replace "^\\./\\.\\./\\.\\./","";
|
|||
|
|
$p = $p -replace "^\\./\\.\\./","";
|
|||
|
|
$p = $p -replace "^\\./","";
|
|||
|
|
if ($p -like 'components/*') { $p = "library/" + $p }
|
|||
|
|
$p
|
|||
|
|
} | Sort-Object -Unique;
|
|||
|
|
|
|||
|
|
$missing = foreach ($p in $imports) { if ($specText -notmatch [regex]::Escape($p)) { $p } };
|
|||
|
|
if ($missing) { $missing } else { '(none)' }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
对账 `src/router/index.ts` 引用的 `@/views/*.vue` 是否都存在,并列出未被路由引用的 views:
|
|||
|
|
|
|||
|
|
```powershell
|
|||
|
|
$repo = (Get-Location).Path;
|
|||
|
|
$routerPath = "$repo\src\router\index.ts";
|
|||
|
|
$viewsRoot = "$repo\src\views";
|
|||
|
|
|
|||
|
|
$router = Get-Content -LiteralPath $routerPath -Raw;
|
|||
|
|
# 只提取“非注释行”中的 views 引用,避免把 // 注释的 demo 路由当成缺失文件
|
|||
|
|
$routeViewRefs = [regex]::Matches(
|
|||
|
|
$router,
|
|||
|
|
"(?m)^(?!\\s*//).*@/views/(?<p>[^'\\\"\\)]+\\.vue)",
|
|||
|
|
[System.Text.RegularExpressions.RegexOptions]::Multiline
|
|||
|
|
) | ForEach-Object { $_.Groups['p'].Value } | Sort-Object -Unique;
|
|||
|
|
|
|||
|
|
$missingFiles = foreach ($p in $routeViewRefs) {
|
|||
|
|
$abs = Join-Path $viewsRoot ($p -replace '/', '\\');
|
|||
|
|
if (-not (Test-Path -LiteralPath $abs)) { "src/views/$p" }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
$allViews = Get-ChildItem -LiteralPath $viewsRoot -Recurse -File -Filter '*.vue' | ForEach-Object {
|
|||
|
|
$_.FullName.Substring($viewsRoot.Length + 1).Replace('\\','/')
|
|||
|
|
} | Sort-Object -Unique;
|
|||
|
|
|
|||
|
|
$unreferenced = Compare-Object -ReferenceObject $allViews -DifferenceObject $routeViewRefs -PassThru | Where-Object { $_ -in $allViews } | Sort-Object;
|
|||
|
|
|
|||
|
|
'--- router references missing files ---';
|
|||
|
|
if ($missingFiles) { $missingFiles } else { '(none)' };
|
|||
|
|
'--- views not referenced by router ---';
|
|||
|
|
if ($unreferenced) { $unreferenced | ForEach-Object { "src/views/$_" } } else { '(none)' };
|
|||
|
|
```
|