A robust static dependency analyzer for your JavaScript
and TypeScript
projects with Rust
!
Highlights | Install | Usage | Options | API
This is fork from acrazing/dpdm, and compability with
dpdm
99%. It's faster and bring a performance improvement of more than ten times!(Please use--no-progress
to be fastest,progress
will be slower thandpdm
withnode
).
- Supports
CommonJS
,ESM
. - Supports
JavaScript
andTypeScript
completely.- Supports TypeScript path mapping.
- Supports ignore TypeScript type dependencies.
- Light weight: use TypeScript to parse all modules.
- Fast: use
Rust
andswc-parser
to parse all modules. This will bring a performance improvement of more than ten times! - Stable output: This is compared to
madge
, whose results are completely inconclusive when analyzeTypeScript
.
-
For command line
npm i -g dpdm-fast # or via yarn yarn global add dpdm-fast
-
As a module
npm i -D dpdm-fast # or via yarn yarn add -D dpdm-fast
-
Simple usage
dpdm ./src/index.ts
-
Print circular dependencies only
dpdm --no-warning --no-tree ./src/index.ts
-
Exit with a non-zero code if a circular dependency is found.
dpdm --exit-code circular:1 ./src/index.ts
-
Ignore type dependencies for TypeScript modules
dpdm -T ./src/index.ts
-
Find unused files by
index.js
insrc
directory:dpdm --no-tree --no-warning --no-circular --detect-unused-files-from 'src/**/*.*' 'index.js'
-
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
$ dpdm --help
Analyze the files' dependencies.
Usage: dpdm [OPTIONS] <FILES>...
Arguments:
<FILES>... The file paths or globs
Options:
--context <CONTEXT>
The context directory to shorten path, default is current directory
-e, --extensions <EXTENSIONS>
Comma separated extensions to resolve [default: ts,tsx,mjs,js,jsx,json]
--js <JS>
Comma separated extensions indicate the file is js like [default: ts,tsx,mjs,js,jsx]
--include <INCLUDE>
Included filenames regexp in string, default includes all files [default: .*]
--exclude <EXCLUDE>
Excluded filenames regexp in string, set as empty string to include all files [default: node_modules]
-o, --output <OUTPUT>
Output json to file
--no-tree
Print tree to stdout
--circular
Print circular to stdout
--no-warning
Print warning to stdout
--tsconfig <TSCONFIG>
The tsconfig path, which is used for resolve path alias
-T, --transform
Transform typescript modules to javascript before analyze
--exit-code <EXIT_CODE>
Exit with specified code
--no-progress
Show progress bar
--detect-unused-files-from <DETECT_UNUSED_FILES_FROM>
This file is a glob, used for finding unused files
--skip-dynamic-imports <SKIP_DYNAMIC_IMPORTS>
Skip parse import(...) statement
-h, --help
Print help
-V, --version
Print version
TODO: This part has not yet been completed. So if you call the API, it will auto use
dpdm-ts
. Next time I will usewasm-bindgen
to call rust api.
import { parseDependencyTree, parseCircular, prettyCircular } from 'dpdm';
parseDependencyTree('./index', {
/* options, see below */
}).then((tree) => {
const circulars = parseCircular(tree);
console.log(prettyCircular(circulars));
});
-
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>;
-
parseCircular(tree)
: parse circulars in dependency treeexport declare function parseCircular(tree: DependencyTree): string[][];
- [ ] Supports HTML and HTML like modules
- [ ] Supports CSS and CSS like modules
- [ ] Prints interactive SVG