dependency-cruiser

repository·main·Indexed 27 days ago

https://github.com/sverweij/dependency-cruiser

A tool for validating and visualizing dependencies in JavaScript, TypeScript, CoffeeScript, and LiveScript projects. It supports ES6, CommonJS, and AMD, allowing developers to enforce architectural rules via a configuration file and generate dependency graphs in formats such as DOT, HTML, and Mermaid. The package includes a CLI, a programmatic API, and specialized tools like depcruise-baseline and depcruise-fmt.

Tokens
48.9K
Snippets
148
Records
271
Agent score
91%

What's inside dependency-cruiser

  1. Configure dependency-cruiser for Svelte

    main

    Dependency-cruiser supports .svelte files using the svelte (version 4.x) package.

    Because Svelte files automatically depend on "svelte/internal", you may find this dependency noisy. You can ignore it using the configuration file or a command-line parameter.

  2. Use the dependency-cruiser API programmatically

    main

    While dependency-cruiser is typically used via the CLI, you can use its programmatic API to retrieve module dependencies. The API follows the same semantic versioning as the CLI.

    To perform a basic cruise, import the cruise function and pass an array of files or directories to be analyzed. The function returns an IReporterOutput object containing the dependency information in its output property.

    import { cruise, type IReporterOutput } from "dependency-cruiser";
    
    const ARRAY_OF_FILES_AND_DIRS_TO_CRUISE: string[] = ["src"];
    try {
      const cruiseResult: IReporterOutput = await cruise(
        ARRAY_OF_FILES_AND_DIRS_TO_CRUISE,
      );
      console.dir(cruiseResult.output, { depth: 10 });
    } catch (pError) {
      console.error(pError);
    }
  3. Validate dependencies against a configuration file

    main

    By default, dependency-cruiser looks for a configuration file named .dependency-cruiser.js, .dependency-cruiser.cjs, .dependency-cruiser.mjs, or .dependency-cruiser.json.

    To use a custom configuration file, use the --config flag. If you want to run the tool without any configuration, use --no-config.

    Tip: If you are passing arguments (like file paths) after the --config flag, use -- to separate the options from the arguments to prevent the tool from interpreting your paths as configuration files.

    dependency-cruise -x node_modules --config my.rules.json src spec
    
    # To prevent paths from being interpreted as config files:
    dependency-cruise --config -- src
  4. Configure dependency-cruiser rules

    main

    A dependency-cruiser configuration is typically a JSON or JavaScript file that exports an object. The core sections for defining dependency constraints are forbidden, allowed, required, and options.

    • forbidden: A list of rules describing dependencies that are not allowed. Violations emit error/warning/info messages.
    • allowed: A list of rules describing dependencies that are permitted. Any dependency not satisfying at least one rule triggers a 'not-in-allowed' message.
    • required: A list of rules describing mandatory dependencies (e.g., 'every controller must depend on the base controller').
    • options: Configuration settings that influence how the cruise is performed.

    To quickly generate a starting configuration, run:

    depcruise --init
    {
      "forbidden": [],
      "allowed": [],
      "required": [],
      "options": {}
    }
  5. Generate dependency graphs (v12 and older)

    main
    In dependency-cruiser versions 12 and older, you must explicitly pass the --config option to locate the .dependency-cruiser.js file.
    ```shellnpx depcruise src --include-only "^src" --config --output-type dot | dot -T svg > dependency-graph.svg
  6. Handle node_modules violations separately

    main

    To prevent third-party dependencies in node_modules from breaking your build while still tracking them, create two separate rules:

    1. An error rule for your source code (using pathNot: "^node_modules").
    2. A warn rule for node_modules (using path: "^node_modules").
    {
      "forbidden": [
        {
          "name": "not-to-core-http",
          "severity": "error",
          "from": { "pathNot": "^node_modules" },
          "to": { "dependencyTypes": ["core"], "path": "^http$" }
        },
        {
          "name": "node_mods-not-to-http",
          "severity": "warn",
          "from": { "path": "^node_modules" },
          "to": { "dependencyTypes": ["core"], "path": "^http$" }
        }
      ]
    }
  7. Generate dependency graphs for React

    main

    To generate dependency graphs for a React repository, follow these steps to set up the environment and run the analysis:

    1. Prepare the environment:
      • Clone the repo and install dependencies.
      • Add dependency-cruiser as a dev dependency.
      • Download the react-dependency-cruiser-config.js.
    2. Add these scripts to package.json:
    "scripts": {
      "dc": "depcruise --version && depcruise --ignore-known --config react-dependency-cruiser-config.js -T err packages/*/{*.js,src}",
      "depcruise:baseline": "depcruise --version && depcruise-baseline packages/*/{*.js,src} --config react-dependency-cruiser-config.js",
      "depcruise:archi": "depcruise --ignore-known --config react-dependency-cruiser-config.js -T archi packages/*/{*.js,src} | dot -T svg | tee react-high-level-dependencies.svg | depcruise-wrap-stream-in-html > react-high-level-dependencies.html"
    }
    1. Run yarn depcruise:baseline to establish a baseline, then yarn depcruise:archi to generate the architectural graph.
    git clone git@github.com:facebook/react.git
    cd react
    yarn
    yarn add -D -W dependency-cruiser
    rm -f react-dependency-cruiser-config.js
    wget https://raw.githubusercontent.com/sverweij/dependency-cruiser/main/doc/real-world-samples/react-dependency-cruiser-config.js
    
    # In package.json:
    "dc": "depcruise --version && depcruise --ignore-known --config react-dependency-cruiser-config.js -T err packages/*/{*.js,src}",
    "depcruise:baseline": "depcruise --version && depcruise-baseline packages/*/{*.js,src} --config react-dependency-cruiser-config.js",
    "depcruise:archi": "depcruise --ignore-known --config react-dependency-cruiser-config.js -T archi packages/*/{*.js,src} | dot -T svg | tee react-high-level-dependencies.svg | depcruise-wrap-stream-in-html > react-high-level-dependencies.html"
    
    yarn depcruise:baseline
    yarn depcruise:archi
  8. Detect dead wood or transient dependencies with `reachable`

    main

    The reachable attribute (Boolean) in the to section determines if modules matching the to criteria are reachable from the modules matching the from criteria.

    Use Case 1: Detect Dead Wood

    Set "reachable": false to find modules that are part of your source but cannot be reached from your entry point (e.g., src/index.js).

    Use Case 2: Prevent Transient Dependencies (Via-Via)

    Set "reachable": true to ensure that certain modules are never reached through a chain of imports. For example, preventing schema files from ever reaching database implementation files, even indirectly.

    Usage Notes:

    • Rules with reachable can only have path and pathNot in the from part.
    • In the to part, you can use path, pathNot, and reachable together.
    {
        "name": "no-unreachable-from-root",
        "severity": "error",
        "from": { "path": "src/index\\.js$" },
        "to": {
            "path": "src",
            "pathNot": "\\.spec\\.(js|ts)$|\\.d\\.ts$",
            "reachable": false
        }
    }
  9. Generate high-level dependency graphs for Yarn Berry (v2+)

    main

    To generate a high-level dependency graph for a Yarn Berry project, you must use the local depcruise installation to ensure Yarn's PnP (Plug'n'Play) resolution works correctly.

    1. Install dependency-cruiser as a dev dependency in the root of the berry repo.
    2. Download the specific configuration file: berry-dependency-cruiser-config.js.
    3. Add the following scripts to your package.json to avoid using global or incorrectly resolved binaries:
    "scripts": {
      "dc": "depcruise --version && depcruise --config berry-dependency-cruiser-config.js --output-type err packages",
      "depcruise:archi": "depcruise --version && depcruise --config berry-dependency-cruiser-config.js --output-type archi packages | dot -T svg | tee berry-high-level-dependencies.svg | depcruise-wrap-stream-in-html > berry-high-level-dependencies.html"
    }
    1. Run yarn depcruise:archi to generate the SVG and interactive HTML graph.
    yarn
    yarn add -D dependency-cruiser
    rm -f berry-dependency-cruiser-config.js
    wget https://raw.githubusercontent.com/sverweij/dependency-cruiser/main/doc/real-world-samples/berry-dependency-cruiser-config.js
    
    # In package.json:
    "dc": "depcruise --version && depcruise --config berry-dependency-cruiser-config.js --output-type err packages",
    "depcruise:archi": "depcruise --version && depcruise --config berry-dependency-cruiser-config.js --output-type archi packages | dot -T svg | tee berry-high-level-dependencies.svg | depcruise-wrap-stream-in-html > berry-high-level-dependencies.html"
    
    yarn depcruise:archi