1. 抽离底部导航归属逻辑为纯函数resolveEntryTab,优化分包页面高亮规则,对齐iOS HIG规范 2. 新增页面Tab通配符映射,简化PAGE_TAB_MAP维护 3. 修复鸿蒙平台webview返回按钮适配问题 4. 新增pages.json校验与导航标题自动注入脚本 5. 优化启动页动画性能,提升合成渲染效率 6. 修复diy-picture组件v-for缺少key的警告 7. 清理鸿蒙平台多余的分包构建配置 8. 更新统计数据与store注释说明
154 lines
4.5 KiB
JavaScript
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); |