Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

submodule analysis of a huge monorepo with yarn workspaces #981

Open
marosivanco opened this issue Jan 9, 2025 · 3 comments
Open

submodule analysis of a huge monorepo with yarn workspaces #981

marosivanco opened this issue Jan 9, 2025 · 3 comments
Labels

Comments

@marosivanco
Copy link

Summary

We have a huge monorepo with yarn workspaces. The codebase has the following structure:

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

/package.json defines yarn workspaces:

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

Each app (1...N) has its own webpack/esling/ts configuration.
Each app can use different version of babel, typescript...
Each app imports modules using paths:

  • relative to module, e.g. import '../dir1/dir2/module'
  • relative to app, e.g. import '@/dir1/dir2/module'
  • relative to package, e.g. import '@base/i18n/module'

webpack.config.js and tsconfig.json properly set the aliases:

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/*"]
        }

Since the repo is huge, I would like to analyze only a submodule pageM of a appN.
I initialized cruiser with: depcruise --init in /.
Then I am tried variations of
depcruise --include-only "pageM" --output-type dot appN/src | dot -T svg > dependencygraph.svg
but cannot get sensible results.
Module in a packages is resolved in SVG sometimes as ../packages/ui/src/module sometimes as @base/ui/src/module, that is as two modules instead of one.
Modules with app root alias @/page1/module are resolved as different from page1/module - seams as if @ alias is not handled properly.

depcruise --info reported that neither babel nor typescript is used. So I installed them in the /.
I tweaked the exclude and doNotFollow options to make the SVG more readable. I ended up with:
depcruise --output-type dot appN/src/pageM | dot -T svg > dependencygraph.svg

Aside the aforementioned path resolving issues, I get tons of not-to-unresolvable edges in SVG.
I have also noticed, that if moduleA imports symbol S from moduleB, the resulting SVG includes not just symbol S but all the other symbols of moduleB and their transitive dependencies. Webpack implements tree-shaking to get rid of unused symbols and dependencies. Maybe the depcruiser could implement something similar.

The configuration is quite complex so maybe I am missing a setting or a combination.

To sum things up:

  1. module is included multiple times - path aliases are not resolved properly. Could you please confirm that this is an error?
  2. resulting graph has many not-to-unresolvable edges. I have no idea why. Any suggestions?
  3. resulting graph should contain only the modules, that are really used. Is there a setting or a combination? Any idea how to achieve that?

I am not sure if I am hitting bug, feature, feature request or maybe I just need to use a combination of settings.
Any response, that will move me forward is appreciated.

Context

I am trying to get helicopter view of the react component subset in a huge repository.

@austinm911
Copy link

austinm911 commented Jan 12, 2025

Related note, i'm also running into many not-to-unresolvable issues in a monorepo.

My monorepo follows a turborepo structure. Could we get some additional documentation/recipes/examples for a monorepo structure? The three repos below could all be used as examples and are pretty straight forward to understand.
https://github.com/AnswerOverflow/AnswerOverflow
https://github.com/midday-ai/v1
https://github.com/midday-ai/midday

Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions bot added the stale label Jan 23, 2025
@sverweij sverweij reopened this Jan 28, 2025
@sverweij sverweij added question and removed stale labels Jan 28, 2025
@sverweij
Copy link
Owner

Hi @marosivanco answering your question took a bit longer as my off line life asked for attention in the past few weeks.

It looks like the issues you bump into are related to a future feature to support multiple contexts for alias resolutions (e.g. multiple, not necessarily related, tsconfigs that are applicable to different parts of a repo).

The current 'workaround' is installing dependency-cruiser for each of these contexts and running them individually. Apart from the drawback of the manual labor that approach might miss dependencies you do want to see...

So the prio of the future feature went up a notch.

@austinm911 thanks for the sample repos - those are always useful.

  • https://github.com/AnswerOverflow/AnswerOverflow/ this is cooked with bun, which seems to have added some new stuff to the already impressive array of resolution options in javascript land. I'll take a closer look later.
  • The other two repos seem to be bun repo's as well, but have added locally scoped tsconfigs in the mix (with 'local' tsconfigs that alias everyting in a scope to @) - which need aforementioned future feature in dependency-cruiser.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants