1.一个项目总共有多少组件?每个页面又有多少组件构成?
2.有哪些组件是公共组件,它们分别被哪些页面引用?
对于这两个问题,我们先思考一会。sleep……
跟随这篇文章我们一起探讨下,希望能帮你找到答案。
背景
随着组件化思想深入人心,开发中遇到特定的功能模块或UI模块,我们便会想到抽成组件,高级一点的做法就是把多个页面相似的部分抽成公共的组件。
组件化的“诅咒”
但是往往对一件事物依赖越强,越容易陷入它的“诅咒”当中。当项目有越多的组件时,开发者越不容易建立它们之间的关系,特别当改动了某个组件的一行代码,甚至不能准确的判断由于这行代码变动,都影响了哪些页面。我暂且称之为“组件化的诅咒”。如果我们有个完整的组件依赖关系,就可以很好的解决这个问题。
我们以下面的场景为例,看一看依赖分析的重要性和必要性。
通过前一篇文章,想必大家对埋点自动收集方案有了宏观且全面的了解。在这里再简单概述下:
埋点自动收集方案是基于jsdoc对注释信息的搜集能力,通过给路由页面中所有埋点增加注释的方式,在编译时建立起页面和埋点信息的对应关系。
点击查看《埋点自动收集方案-概述》
在整个方案中,埋点的数据源很重要,而数据源与页面的对应关系又是保证数据源完整性的关键。比如:首页和个人主页的商品流都采用相同的商品卡片,开发者自然会将商品卡片抽离为一个公共组件。如下:
//Index.vue 首页
import Card from './common/Card.vue' //依赖商品卡片组件
//Home.vue 个人主页
import Card from './common/Card.vue' //依赖商品卡片组件
//Card.vue 商品卡片组件
goDetail(item) {
/**
* @mylog 商品卡片点击
*/
this.$log('card-click') // 埋点发送
}
这就带来一个问题:商品卡片的点击信息(埋点的数据源),既可能是首页的,也可能是个人主页的,而jsdoc搜集埋点注释时,对这种归属情况的判断无能为力。所以必须找到一种方法可以拿到组件和页面的映射关系。
期望效果
项目中的实际依赖关系:
对应的依赖分析关系:(每个组件,与引用它的页面路由的映射)
方案思考
那么,怎么做依赖分析?在思考这个问题之前,我们先看一看有哪些常见的建立依赖的语法。
//a.ts
import B from './b.ts'
import getCookie from '@/libs/cookie.ts'
//c.ts
const C = require('./b.ts')
//b.ts
div {
background: url('./assets/icon.png') no-repeat;
}
import './style.css'
// c.vue
import Vue from Vue
import Card from '@/component/Card.vue'
这里给出三种依赖分析的思路:
1 递归解析
从项目的路由配置文件开始,分别对每个路由页面,进行依赖的递归解析。这种思路想法简单直接,但实现起来可能较为繁琐,需要解析页面中所有形式的依赖关系。
2 借助webpack工具的统计分析数据,进行二次加工
实际项目中我们都是采用webpack打包工具,而它的一大特点就是会自动帮开发者做依赖分析(独立的enhanced-resolve库)。相较于第一种重写解析的方法,为何不站在webpack的肩膀上解决问题呢。
先来看下webpack的整体编译流程: