Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

acrazing/dpdm

Repository files navigation

A robust static dependency analyzer for your JavaScript and TypeScript projects.

Highlights | Install | Usage | Options | API

Highlights

  • Supports CommonJS, ESM.
  • Supports JavaScript and TypeScript completely.
    • Supports TypeScript path mapping.
    • Supports ignore TypeScript type dependencies.
  • Light weight: use TypeScript to parse all modules.
  • Fast: use asynchronous API to load modules.
  • Stable output: This is compared to madge, whose results are completely inconclusive when analyze TypeScript.

Install

  1. For command line

    npm i -g dpdm
    # or via yarn
    yarn global add dpdm
  2. As a module

    npm i -D dpdm
    # or via yarn
    yarn add -D dpdm

Usage in command line

  1. Simple usage

    dpdm ./src/index.ts
  2. Print circular dependencies only

    dpdm --no-warning --no-tree ./src/index.ts
  3. Exit with a non-zero code if a circular dependency is found.

    dpdm --exit-code circular:1 ./src/index.ts
  4. Ignore type dependencies for TypeScript modules

    dpdm -T ./src/index.ts
  5. Find unused files by index.js in src directory:

    dpdm --no-tree --no-warning --no-circular --detect-unused-files-from 'src/**/*.*' 'index.js'
  6. Skip dynamic imports:

    # The value circular will only ignore the dynamic imports
    # when parse circular references.
    # You can set it as tree to ignore the dynamic imports
    # when parse source files.
    dpdm --skip-dynamic-imports circular index.js

Options

dpdm [options] <files...>
Analyze the files' dependencies.

Positionals:
 files The file paths or globs [string]

Options:
 --version Show version number [boolean]
 --context the context directory to shorten path, default is current
 directory [string]
 --extensions, --ext comma separated extensions to resolve
 [string] [default: ".ts,.tsx,.mjs,.js,.jsx,.json"]
 --js comma separated extensions indicate the file is js like
 [string] [default: ".ts,.tsx,.mjs,.js,.jsx"]
 --include included filenames regexp in string, default includes all files
 [string] [default: ".*"]
 --exclude excluded filenames regexp in string, set as empty string to
 include all files [string] [default: "node_modules"]
 -o, --output output json to file [string]
 --tree print tree to stdout [boolean] [default: true]
 --circular print circular to stdout [boolean] [default: true]
 --warning print warning to stdout [boolean] [default: true]
 --tsconfig the tsconfig path, which is used for resolve path alias, default
 is tsconfig.json if it exists in context directory [string]
 -T, --transform transform typescript modules to javascript before analyze, it
 allows you to omit types dependency in typescript
 [boolean] [default: false]
 --exit-code exit with specified code, the value format is CASE:CODE,
 `circular` is the only supported CASE, CODE should be a integer
 between 0 and 128. For example: `dpdm --exit-code circular:1` the
 program will exit with code 1 if circular dependency found.
 [string]
 --progress show progress bar [boolean] [default: true]
 --detect-unused-files-from this file is a glob, used for finding unused files. [string]
 --skip-dynamic-imports Skip parse import(...) statement.
 [string] [choices: "tree", "circular"]
 -h, --help Show help [boolean]

Example output

Screenshot

Usage as a package

import { parseDependencyTree, parseCircular, prettyCircular } from 'dpdm';
parseDependencyTree('./index', {
 /* options, see below */
}).then((tree) => {
 const circulars = parseCircular(tree);
 console.log(prettyCircular(circulars));
});

API Reference

  1. parseDependencyTree(entries, option, output): parse dependencies for glob entries

    /**
     * @param entries - the glob entries to match
     * @param options - the options, see below
     */
    export declare function parseDependencyTree(
     entries: string | string[],
     options: ParserOptions,
    ): Promise<DependencyTree>;
    /**
     * the parse options
     */
    export interface ParseOptions {
     context: string;
     extensions: string[];
     js: string[];
     include: RegExp;
     exclude: RegExp;
     tsconfig: string | undefined;
     onProgress: (event: 'start' | 'end', target: string) => void;
     transform: boolean;
     skipDynamicImports: boolean;
    }
    export enum DependencyKind {
     CommonJS = 'CommonJS', // require
     StaticImport = 'StaticImport', // import ... from "foo"
     DynamicImport = 'DynamicImport', // import("foo")
     StaticExport = 'StaticExport', // export ... from "foo"
    }
    export interface Dependency {
     issuer: string;
     request: string;
     kind: DependencyKind;
     id: string | null; // the shortened, resolved filename, if cannot resolve, it will be null
    }
    // the parse tree result, key is file id, value is its dependencies
    // if file is ignored, it will be null
    export type DependencyTree = Record<string, Dependency[] | null>;
  2. parseCircular(tree): parse circulars in dependency tree

    export declare function parseCircular(tree: DependencyTree): string[][];

TODOs

  • Supports HTML and HTML like modules
  • Supports CSS and CSS like modules
  • Prints interactive SVG

AltStyle によって変換されたページ (->オリジナル) /