refactor(pages.json&scripts): 优化自定义组件占位符注入逻辑
1. 为商品详情页添加所有diy-*组件的占位符配置 2. 重构占位符注入脚本,实现组件使用的递归检测 3. 移除原有的简单字符串匹配,改用导入链追踪准确判断组件使用情况
This commit is contained in:
@@ -99,18 +99,69 @@ function lastMeaningfulIdx(bodyLines) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 page 的 .vue 文件是否引用了 <diy-*> 组件.
|
||||
* 简单的字符串检查, 包含 <diy- 即认为使用 (覆盖模板引用、动态组件等).
|
||||
* 把 import specifier 解析为相对项目根的 .vue 路径(不带扩展名).
|
||||
* 仅处理 ./ ../ @/ 开头的本地路径; node_modules 等外部模块直接返回 null.
|
||||
*/
|
||||
function resolveVueImport(fromRel, spec) {
|
||||
let abs;
|
||||
if (spec.startsWith('@/')) {
|
||||
abs = path.join(PROJECT_ROOT, spec.slice(2));
|
||||
} else if (spec.startsWith('./') || spec.startsWith('../')) {
|
||||
abs = path.resolve(path.dirname(path.join(PROJECT_ROOT, fromRel + '.vue')), spec);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
let rel = path.relative(PROJECT_ROOT, abs).replace(/\\/g, '/');
|
||||
if (rel.startsWith('..')) return null;
|
||||
if (!rel.endsWith('.vue')) return null;
|
||||
return rel.slice(0, -'.vue'.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存: 相对路径 → 是否(直接或传递)使用了 <diy-*>.
|
||||
*/
|
||||
const _usesDiyCache = new Map();
|
||||
const _importRe = /import\s+[^'"`;\n]*['"]([^'"`]+\.vue)['"]/g;
|
||||
|
||||
/**
|
||||
* 检查一个 .vue 文件是否(传递)使用了 <diy-*> 组件.
|
||||
* 不仅看模板里是否含 <diy-, 还会沿 import 链继续追踪子组件.
|
||||
* 例如 pages_goods/detail.vue → _components/goods-detail-view/goods-detail-view.vue → <diy-icon>
|
||||
*/
|
||||
function fileUsesDiy(relVuePath) {
|
||||
if (!relVuePath) return false;
|
||||
if (_usesDiyCache.has(relVuePath)) return _usesDiyCache.get(relVuePath);
|
||||
// 暂存 false 以打破循环引用
|
||||
_usesDiyCache.set(relVuePath, false);
|
||||
const abs = path.join(PROJECT_ROOT, relVuePath + '.vue');
|
||||
let content;
|
||||
try {
|
||||
content = fs.readFileSync(abs, 'utf-8');
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
if (/<diy-/.test(content)) {
|
||||
_usesDiyCache.set(relVuePath, true);
|
||||
return true;
|
||||
}
|
||||
_importRe.lastIndex = 0;
|
||||
let m;
|
||||
while ((m = _importRe.exec(content)) !== null) {
|
||||
const target = resolveVueImport(relVuePath, m[1]);
|
||||
if (target && fileUsesDiy(target)) {
|
||||
_usesDiyCache.set(relVuePath, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 page 的 .vue 文件(或其传递子组件)是否引用了 <diy-*> 组件.
|
||||
* fullPagePath 是 pages.json 中拼接的页面路径, 如 "pages_goods/detail".
|
||||
*/
|
||||
function pageUsesDiy(fullPagePath) {
|
||||
if (!fullPagePath) return false;
|
||||
const vuePath = path.join(PROJECT_ROOT, fullPagePath + '.vue');
|
||||
try {
|
||||
const content = fs.readFileSync(vuePath, 'utf-8');
|
||||
return /<diy-/.test(content);
|
||||
} catch (e) {
|
||||
return false; // 文件不存在时不注入
|
||||
}
|
||||
return fileUsesDiy(fullPagePath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user