npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-import-graph

v0.1.0

Published

Dependency graph for DeepSeek Harness: build_graph (parse JS/TS import & require edges), find_cycles (circular dependency detection), orphan_files (files neither imported by nor importing others). Heuristic resolution, zero runtime dependencies, read-only

Readme

dsh-import-graph

DeepSeek Harness 的依赖图工具箱:build_graph 解析 JS/TS 源码的 import / require 依赖构建图,find_cycles 检测循环依赖,orphan_files 找出不被任何本地文件引用也不引用别人的孤立源码。只读、零运行时依赖,启发式解析而非完整 AST。

  • 源码:https://github.com/geeklei/dsh-plugins/tree/main/dsh-import-graph
  • npm:https://www.npmjs.com/package/dsh-import-graph

功能说明

「这个模块删掉会影响谁?」、「A 和 B 是不是循环依赖?」、「仓库里哪些文件其实没人用了?」——单看文件列表回答不了这些问题,要看文件之间的依赖关系。

本插件用启发式扫描给出三档信息,帮你把模块边界和依赖健康状况摸清楚:

  • 依赖图(build_graph):递归扫描目录里的 JS/TS 家族源码,解析 import / require / export...from / 动态 import(),构建「文件 → 它依赖的文件」的边,并统计入度 / 出度与孤立文件。
  • 循环依赖(find_cycles):在依赖图上用深度优先找环(A→B→C→A)。循环依赖常导致初始化顺序问题、命名空间污染、难以安全拆分,是代码质量的常见隐患。
  • 孤立文件(orphan_files):找出无入边(不被任何本地文件引用)且无出边(也不引用任何本地文件)的源码。这类文件可能是废弃模块、被动态加载/注册调用的入口,也可能是移出模块边界的遗留。

解析是启发式的:只解析以 ./ ../ 开头的相对引用(npm 包 / 别名 / 内置模块不计为本地边),用「字符串 / 注释剥离 + 正则」近似识别语句,不是完整 AST,个别边界可能不精确,但用于结构判断足够。

安装

npm install dsh-import-graph

安装后在 cordis.patch.yml 中加入:

- insert:
    - id: import-graph
      name: "dsh-import-graph"

使用说明

build_graph

解析目录(或单个文件)的依赖关系,输出依赖边与出入度统计。path 传目录或文件;exclude 逗号分隔排除子串;show_edges 控制列出多少条边。

扫描路径:./src(排除 node_modules)
代码文件 6 个;依赖边 7 条;孤立文件 1 个
依赖边(前 5 / 共 7条):
1. src/a.js → src/b.js
2. src/a.js → src/util.js
3. src/b.js → src/c.js
4. src/cycle1.js → src/cycle2.js
5. src/cycle2.js → src/cycle1.js
孤立文件(无入边且无出边,共 1):
  - src/e.js
说明:依赖解析为启发式(字符串/注释剥离 + 正则),非完整 AST;npm 包与内置模块不计入本地边。

参数:path(必填);exclude;max_files(默认 500);max_size(默认 10240 KB);show_edges(默认 20);max_chars。

用户:这个 src 目录里文件都互相依赖谁,画个清单

助手:调用 build_graph,path=src、exclude=node_modules,输出依赖边与孤立文件

用户:删掉 util.js 会影响哪些文件

助手:调用 build_graph,看 util.js 的入边(谁依赖它)

find_cycles

在依赖图上检测循环依赖,每个环输出一条 A→B→C→A 链路。同一个环即使多次出现在栈中也只输出一次(按规范化键去重)。

扫描路径:./src;代码文件 6 个
发现循环依赖 1 个(前 1):
1. src/cycle1.js → src/cycle2.js → src/cycle1.js
提示:打破循环可先分析环中各边,常从「依赖最轻/最稳定」的节点切断。

参数:path(必填);exclude;max_files / max_size;top(默认 5);max_chars。

用户:这个模块有循环依赖吗,是哪几处

助手:调用 find_cycles,path=src,列出所有环

orphan_files

找出既不被任何本地文件引用、也不引用任何本地文件的孤立源码。

扫描路径:./src;代码文件 6 个
孤立文件(无入边且无出边,共 1):
1. src/e.js
说明:仅统计本地相对依赖;若文件经动态加载/插件注册/构建工具引用,可能为误报。

参数:path(必填);exclude;max_files / max_size;top(默认 5);max_chars。

用户:仓库里哪些文件其实没人用了

助手:调用 orphan_files,path=src,列出孤立文件

典型场景

  • 删除前影响面评估:删 / 移动一个文件前,build_graph 看它的入边(谁依赖它),避免删了炸一片。
  • 循环依赖治理:find_cycles 全量找出环,逐条分析切断点,配合重构把 A↔B 拆成单向依赖。
  • 废弃代码清理:orphan_files 定位「无入无出」的文件,确认后清理或标记废弃。
  • 模块边界梳理:新接手一个库,先 build_graph 整体依赖图,理解核心 / 外围模块。
  • 重构验证:拆分模块后重跑 build_graph,确认环数量下降、依赖方向变清晰。
  • 文档生成辅助:把 build_graph 的边列表喂给绘图工具,生成依赖可视化。
  • CI 门禁:对核心目录跑 find_cycles,出现环即告警,防止循环依赖回流。

安全边界

  • 只读:三个工具都不写入、不修改、不删除文件;只读取源码做文本扫描。
  • 不访问网络:依赖解析全部在本地完成,无任何外部请求,也不外发源码。
  • 不执行代码:只做文本扫描与字符串 / 注释剥离,不 eval、不运行被测代码。
  • 跳过无关内容:默认跳过 node_modules / .git / dist / build / coverage 与隐藏目录;二进制与超过 max_size 的文件不解析;max_files 限流。
  • 启发式结论,非权威:只解析相对引用,npm 包 / 别名 / 内置模块不计为本地边;字符串 / 注释剥离用正则近似,个别边界可能误识别。结果用于结构判断,不应作为唯一裁决依据。
  • 动态加载误报:经 import() 变量路径、插件注册、构建工具字符串引用加载的文件可能被漏报为孤立,orphan_files 已提示此风险。

其他插件集成说明

| 协作插件 | 集成方式 | |---|---| | dsh-code-metrics | import-graph 看依赖影响面,metrics 看体量 / 复杂度,互补定位重构目标 | | dsh-code-check | 有环或孤立文件时用 code-check 检查相关文件的具体 lint 问题 | | dsh-deps-audit | import-graph 管本地模块依赖,deps-audit 管 lock 文件里的外部依赖,双层治理 | | dsh-template-render | 用模板把依赖边列表渲染成 Markdown / 报告 | | dsh-chart-ascii | 把各模块出入度画成条形图,直观对比依赖热度 | | dsh-test-report | 拆环 / 清孤立后跑测试,确认没有回归 |

版本说明

  • 0.1.0(2026-10-08):初始版本。
    • build_graph:递归扫描目录,解析 import / require / export...from / 动态 import(),构建依赖边 + 出入度统计 + 孤立文件;默认跳过常见噪声目录
    • find_cycles:DFS 环检测,按规范化键去重,输出 A→B→C→A 链路
    • orphan_files:找出无入边且无出边的孤立源码
    • 说明符解析:相对引用补齐扩展名(js/jsx/mjs/cjs/ts/tsx)与目录 index;裸说明符(npm 包 / 别名 / 内置)不计为本地边
    • 字符串 / 模板 / 注释先剥离再做关键字识别,避免误匹配
    • 只读、二进制拒绝、多层上限

RoadMap

v0.2(计划)

  • 增加 influence:给定一个文件,输出它的下游影响面(直接 / 间接依赖它的文件)
  • 支持解析别名(如 @/ ~/)与 tsconfig paths,把别名映射到真实相对路径
  • 输出可选 format=json,便于脚本消费依赖图

v0.3(展望)

  • 增加 subgraph:只导出某模块为根的子图,聚焦局部依赖
  • 增加环的「切断建议」:按入度 / 稳定度给每环推荐切边
  • 支持更多语言(Python import、Go import)的相对依赖解析

FAQ

Q:为什么 npm 包(如 react)不算依赖边? 只解析以 ./ ../ 开头的相对引用,因为 npm 包 / 别名 / 内置模块解析需要 node_modules 与配置,超出本插件的只读、零依赖边界。所以边表示「本地文件之间的结构关系」。

Q:import './util' 没有扩展名怎么解析? 启发式尝试补齐扩展名:依次试 .js .jsx .mjs .cjs .ts .tsx,若指向目录则试 index.js 等。优先取第一个在扫描文件集合中命中的。

Q:循环依赖检测准吗? DFS 环检测是标准的、准确的(给定正确的边)。边本身来自启发式解析,个别复杂 import 形态可能漏一条边,从而漏掉对应环;识别出的环都是真实存在的。

Q:同一个环为什么不会重复输出? 一个环从不同节点进入栈会出现多次。本插件把环「旋转到最小起点」并规范化成唯一键去重,每个环只输出一次。

Q:孤立文件一定是废弃代码吗? 不一定。可能被 import() 变量路径、插件注册、构建工具的字符串引用动态调用。orphan_files 只报告「无入无出」,是否删除需结合业务判断。

Q:为什么跳过 node_modules? node_modules 数量大、多为第三方,解析无意义且拖慢。dist / build / coverage 同理。需要分析这些目录时用 exclude 反向指定即可(默认名单可整体绕过,但一般不推荐)。

Q:会执行我的代码吗? 不会。只读文本扫描 + 字符串 / 注释剥离 + 正则识别,不 eval、不加载、不运行任何被测文件。

Q:目录很大会不会卡? max_files(默认 500)限流扫描数量,max_size(默认 10240 KB)跳过超大文件,二进制文件不解析。

源码与发布地址

  • 源码:https://github.com/geeklei/dsh-plugins/tree/main/dsh-import-graph
  • npm:https://www.npmjs.com/package/dsh-import-graph

许可证

MIT