Initial commit: MSH System\n\n- msh_single_uniapp: Vue 2 + UniApp 前端(微信小程序/H5/App/支付宝小程序)\n- msh_crmeb_22: Spring Boot 2.2 后端(C端API/管理端/业务逻辑)\n- models-integration: AI服务集成(Coze/KieAI/腾讯ASR)\n- docs: 产品文档与设计稿
This commit is contained in:
95
msh_single_uniapp/scripts/analyze-mp-main.js
Normal file
95
msh_single_uniapp/scripts/analyze-mp-main.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* 微信小程序主包体积分析
|
||||
* 用法:先执行发行构建(微信小程序),再运行:node scripts/analyze-mp-main.js
|
||||
* 输出:主包总大小、超过 2MB 时告警、主包内大文件列表
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const BUILD_DIR = path.join(__dirname, '../unpackage/dist/build/mp-weixin');
|
||||
const MAIN_PACKAGE_LIMIT_KB = 2048;
|
||||
|
||||
function getSubPackageRoots() {
|
||||
const appJsonPath = path.join(BUILD_DIR, 'app.json');
|
||||
if (!fs.existsSync(appJsonPath)) {
|
||||
console.error('未找到 app.json,请先执行:发行 -> 微信小程序');
|
||||
process.exit(1);
|
||||
}
|
||||
const app = JSON.parse(fs.readFileSync(appJsonPath, 'utf8'));
|
||||
let roots = (app.subPackages || []).map((p) => p.root);
|
||||
// 若构建产物尚未包含最新分包,则按源码 pages.json 补充(如 goods_cate)
|
||||
const pagesJsonPath = path.join(__dirname, '../pages.json');
|
||||
if (fs.existsSync(pagesJsonPath)) {
|
||||
let raw = fs.readFileSync(pagesJsonPath, 'utf8');
|
||||
// 只去掉行尾 // 注释(不删字符串内的 //)
|
||||
raw = raw.replace(/\s*\/\/[^\n"']*$/gm, '');
|
||||
try {
|
||||
const pagesJson = JSON.parse(raw);
|
||||
const subRoots = (pagesJson.subPackages || []).map((p) => p.root);
|
||||
subRoots.forEach((r) => {
|
||||
if (!roots.includes(r)) roots = roots.concat(r);
|
||||
});
|
||||
} catch (_) {}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
function isInMainPackage(filePath, subRoots) {
|
||||
const normalized = filePath.replace(BUILD_DIR + path.sep, '').replace(/\\/g, '/');
|
||||
for (const root of subRoots) {
|
||||
if (normalized === root || normalized.startsWith(root + '/')) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function walkDir(dir, subRoots, list) {
|
||||
if (!fs.existsSync(dir)) return;
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const e of entries) {
|
||||
const full = path.join(dir, e.name);
|
||||
const rel = path.relative(BUILD_DIR, full).replace(/\\/g, '/');
|
||||
if (e.isDirectory()) {
|
||||
walkDir(full, subRoots, list);
|
||||
} else {
|
||||
if (!isInMainPackage(full, subRoots)) continue;
|
||||
try {
|
||||
const stat = fs.statSync(full);
|
||||
list.push({ path: rel, size: stat.size });
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
const subRoots = getSubPackageRoots();
|
||||
const files = [];
|
||||
walkDir(BUILD_DIR, subRoots, files);
|
||||
|
||||
const totalBytes = files.reduce((s, f) => s + f.size, 0);
|
||||
const totalKB = Math.round(totalBytes / 1024);
|
||||
const totalMB = (totalBytes / 1024 / 1024).toFixed(2);
|
||||
|
||||
console.log('========== 微信小程序主包体积分析 ==========\n');
|
||||
console.log('主包总大小:', totalKB, 'KB', '(' + totalMB + ' MB)');
|
||||
console.log('微信主包上限:', MAIN_PACKAGE_LIMIT_KB, 'KB (2 MB)\n');
|
||||
|
||||
if (totalKB > MAIN_PACKAGE_LIMIT_KB) {
|
||||
console.log('⚠️ 主包超出限制', totalKB - MAIN_PACKAGE_LIMIT_KB, 'KB,需优化后再上传。\n');
|
||||
} else {
|
||||
console.log('✓ 主包未超限。\n');
|
||||
}
|
||||
|
||||
const sorted = files.slice().sort((a, b) => b.size - a.size);
|
||||
console.log('主包内大文件(按体积排序,前 30):');
|
||||
console.log('----------------------------------------');
|
||||
sorted.slice(0, 30).forEach((f) => {
|
||||
const kb = (f.size / 1024).toFixed(1);
|
||||
console.log(kb.padStart(8) + ' KB ' + f.path);
|
||||
});
|
||||
|
||||
console.log('\n主包页面(来自 app.json):');
|
||||
const app = JSON.parse(fs.readFileSync(path.join(BUILD_DIR, 'app.json'), 'utf8'));
|
||||
(app.pages || []).forEach((p) => console.log(' -', p));
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user