dependency-cruiser icon indicating copy to clipboard operation
dependency-cruiser copied to clipboard

Feature request: Dependency Cruiser as an eslint plugin

Open kyranjamie opened this issue 2 years ago • 3 comments

dependency-cruiser is awesome, it fills a tooling gap I've needed for a long time. Fantastisch werk @sverweij. While I do wish it worked with globs, at least it's a reason to become a regex pro.

For the Hiro Wallet, we're using depcruiser pretty extensively.

Nonetheless, it's another tool in our stack, and I'm curious about the viability of this being a eslint plugin. What I'd really like is a github & editor integrations, highlighting forbidden imports, so they can be fixed proactively, rather than reactively when our CI jobs fails. Think: eslint squiggly line under the import at dev-time.

Has this been considered? Are there implementation details that make this infeasible? Could a bridge be made between the two?

kyranjamie avatar Nov 25 '21 11:11 kyranjamie

Dank voor de vriendelijke woorden @kyranjamie :-)

I've indeed investigated implementing an eslint plugin for dependency-cruiser. To understand how eslint plugins work I even wrote a simple one (eslint-plugin-budapestian). It is possible to cover part of dependency-cruiser's (validation) functionality in an eslint plugin, but it will be a bit of an effort.

functionally

  • Rules that require knowledge of a modules dependents (e.g. orphan and reachability rules and the upcoming stable dependencies validation) are likely tough to do (if possible at all) as an eslint plugin, especially when it needs to be fast enough to be helpful in an editor context.
  • cycle checks should be doable, but I'm a bit sceptic it'll be easy to get fast enough for an editor context, but maybe I'm just pessimistic :-)
  • eslint works with one parser at a time (either the typescript one or the javascript one). This makes pre-compilation related checks dependency-cruiser can currently do tougher to implement.
  • not investigated: if and how eslint works with svelte or vue's single file components

Other rules seem doable, though.

technically

Making an eslint plugin for dependency-cruiser rules would involve taking the AST as passed from eslint, pluck out the dependencies (requires, imports, exports, triple slash directives, exotics) and for each of them:

  • transform it into a format digestible for dependency-cruiser (custom code, but likely fairly trivial)
  • resolve the found dependencies to concrete files on disk (can reuse dependency-cruiser code)
  • derive things that are not part of the AST yet (cycles, whether it's an external module or not, whether it's declared in package.json etc - can reuse dependency-cruiser code)
  • validate (can reuse dependency-cruiser code)

Other things:

  • We'd have to ensure to take the right configuration files into account (apart from .dependency-cruiser.js - tsconfig/ jsconfig, babelrc, webpack config and possibly the dependency-cruiser-known-violations.json) - I assume the .eslintrc can play a role there.
  • We might want to issue a warning for rules that can't be covered with the plugin (yet) with the hint to run the standalone version of dependency-cruiser.

sverweij avatar Nov 27 '21 12:11 sverweij

Interesting topic. I also think that an eslint plugin would be overkill, because eslint checks should be fast. Here are some ideas that come to mind:

  • eslint has https://eslint.org/docs/rules/no-restricted-imports which let's you restrict imports. Obviously much less powerful than dependency-cruiser
  • in addition to CI, you could run d-c in a pre-commit / pre-push hook locally, possibly via husky or similar so that every dev gets the same feedback
  • For editor support, maybe d-c could run as a language server

Narretz avatar Jan 14 '22 19:01 Narretz

I had a stab at this that you can check out here: https://github.com/pekala/eslint-plugin-dependency-cruiser It's fairly basic and only covers a subset of what could be done. I chose to run dependency-cruiser for each file at maxDepth: 1 so it performs ok for making changes to a single file, but when running a whole ESLint suite for a large codebase, it's very slow. Would love to brainstorm on ideas for how to make it better!

pekala avatar Jul 18 '22 10:07 pekala