UNPKG

dependency-tree

Version:
120 lines (92 loc) 6.07 kB
# dependency-tree [![CI](https://img.shields.io/github/actions/workflow/status/dependents/node-dependency-tree/ci.yml?branch=main&label=CI&logo=github)](https://github.com/dependents/node-dependency-tree/actions/workflows/ci.yml?query=branch%3Amain) [![npm version](https://img.shields.io/npm/v/dependency-tree?logo=npm&logoColor=fff)](https://www.npmjs.com/package/dependency-tree) [![npm downloads](https://img.shields.io/npm/dm/dependency-tree)](https://www.npmjs.com/package/dependency-tree) > Get the dependency tree of a module ```sh npm install dependency-tree ``` * Supports JS (AMD, CommonJS, ES6), TypeScript, and CSS preprocessors (PostCSS, Sass, Stylus, Less) - any type handled by [precinct](https://github.com/dependents/node-precinct) - CommonJS: third-party (npm) dependencies are included by default - Path resolution is handled by [filing-cabinet](https://github.com/dependents/node-filing-cabinet); RequireJS and webpack loaders are supported * Core Node built-ins (assert, path, fs, etc.) are excluded by default ## Usage ```js // ESM import dependencyTree from 'dependency-tree'; // CommonJS const { default: dependencyTree } = require('dependency-tree'); // Returns a nested dependency tree object for the given file const tree = dependencyTree({ filename: 'path/to/a/file', directory: 'path/to/all/files', requireConfig: 'path/to/requirejs/config', // optional webpackConfig: 'path/to/webpack/config', // optional tsConfig: 'path/to/typescript/config', // optional nodeModulesConfig: { entry: 'module' }, // optional filter: (dependencyPath, parentPath) => !dependencyPath.includes('node_modules'), // optional nonExistent: [], // optional noTypeDefinitions: false // optional }); // Returns a post-order flat list of absolute paths (dependencies before dependents). // Useful as a concatenation order for bundling. const list = dependencyTree.toList({ filename: 'path/to/a/file', directory: 'path/to/all/files' }); ``` ### Options | Option | Type | Default | Description | |---|---|---|---| | `filename` | `string` | - | **Required.** Absolute path to the entry file | | `directory` | `string` | - | **Required.** Root directory used to resolve relative paths | | `root` | `string` | `undefined` | Alias for `directory` | | `requireConfig` | `string` | `undefined` | Path to a RequireJS config for AMD modules (resolves aliased paths) | | `config` | `string` | `undefined` | Alias for `requireConfig` | | `webpackConfig` | `string` | `undefined` | Path to a webpack config for aliased modules | | `tsConfig` | `string \| object` | `undefined` | Path to a TypeScript config file, or a preloaded config object | | `tsConfigPath` | `string` | `undefined` | Virtual path for the TypeScript config when `tsConfig` is an object. Required for [Path Mapping](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping); ignored when `tsConfig` is a string path | | `nodeModulesConfig` | `object` | `undefined` | Config for resolving `node_modules` entry files (e.g. `{ entry: 'module' }`) | | `visited` | `object` | `{}` | Memoization cache (filename to subtree) to skip already-processed files | | `nonExistent` | `string[]` | `[]` | Array populated with partial paths that could not be resolved | | `isListForm` | `boolean` | `false` | Return a flat post-order list of paths instead of a nested tree (same as calling `dependencyTree.toList()`) | | `filter` | `(dependencyPath: string, parentPath: string) => boolean` | `undefined` | Return `true` to include a dependency (and its subtree) in the tree | | `detectiveConfig` | `object` | `{}` | Options passed to [precinct](https://github.com/dependents/node-precinct#usage) for dependency extraction - e.g. `{ amd: { skipLazyLoaded: true } }`, `{ ts: { skipTypeImports: true } }` | | `detective` | `object` | `{}` | Alias for `detectiveConfig` | | `noTypeDefinitions` | `boolean` | `false` | Resolve TypeScript imports to `*.js` instead of `*.d.ts` | ### Output format The default output is a nested object where every key is an absolute file path and the value is its own subtree: ```js { '/path/to/a.js': { '/path/to/b.js': { '/path/to/d.js': {}, '/path/to/e.js': {} }, '/path/to/c.js': { '/path/to/f.js': {}, '/path/to/g.js': {} } } } ``` This format was designed for visual representation in the [Dependents](https://github.com/mrjoelkemp/sublime-dependents) plugin. ### CLI Requires a global install: `npm install -g dependency-tree` ``` dependency-tree --directory=path/to/files [--list-form] [--es6-mixed-imports] [-c path/to/require/config] [-w path/to/webpack/config] filename ``` Prints the dependency tree as JSON. Use `--list-form` to print one path per line instead. ## How it works dependency-tree passes the entry file to [precinct](https://github.com/dependents/node-precinct/) to extract raw dependency strings, then passes each to [filing-cabinet](https://github.com/dependents/node-filing-cabinet) to resolve them to real filesystem paths, and recurses until the full tree is built. Precinct generates an AST via [node-source-walk](https://github.com/dependents/node-source-walk), detects the module format (CommonJS, AMD, or ES6), and delegates to the appropriate detective to extract dependency declarations. Filing-cabinet reuses that AST to detect the module format again, then delegates to the right resolver - necessary because AMD supports path aliasing via a RequireJS config, while CommonJS has its own resolution algorithm. The resolver returns an absolute path, which dependency-tree then recurses into. ## FAQ ### Why aren't some dependencies being detected? Bugs in [precinct](https://github.com/dependents/node-precinct) or an incomplete `requireConfig`/`webpackConfig`/`tsConfig` are the most common causes. Any path that could not be resolved is appended to the array passed as `nonExistent`. For detailed resolution logs, set `NODE_DEBUG=*` when using the CLI: ```sh NODE_DEBUG=* dependency-tree -w path/to/webpack.config.json path/to/a/file ```