npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sourcebug/dpdm

v1.0.15

Published

Analyze circular dependencies in your JavaScript/TypeScript projects.

Downloads

132

Readme

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; // context to shorten filename,           default is process.cwd()
      extensions: string[]; // the custom extensions to resolve file, default is [ '.ts', '.tsx', '.mjs', '.js', '.jsx', '.json' ]
      include: RegExp; // the files to parse match regex,        default is /\.m?[tj]sx?$/
      exclude: RegExp; // the files to ignore parse,             default is /\/node_modules\//
    }
    
    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