项目组件太多,依赖关系太复杂,一不小心改漏了,线上bug又来了,是开发的问题,还是测试的责任?
对于这个问题,我觉得妥妥的是开发的问题,因为测试哪知道你的改动会影响几个地方,那到底该怎么解决呢?
废话不多说直接上案例和解决方案:
以下是一个页面引用案例
//Card.vue 商品卡片组件
//Index.vue 首页
import Card from './common/Card.vue' //依赖商品卡片组件
//Home.vue 个人主页
import Card from './common/Card.vue' //依赖商品卡片组件
.....
这里假设有100个页面引用了Card.vue
这时候产品让你改这个Card组件,然后测试让你评估影响范围,你会怎么办?
我会说:我来做一个可视化的页面给你,下次再遇到类似的问题,我给你个组件名,你就会知道影响到哪些页面了,6不6
咱们来分析一下具体怎么做:
要想做到组件对应页面的关系,我得先知道这个组件的引用关系,以及最上层父组件是对应的哪个页面的路由,这样才可能打开对应的页面链接
首先来看一下项目中的实际依赖关系
对应的依赖分析关系:(每个组件,与引用它的页面路由的映射)
其实这是一个很简单的树形结构变线型结构的问题,再找到路由和组件的对应关系输出一份JSON就基本完成工作了
但是这个分析是需要要我们自己去写js脚本读取文件结构吗?还要去分析路由,感觉好麻烦的样子,我的结论是大可不必
webpack强大的插件能力你不用多浪费呀,webpack之所以强大就是因为插件理念,几乎每一个操作节点都会有钩子暴露,所以既然我们用webpack打包,为何不借助插件做这个工作
先来了解下webpack的整体编译流程:
再来看一下webpack的事件流,即编译过程暴露的回调钩子
可以看到,每一个文件都会经过resolve阶段,最终在编译结束后,得到本次编译的统计分析信息,通过这些信息我们就能获取到组件的引用关系,废话不多说直接上代码:
compiler.hooks.normalModuleFactory.tap('FileLinkAnalysisPlugin', nmf => {
nmf.hooks.afterResolve.tapAsync('FileLinkAnalysisPlugin', (result, callback) => {
const { resourceResolveData } = result
// 当前文件的路径
let path = resourceResolveData.path
// 父级文件路径
let fatherPath = resourceResolveData.context.issuer
// 不是node_module中的文件
if (!this.skipNodeModules(path)) {
if (fatherPath && fatherPath != path) {
// 父子路径相同的排除
if (fatherPath.endsWith('vue') && path.endsWith('vue')) {
// 只统计vue文件依赖关系
this.linkParentDependencies(path, fatherPath)
// 获取路由组件映射关系
this.getBuildRouter(path)
}
}
}
callback(null, result)
})
})
利用afterResolve这个钩子就可以获取我们想要的组件依赖关系,完成第一步
接下来我们要获取路由信息了,这就很简单了,因为webpack打包后会生成一个router.js, 我们要做的就是去读取它的内容,然后用router里面的path和页面的path作对比就可以获取对应关系了。
最后就是完成导出JSON了,这个步骤就要在webpack打包结束的钩子里面去操作了,也就是done这个钩子
compiler.hooks.done.tapAsync('FileLinkAnalysisPlugin', (stats, cb) => {
const componentLine = this.getComponentLine();
const componentTree = this.getComponentTree();
const routesMap = this.getRoutesMap();
const json = {
componentLine
componentTree
routesMap
}
fs.writeFile(cwdPath + '/FileLinkAnalysisPlugin.json', JSON.stringify(json, '', '\t'), err => {
if (err) {
throw err
}
})
cb()
})
导出文件大概就是这个样子:
有了它我们就可以发送请求到后端存储到数据库,进而完成可视化页面,再往下的代码就不过多赘述了,这样当下次测试再来问你这次改动会影响到哪个页面,你就可以大大方方的和他说:去我们的工具平台上搜一下 xxx 组件名就可以看到了