Files
Web_Template_Vue3_Dev/AI-Coding/Validation.md

4.0 KiB
Raw Permalink Blame History

最小验证Validation

在本仓库验证:

pnpm i
pnpm run serve

迁移到新仓库后,至少验证:

  • 首页可渲染Layout 正常)
  • 路由跳转正常
  • Pinia 与 i18n 可注入
  • Mock 请求可命中(开发环境)

建议附加:

pnpm run lint
pnpm run test:unit
pnpm run build

文档/清单对账(防止漏登记模块)

对账 library/components/* 是否都已登记到 AI-Coding/openspec-lite/manifest.yaml

$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 覆盖:

$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 覆盖(按源文件路径精确匹配):

$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

$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)' };