Files
lucky_shop/scripts/verify-pages-json-cross-platform.js
ZF sun 55a9ed5946 refactor: 重构底部导航高亮逻辑,新增跨平台兼容与工具脚本
1. 抽离底部导航归属逻辑为纯函数resolveEntryTab,优化分包页面高亮规则,对齐iOS HIG规范
2. 新增页面Tab通配符映射,简化PAGE_TAB_MAP维护
3. 修复鸿蒙平台webview返回按钮适配问题
4. 新增pages.json校验与导航标题自动注入脚本
5. 优化启动页动画性能,提升合成渲染效率
6. 修复diy-picture组件v-for缺少key的警告
7. 清理鸿蒙平台多余的分包构建配置
8. 更新统计数据与store注释说明
2026-07-16 11:47:29 +08:00

154 lines
4.5 KiB
JavaScript

/**
* 跨平台验证: 模拟 uni-app 预处理, 把 pages.json 在每个平台上
* (H5 / MP-WEIXIN / APP-PLUS / MP-HARMONY / etc.) 展开后,
* 用标准 JSON.parse 验证其合法性.
*
* uni-app 预处理规则:
* - // #ifdef PLATFORM ... // #endif: 当 PLATFORM 匹配当前平台, 保留块; 否则删除 (含注释行)
* - // #ifndef PLATFORM ... // #endif: 当 PLATFORM 不匹配当前平台, 保留块; 否则删除
* - 处理嵌套
*
* 运行: node scripts/verify-pages-json-cross-platform.js
*/
const fs = require('fs');
const path = require('path');
const PAGES_JSON = path.join(__dirname, '..', 'pages.json');
const raw = fs.readFileSync(PAGES_JSON, 'utf-8');
const lines = raw.split(/\r?\n/);
const PLATFORMS = ['H5', 'MP-WEIXIN', 'APP-PLUS', 'MP-HARMONY', 'MP-ALIPAY', 'MP-BAIDU', 'MP-TOUTIAO', 'MP-QQ', 'MP-KUAISHOU', 'MP-JD', 'MP-360', 'MP-XHS', 'APP', 'APP-NVUE'];
/**
* 模拟预处理: 给定平台, 返回剥除 // #ifdef / // #ifndef 后的行数组.
*/
function preprocess(platform) {
const out = [];
const stack = []; // 每项 { mode: 'ifdef' | 'ifndef', platform, keep }
for (const line of lines) {
// 检测 // #ifdef PLAT / // #ifndef PLAT
const openMatch = line.match(/^\s*\/\/\s*#(ifdef|ifndef)\s+([\w-]+)\b/);
if (openMatch) {
const mode = openMatch[1];
const plat = openMatch[2];
const keep = mode === 'ifdef'
? plat === platform
: plat !== platform;
stack.push({ mode, platform: plat, keep });
if (!keep) {
// 这行也不输出 (块被剥除)
continue;
}
out.push(line);
continue;
}
const closeMatch = line.match(/^\s*\/\/\s*#endif\b/);
if (closeMatch) {
const top = stack.pop();
if (!top) {
// 不平衡的 #endif, 仍输出 (避免破坏后续)
out.push(line);
continue;
}
if (!top.keep) continue; // 整块被剥除, // #endif 也不输出
out.push(line);
continue;
}
// 普通行: 若当前栈顶 keep=false, 不输出
if (stack.length > 0 && !stack[stack.length - 1].keep) continue;
out.push(line);
}
if (stack.length > 0) {
console.warn(`[warn] platform=${platform}: 残留未关闭 #ifdef/#ifndef ${stack.length} 个`);
}
return out;
}
/**
* 剥除 // 行注释, 返回纯 JSON 字符串.
* 注意: 必须先做预处理把 // #ifdef 块剥除, 否则 // 会被当成 JSON 注释.
*/
function stripLineComments(keptLines) {
const out = [];
for (const line of keptLines) {
let lo = '';
let inS = false, e = false;
for (let i = 0; i < line.length; i++) {
const c = line[i];
if (inS) {
if (e) e = false;
else if (c === '\\') e = true;
else if (c === '"') inS = false;
} else {
if (c === '/' && line[i + 1] === '/') break;
if (c === '"') inS = true;
}
lo += c;
}
out.push(lo);
}
return out.join('\n');
}
let allOk = true;
for (const plat of PLATFORMS) {
const kept = preprocess(plat);
const cleanJson = stripLineComments(kept);
try {
JSON.parse(cleanJson);
console.log(`✅ ${plat.padEnd(12)} OK`);
} catch (err) {
allOk = false;
console.log(`❌ ${plat.padEnd(12)} FAIL: ${err.message}`);
// 输出错误附近 6 行
const m = err.message.match(/position (\d+)/);
if (m) {
const pos = parseInt(m[1]);
const allLines = cleanJson.split('\n');
let p = 0;
for (let k = 0; k < allLines.length; k++) {
if (p + allLines[k].length + 1 > pos) {
console.log(' near preprocessed line', k + 1, '(in raw pages.json line', findRawLine(k, plat) + ')');
for (let j = Math.max(0, k - 3); j <= Math.min(allLines.length - 1, k + 3); j++) {
console.log(' ', j === k ? '>>>' : ' ', allLines[j]);
}
break;
}
p += allLines[k].length + 1;
}
}
}
}
function findRawLine(preprocIdx, platform) {
// 找到 raw 中第 preprocIdx 行对应到哪一行. 用同样的预处理规则计算.
const stack = [];
let preIdx = -1;
for (let k = 0; k < lines.length; k++) {
const line = lines[k];
const openMatch = line.match(/^\s*\/\/\s*#(ifdef|ifndef)\s+([\w-]+)\b/);
if (openMatch) {
const mode = openMatch[1];
const plat = openMatch[2];
const keep = mode === 'ifdef' ? plat === platform : plat !== platform;
stack.push({ keep });
if (!keep) continue;
preIdx++;
continue;
}
if (/^\s*\/\/\s*#endif\b/.test(line)) {
const top = stack.pop();
if (top && !top.keep) continue;
preIdx++;
continue;
}
if (stack.length > 0 && !stack[stack.length - 1].keep) continue;
preIdx++;
if (preIdx === preprocIdx) return k + 1;
}
return -1;
}
process.exit(allOk ? 0 : 1);