Node Library 依赖关系分析工具--技术文档

1,113 阅读3分钟

✨ 需求文档

❣ 背景

NodeJS 的包管理逻辑非常复杂,直观感受是 npm install 后常常会安装许多不明所以的包,例如:

{
  "name": "tmp3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "glob": "^10.1.0"
  }
}

image.png

glob 包会带来 balanced-match 等总计 7 个子包,分析这些包的 package.json,可以发现它们之间形成如下依赖关系:

image.png

项目变大,依赖变多之后,这种依赖关系会变得非常非常复杂,常常让我们看不清为什么会安装某个特定 package,或者为什么某些 package 会安装多个版本等,为此期望实现一个工具,用于从项目 package.json 出发,递归遍历所有 node_modules 中的 package.json ,生成模块依赖关系图。

❣ 需求

  • 需要封装为 node 命令行工具;

  • 支持 xx-cli analyze 命令,用于分析从当前目录 package.json 开始递归查找到的全量依赖关系(包名 & 版本号),分析完成后自动打开网页,并渲染依赖关系图

    • 注意处理好循环依赖问题,避免陷入死循环;
    • 支持 --depth=n 参数,限制向下递归分析的层次深度;
    • [可选] 支持 --json=[file-path] 参数,传入后不再打开网页,只是将依赖关系以 JSON 形式存储到用户指定的文件

✨使用方法

指定深度为2时:

初次打开时 动画11.gif

拖拽移动

脱拽移动.gif

放大

动画放大.gif

选中节点高亮,并移动节点

动画移动.gif

取消选中

取消选中.gif

搜索关键字,查找其有关的依赖关系

搜索关键字,查找其有关的依赖关系.gif

搜索关键字,查找其有关的依赖关系.gif

✨实现与思路

1️⃣ 技术选型

 ✋🏽 功能技术选型

 i. commander (github.com/tj/commande…) node命令行解决方案

 ii. d3.js(初识 D3.js :入门教程 + 与echarts对比 - 掘金 (juejin.cn) ) 可视化解决方案

 ii.  prettier (www.prettier.cn/) 是一个有态度的代码格式化程序

 ✋🏻 工程化技术选型

 i. typescript (www.tslang.cn/docs/home.h…) js的超集

 ii. webpack(webpack | webpack 中文文档 | webpack 中文网 (webpackjs.com))

2️⃣ 绘制流程图,确定整个程序运行的逻辑流程

  1. ❤ 依赖关系处理逻辑的流程图

Flowchart.jpg

  1. 💙 依赖关系处理逻辑的流程图

Flowchart (1).jpg

  1. 💜 不同包管理器的处理逻辑相同,但是需要分为首次和非首次(具体区别:npm & yarn & pnpm包管理器机制 - 掘金 (juejin.cn)

    🔸npm和yarn管理依赖扁平化

// 具体结构如下所示
node_modules
├── @types
├── A@1.0.0
├── B@1.0.0
├── D@1.0.0
├── C@1.0.0
└── E@1.0.0
package.json

@xxx开头的依赖 vs 普通依赖A:

  • package.json文件中的依赖中,以@开头的通常是指向特定npm命名空间(namespace)的包。在npm中,包名称可以包含命名空间,命名空间是包的一种逻辑组织方式,用于将相关的包归类在一起。

      例如:

        @babel/core中的@babel是一个命名空间,core是这个命名空间下的具体包名称。这个包属于Babel工具链的核心模块,用于将源代码转换为目标代码。

  🔸Pnpm管理依赖

// 采用内容寻址存储
node_modules
├─ .pnmp 
  ├─ registry.npmmirror.com+jest@27.5.1  <-------------           
    ├─node_modules                                     |
      ├─ @jest                                         |
         ├─ package.json                               |
      ├─ import-local                                  |
      ├─ jest                                          |
      ├─ jest-cli                                      |
  ├─ registry.npmmirror.com+pretty-format@29.6.2       |
    ├─node_modules                                     |
      ├─ @jest // pretty-format 子依赖符号链接-----------
      ├─ ansi-styles // pretty-format 子依赖 符号链接
      ├─ pretty-format // pretty-format 本身
         ├─ package.json 
      ├─ react-is // pretty-format 子依赖 符号链接
├─ pretty-format-> ../node_modules/.pnpm/registry.npmmirror.com+pretty-format@29.6.2/
package.json

  🔸这两种不同类别的包管理器:① 统一使用CommonJS中的require.resolve(),找到依赖的地址;② 处理依赖时,统一使用CommonJS中的require()解析依赖。 具体流程图分析如下:

Flowchart (2).jpg

3️⃣ 搭建配置ts

4️⃣ 配置webpack

webpack保姆级教程,如何一步步配置,webpack基础使用

源码地址

后端代码:github.com/qiaoruiqi/d…

前端代码:github.com/qiaoruiqi/d…