和大怨,必有余怨。安可以为善?是以圣人执左契,而不责于人。有德司契,无德司彻。天道无亲,常于善人。
github:
miniapp-shaking
上一章我们初步完成了整个小程序的依赖收集,这一章我们介绍如何生成类似小程序开发者工具的依赖图,以便对我们摇树之后的代码有个更加清晰的了解。
在上一章我们把主包和子包的依赖树组合成了一个完整的依赖树,并输出到了
analyse
目录下,我们将使用这些数据结合
echarts
来生成真正的可视化依赖图:
createTree() {
console.log('正在生成依赖图...');
const tree = { [this.config.mainPackageName]: this.mainDepend.tree };
this.subDepends.forEach(item => {
tree[item.rootDir] = item.tree;
});
fse.copySync(path.join(__dirname, '../analyse'), this.config.analyseDir);
fse.writeJSONSync(path.join(this.config.analyseDir, 'tree.json'), tree, { spaces: 2 });
}
在该目录下还有两个文件:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>依赖分析</title>
<style>
html, body, #app {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="app"></div>
</body>
<script src="https://cdn.jsdelivr.net/npm/echarts@4.9.0/dist/echarts.min.js"></script>
<script src="./index.js"></script>
</html>
index.js
function flatDependency(map, arr) {
Object.keys(map).forEach((name) => {
const { size, children } = map[name];
const flatChildren = [];
arr.push({
name,
value: size,
children: flatChildren,
});
if (!children) {
return;
}
flatDependency(children, flatChildren);
});
}
const data = [];
const treeJson = require('./tree.json');
flatDependency(treeJson, data);
const eChart = echarts.init(document.getElementById('app'));
const formatUtil = echarts.format;
const option = {
backgroundColor: '#333',
title: {
text: '小程序依赖分布',
left: 'center',
textStyle: {
color: '#fff',
},
},
tooltip: {
formatter: function (info) {
const treePath = [];
const { value, treePathInfo } = info;
const pathDeep = treePathInfo.length;
if (pathDeep <= 2) {
treePath.push(treePathInfo[1] && treePathInfo[1].name);
} else {
for (let i = 2; i < pathDeep; i++) {
treePath.push(treePathInfo[i].name);
}
}
return [
'<div class="tooltip-title">'
+ formatUtil.encodeHTML(treePath.join('/'))
+ '</div>',
'size: ' + value.toFixed(2) + ' KB',
].join('');
},
},
series: [
{
type: 'treemap',
name: 'Dependency',
data: data,
radius: '100%',
visibleMin: 300,
label: {
show: true,
formatter: '{b}',
},
itemStyle: {
borderColor: '#fff',
},
levels: [
{
itemStyle: {
gapWidth: 1,
borderWidth: 0,
// borderColor: "#777",
},
},
{
itemStyle: {
gapWidth: 1,
borderWidth: 5,
borderColor: '#555',
},
upperLabel: {
show: true,
},
},
{
itemStyle: {
gapWidth: 1,
borderWidth: 5,
borderColor: '#888',
},
upperLabel: {
show: true,
},
},
{
itemStyle: {
gapWidth: 1,
borderWidth: 5,
borderColor: '#4eba0f',
},
upperLabel: {
show: true,
},
},
{
colorSaturation: [0.35, 0.5],
itemStyle: {
gapWidth: 1,
borderWidth: 5,
borderColorSaturation: 0.4,
color: '#fc8452',
},
upperLabel: {
show: true,
},
},
],
},
],
};
eChart.setOption(option);
我们只要在本地启动一个服务,并访问index.html就可以看到整个依赖图了,例如:
npm i parcel-bundler -g
parcel ./analyse/index.html --open --out-dir analyse-dist
下一章开始我们介绍更为高级的摇树优化,逻辑会更加复杂,敬请期待下文。
连载文章链接:
手写小程序摇树工具(一)——依赖分析介绍
手写小程序摇树工具(二)——遍历js文件
手写小程序摇树工具(三)——遍历json文件
手写小程序摇树工具(四)——遍历wxml、wxss、wxs文件
手写小程序摇树工具(五)——从单一文件开始深度依赖收集
手写小程序摇树工具(六)——主包和子包依赖收集
手写小程序摇树工具(七)——生成依赖图
手写小程序摇树工具(八)——移动独立npm包
手写小程序摇化工具(九)——删除业务组代码