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

Feature request: Allow module names instead of paths for reaches, doNotFollow, etc. #806

Open
mrmckeb opened this issue May 9, 2023 · 3 comments
Assignees
Labels
enhancement this will make dependency-cruiser sweeter

Comments

@mrmckeb
Copy link
Contributor

mrmckeb commented May 9, 2023

Context

I'd like to be able to pass module names to dependency-cruiser, instead of paths to node modules, so that I can match those without having to list all potential paths.

I'm using the JS API, and want to support user input in my wrapper. The below references to "chalk" are just for example.

Expected Behavior

In this scenario, I want to find all modules that reach chalk, but not modules within chalk that reference other chalk modules.

const options = {
  reaches: ['^chalk$'],
  doNotFollow: ['^chalk$'],
};

Current Behavior

The example above returns no matches. With pnpm (7.x, 8.x), I need to use the following to get the example above to work.

const options = {
  reaches: [^node_modules/.pnpm/chalk@5.2.0/node_modules/chalk'],
  doNotFollow: [^node_modules/.pnpm/chalk@5.2.0/node_modules/chalk'],
};

If someone installed a new version of chalk in the monorepo, this wouldn't catch that version.

Possible Solution

I think adding moduleNames (or modules) alongside paths might be a good solution here.

const options = {
  reaches: {
    moduleNames: ['^chalk$'],
  },
  doNotFollow: {
    moduleNames: ['^chalk$'],
  },
};

Considered alternatives

I realise that I can just pass the string, but this would match any package with "chalk" in its name, i.e. definitely-not-chalk.

const options = {
  reaches: {
    moduleNames: ['chalk'],
  },
  doNotFollow: {
    moduleNames: ['chalk'],
  },
};

I could also pass with slashes, but that could match an internal directory of the same name, i.e. utils/chalk/wrapper.ts.

const options = {
  reaches: {
    moduleNames: ['/chalk/'],
  },
  doNotFollow: {
    moduleNames: ['/chalk/'],
  },
};
@sverweij
Copy link
Owner

sverweij commented May 14, 2023

hi @mrmckeb thanks for this suggestion! This can indeed be useful, and not only for the scenario you describe. Reason dependency-cruiser started out with resolved paths only is that it's the only way a module can be uniquely identified - the shorthand names (local/ relative inclusions, aliasses, node_modules, tsconfig paths) don't have that property.

I'm looking for a way to add it - looks like it's something that should fit within the scope of a weekend; I'll keep you posted in this issue - but in the mean time it might in some cases possible to use a quick'n dirty trick: require.resolve the module and then path.relative it:

import { relative } from "node:path";

// next two lines only necessary in ESM:
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);


// ...
const options = {
  reaches: {
    path: [relative(process.cwd(), require.resolve("chalk"))],
  }
};

@mrmckeb
Copy link
Contributor Author

mrmckeb commented May 16, 2023

Thank you! And a good idea on the "quick'n dirty" workaround!

@github-actions
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 May 25, 2023
@sverweij sverweij self-assigned this May 25, 2023
@sverweij sverweij added enhancement this will make dependency-cruiser sweeter and removed stale labels May 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement this will make dependency-cruiser sweeter
Projects
None yet
Development

No branches or pull requests

2 participants