1. 抽离底部导航归属逻辑为纯函数resolveEntryTab,优化分包页面高亮规则,对齐iOS HIG规范 2. 新增页面Tab通配符映射,简化PAGE_TAB_MAP维护 3. 修复鸿蒙平台webview返回按钮适配问题 4. 新增pages.json校验与导航标题自动注入脚本 5. 优化启动页动画性能,提升合成渲染效率 6. 修复diy-picture组件v-for缺少key的警告 7. 清理鸿蒙平台多余的分包构建配置 8. 更新统计数据与store注释说明
105 lines
3.2 KiB
JavaScript
105 lines
3.2 KiB
JavaScript
/**
|
|
* 验证 pages.json 的所有 page.style 块都已经有 navigationBarTitleText 字段,
|
|
* 且都在 // #ifdef / // #ifndef 块之外 (保证所有平台生效).
|
|
*
|
|
* 运行: node scripts/verify-nav-title.js
|
|
*/
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const PAGES_JSON = path.join(__dirname, '..', 'pages.json');
|
|
const s = fs.readFileSync(PAGES_JSON, 'utf-8');
|
|
const lines = s.split(/\r?\n/);
|
|
|
|
let i = 0;
|
|
let totalStyle = 0, totalNavTitle = 0, insideIfdef = 0, doubleTitle = 0, missingTitle = [];
|
|
// 跟踪 subPackage 上下文, 让 missing-title 报出全路径 (root/path), 不只是 path
|
|
let currentSubRoot = null;
|
|
|
|
while (i < lines.length) {
|
|
// 跟踪 subPackage 的 root, 找路径时回退可见
|
|
const rootMatch = lines[i].match(/^\s*"root"\s*:\s*"([^"]+)"/);
|
|
if (rootMatch) {
|
|
currentSubRoot = rootMatch[1];
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
const m = lines[i].match(/^(\s*)"style"\s*:\s*\{\s*,?\s*$/);
|
|
if (m) {
|
|
totalStyle++;
|
|
const blockStart = i;
|
|
i++;
|
|
const bodyStart = i;
|
|
let depth = 1;
|
|
while (i < lines.length && depth > 0) {
|
|
const c = lines[i];
|
|
let b = 0;
|
|
let inS = false, e = false;
|
|
for (let k = 0; k < c.length; k++) {
|
|
const ch = c[k];
|
|
if (inS) {
|
|
if (e) e = false;
|
|
else if (ch === '\\') e = true;
|
|
else if (ch === '"') inS = false;
|
|
} else {
|
|
if (ch === '/' && c[k + 1] === '/') break;
|
|
if (ch === '"') inS = true;
|
|
else if (ch === '{') b++;
|
|
else if (ch === '}') b--;
|
|
}
|
|
}
|
|
depth += b;
|
|
i++;
|
|
}
|
|
const body = lines.slice(bodyStart, i - 1);
|
|
const titleIdxs = body
|
|
.map((l, idx) => /^\s*"navigationBarTitleText"\s*:/.test(l) ? idx : -1)
|
|
.filter(x => x >= 0);
|
|
totalNavTitle += titleIdxs.length;
|
|
if (titleIdxs.length > 1) doubleTitle++;
|
|
|
|
// 找最近的 path 行, 若处于 subPackage 则补上 root 前缀, 报全路径
|
|
let pathLine = '';
|
|
for (let k = blockStart - 1; k >= 0; k--) {
|
|
const pm = lines[k].match(/^\s*"path"\s*:\s*"([^"]+)"/);
|
|
if (pm) {
|
|
pathLine = pm[1];
|
|
break;
|
|
}
|
|
// 跨过 subPackage 边界 (遇到另一个 root) 视为顶层 pages
|
|
const rm = lines[k].match(/^\s*"root"\s*:\s*"([^"]+)"/);
|
|
if (rm) {
|
|
currentSubRoot = rm[1];
|
|
break;
|
|
}
|
|
}
|
|
if (titleIdxs.length === 0) {
|
|
// 只在缺标题时, 用 currentSubRoot 校正路径
|
|
// (找 path 时可能已被同包兄弟 root 行先 break 出, 这里用循环外的 currentSubRoot)
|
|
const fullPath = pathLine && currentSubRoot ? `${currentSubRoot}/${pathLine}` : pathLine;
|
|
missingTitle.push(fullPath);
|
|
} else {
|
|
for (const tIdx of titleIdxs) {
|
|
let d = 0;
|
|
for (let k = 0; k < tIdx; k++) {
|
|
const t = body[k];
|
|
if (/^\s*\/\/\s*#(ifdef|ifndef)\b/.test(t)) d++;
|
|
else if (/^\s*\/\/\s*#endif\b/.test(t)) d--;
|
|
}
|
|
if (d >= 1) insideIfdef++;
|
|
}
|
|
}
|
|
} else {
|
|
i++;
|
|
}
|
|
}
|
|
|
|
console.log('style blocks:', totalStyle);
|
|
console.log('navigationBarTitleText occurrences:', totalNavTitle);
|
|
console.log('inside-ifdef:', insideIfdef);
|
|
console.log('double-title:', doubleTitle);
|
|
console.log('missing-title:', missingTitle.length, missingTitle);
|
|
const ok = totalStyle === totalNavTitle && insideIfdef === 0 && doubleTitle === 0 && missingTitle.length === 0;
|
|
console.log(ok ? '✅ PASS' : '❌ FAIL');
|
|
process.exit(ok ? 0 : 1); |