@lark-project/cli
Version:
飞书项目插件开发工具
133 lines (132 loc) • 5.22 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeDist = exports.analyzeChunks = void 0;
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const fs_extra_1 = require("fs-extra");
function calcLevelChunk() {
const assetFiles = [];
const resultWithLevel = [];
return {
addLevelChunk: (level, chunks) => {
if (!resultWithLevel[level]) {
resultWithLevel[level] = {
jsFiles: [],
cssFiles: [],
};
}
const { js, css, assets } = chunks;
resultWithLevel[level].jsFiles.push(js);
css && resultWithLevel[level].cssFiles.push(css);
assets && assetFiles.push(...assets);
},
getSortedChunk: () => {
// 直接用sort排序已经是最优计算,此处不做单层的level临时计算排序,存储和排序分开写会比较容易清楚些
const entryFiles = resultWithLevel[0].jsFiles.concat(resultWithLevel[0].cssFiles).map(i => i.path);
const sortedFiles = entryFiles;
for (let i = 1, len = resultWithLevel.length; i < len; i++) {
const { jsFiles, cssFiles } = resultWithLevel[i];
// 同类型按从size的从大到小排序
sortedFiles.push(...jsFiles.sort((a, b) => b.size - a.size).map(i => i.path));
cssFiles.length && sortedFiles.push(...cssFiles.sort((a, b) => b.size - a.size).map(i => i.path));
}
return sortedFiles.concat(assetFiles);
},
};
}
function analyzeChunks(dirPath, stats) {
const { chunks } = stats;
const result = [];
const queue = [];
const visited = new Map();
const { addLevelChunk, getSortedChunk } = calcLevelChunk();
const processChunk = (chunkId) => {
var _a;
const chunk = chunks === null || chunks === void 0 ? void 0 : chunks.find(c => c.id === chunkId);
if (!chunk)
return;
const visitedLevel = visited.get(chunkId);
const jsFile = chunk.files.find(_path => /.*\.js/.test(_path));
const cssFile = chunk.files.find(_path => /.*\.css/.test(_path));
const sizes = chunk.sizes;
const JSChunk = {
path: jsFile,
size: Math.round(sizes.javascript),
type: 'javascript',
isPreload: true,
};
const CSSChunk = cssFile ? {
path: cssFile,
size: Math.round(sizes['css/mini-extract']),
type: 'css',
isPreload: true,
} : null;
const sortedFiles = [JSChunk];
if (CSSChunk) {
sortedFiles.push(CSSChunk);
}
let assetFiles = [];
if ((_a = chunk.auxiliaryFiles) === null || _a === void 0 ? void 0 : _a.length) {
assetFiles = chunk.auxiliaryFiles.map(_p => ({
path: _p,
size: Math.round(fs_1.default.statSync(path_1.default.join(dirPath, _p)).size),
type: 'assets',
isPreload: false,
})).sort((a, b) => a.size - b.size);
}
addLevelChunk(visitedLevel, {
js: JSChunk,
css: CSSChunk,
assets: chunk.auxiliaryFiles,
});
result.push({
id: chunk.id,
initial: chunk.initial,
entry: chunk.entry,
parents: chunk.parents,
children: chunk.children,
files: sortedFiles.concat(assetFiles),
});
chunk.children.forEach(childId => {
if (!visited.has(childId)) {
queue.push(childId);
visited.set(childId, visitedLevel + 1);
}
});
};
const initialChunk = chunks === null || chunks === void 0 ? void 0 : chunks.find(c => c.initial);
if (initialChunk) {
queue.push(initialChunk.id);
visited.set(initialChunk.id, 0);
}
while (queue.length) {
const current = queue.shift();
processChunk(current);
}
const sortedFiles = getSortedChunk();
return {
fileStats: result,
sortedFiles,
};
}
exports.analyzeChunks = analyzeChunks;
const analyzeDist = (distPath) => {
fs_1.default.readdirSync(distPath, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.forEach(({ name }) => {
const dirPath = path_1.default.join(distPath, name);
const statsPath = path_1.default.join(dirPath, 'stats.json');
const assetPath = path_1.default.join(dirPath, 'asset-manifest.json');
if (fs_1.default.existsSync(statsPath)) {
const { fileStats, sortedFiles } = analyzeChunks(dirPath, require(statsPath));
const data = require(assetPath);
data.fileStats = fileStats;
data.sortedFiles = sortedFiles;
(0, fs_extra_1.writeFileSync)(assetPath, JSON.stringify(data, null, 2));
}
});
};
exports.analyzeDist = analyzeDist;