Files
msh-system/msh_single_uniapp/scripts/analyze-mp-main.js

96 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 微信小程序主包体积分析
* 用法先执行发行构建微信小程序再运行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();