使用 yarn 工作空间分析巨大的 monorepo 的子模块

作者: marosivanco创建于 2025年1月9日更新于 2025年1月30日
标签question

我们有一个庞大的单一仓库,其中包含 yarn 工作空间。代码库的结构如下:

/app1
   /page1
   /page2
   ...
   tsconfig.json
   webpack.config.js
/app2
   /page1
   /page2
   ...
   tsconfig.json
   webpack.config.js
...
/packages
   /i18n
   /ui
...

/package.json 定义了 yarn 工作空间:

"workspaces": [
        "app1",
        "app2",
        ...
        "packages/*"
    ]

每个应用程序 (1...N) 都有自己的 webpack/esling/ts 配置。每个应用程序可以使用不同版本的 babel、TypeScript…。每个应用程序使用以下路径导入模块:

  • 相对于模块,例如 import '../dir1/dir2/module'
  • 相对于应用程序,例如 import '@/dir1/dir2/module'
  • 相对于包,例如 import '@base/i18n/module'

webpack.config.js 和 tsconfig.json 正确设置了别名:

webpack.config.js

   resolve: {
        alias: {
            classnames: 'clsx',
            'lodash-es': 'lodash',
            '@': path.resolve('src'),
        },
    },

tsconfig.json

       "paths": {
            "@/*": ["src/*"],
            "@base/i18n": ["../packages/i18n/src/index.ts"],
            "@base/ui/*": ["../packages/ui/*"]
        }

由于仓库非常庞大,我想只分析 appN 中的子模块 pageM。我使用 depcruise --init 在 / 目录中初始化 cruiser。然后,我尝试了以下变化: depcruise --include-only "pageM" --output-type dot appN/src | dot -T svg > dependencygraph.svg 但无法获得可靠的结果。包中的模块有时在 SVG 中被解析为 ../packages/ui/src/module,有时为 @base/ui/src/module,即为两个模块而不是一个。具有应用程序根别名 @/page1/module 的模块在 SVG 中被解析为与 page1/module 不同 - 看起来好像 @ 别名没有得到正确处理。 depcruise --info 报告了既没有使用 babel,也没有使用 TypeScript。因此,我在 / 目录中安装了它们。我调整了 exclude 和 doNotFollow 选项,以使 SVG 更易于阅读。最终结果为: depcruise --output-type dot appN/src/pageM | dot -T svg > dependencygraph.svg

除了上述路径解析问题之外,我还在 SVG 中获得了大量 不可以解析 边。我还注意到,如果模块 A 从模块 B 中导入符号 S,则生成的 SVG 中不仅包含符号 S,还包含模块 B 中的所有其他符号及其传递依赖。Webpack 实现了树摇动,以消除未使用的符号和依赖。也许 depcruiser 能够实现类似的功能。

内容来源: sverweij/dependency-cruiser