@flownet/lib-parse-imports-js
v0.4.7
Published
Downloads
447
Readme
@flownet/lib-parse-imports-js
Introduction
The @flownet/lib-parse-imports-js is a tool designed to analyze JavaScript and TypeScript files to determine their module import dependencies. This utility helps users understand which modules are imported, identifies unused imports, and distinguishes between local, npm, and Node.js built-in modules. It is useful for developers who want to manage and optimize their codebase by identifying unnecessary dependencies.
How It Works
The tool reads a specified JavaScript or TypeScript file and parses it to extract all import statements. It checks for both static imports and dynamic imports, as well as require() calls. The tool then categorizes each import as local, npm, or built-in Node.js module. It can also recursively analyze dependencies, providing a comprehensive view of the module's dependencies.
Key Features
- Parses JavaScript and TypeScript files to list all module imports.
- Differentiates between local, npm, and built-in Node.js modules.
- Identifies unused or unreferenced imports in the code.
- Supports recursive analysis of dependencies.
- Outputs a detailed list of all, unreferenced, unnecessary, and required modules.
Conclusion
The @flownet/lib-parse-imports-js tool provides developers with valuable insights into their project's module dependencies. By identifying and categorizing imports, it helps improve code maintenance by addressing unused dependencies, thus making the codebase cleaner and potentially improving performance.
Developer Guide for "@flownet/lib-parse-imports-js"
Overview
The "@flownet/lib-parse-imports-js" library analyzes JavaScript and TypeScript
files to extract and analyze their import graph. Starting from an entry file it
discovers every referenced module — via static import, require(), dynamic
import(), and export ... from re-exports — and categorizes each as a
local file, an npm package, or a Node.js built-in. It also tracks
which imports are actually used, so it can report unreferenced and unnecessary
modules to help keep a codebase clean.
The result can be returned as a structured object (default) or rendered as a Mermaid diagram, an ASCII tree, or a Graphviz DOT graph, and optionally written straight to a file.
Installation
You can install the "@flownet/lib-parse-imports-js" library using either npm or yarn:
Using npm:
npm install @flownet/lib-parse-imports-jsUsing yarn:
yarn add @flownet/lib-parse-imports-jsAPI
The default export is an async function. All options are passed as a single object:
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| file | string | (required) | Path to the entry file to analyze. |
| recursive | boolean | false | Follow local imports to analyze the whole dependency tree. |
| verbose | boolean | false | Emit verbose [VERBOSE] logging to the console for debugging. |
| format | "json" | "mermaid" | "tree" | "dot" | "json" | Output representation (see below). |
| output | string | null | If set, write the result to this file path and return a short confirmation string instead of the payload. |
Return value
- With
format: "json"(the default) the function returns the structured analysis object:{ all, unreferenced, unnecessary, required }. - With
format: "mermaid" | "tree" | "dot"it returns a presentation string. - With
outputset, it writes the rendered result to the file and returns a confirmation string (e.g.Wrote dot output to /abs/path).jsonis written as pretty-printed JSON; other formats are written as-is.
The result object fields:
all— every module discovered, each withtype,path,importedBy(with per-importusedflags),usesJSX, andusedByRequireOrDynamicImport.unreferenced— modules whose imports are never used in the importing file.unnecessary— modules that are not required according to the dependency graph.required— modules that are actually used.
Usage
import parseImports from '@flownet/lib-parse-imports-js';
const analyzeImports = async () => {
const result = await parseImports({
file: '/path/to/your/file.ts', // entry file to analyze
recursive: true, // analyze imports recursively
});
console.log('All Modules:', result.all);
console.log('Unreferenced:', result.unreferenced);
console.log('Unnecessary:', result.unnecessary);
console.log('Required:', result.required);
};
analyzeImports();Examples
Analyzing a Single File: To analyze a single file without following imports recursively, set
recursivetofalse.parseImports({ file: '/path/to/entry-file.ts', recursive: false, }).then(result => { console.log(result); });Recursive Import Analysis: To analyze your entire project including all nested dependencies, set
recursivetotrue.parseImports({ file: '/path/to/project/index.ts', recursive: true, }).then(result => { console.log(result); });Handling Node Built-in and Npm Modules: The library distinguishes between local, Node.js built-in, and npm modules. The built-in list is derived from Node itself (
node:module'sbuiltinModules), so it stays current and covers sub-paths such asfs/promisesand newer modules likeworker_threads.parseImports({ file: './src/app.ts', recursive: true, }).then(result => { console.log('Node Built-ins:', result.all.filter(mod => mod.type === 'node')); console.log('NPM Modules:', result.all.filter(mod => mod.type === 'npm')); });Finding Dead Imports: List modules whose imports are never used.
parseImports({ file: './src/app.ts', recursive: true }) .then(result => console.log('Unused:', result.unreferenced.map(m => m.path)));
Output Formats
Pass format to render the graph instead of returning the raw object. The
visual encoding uses the analysis data: type → colour, dead
(unreferenced/unnecessary) → red dashed, require()/dynamic import() →
dotted "dynamic" edge, and usesJSX → a jsx marker.
Mermaid (format: "mermaid")
Returns a flowchart string — ideal for embedding in Markdown / README files or
viewing in a PR. Best for small-to-medium graphs.
const diagram = await parseImports({ file: './src/app.ts', recursive: true, format: 'mermaid' });
console.log(diagram); // paste into a ```mermaid code blockTree (format: "tree")
Returns an ASCII dependency tree rooted at the entry point — a quick,
dependency-free view for the terminal. Shared dependencies are printed once;
later occurrences are marked with ↺.
app.ts
├─ util.ts
│ └─ sub.ts
├─ dead.ts (unused-import, dead)
├─ 📦 express
└─ ⚙️ node:fs (unused-import, dead)Graphviz DOT (format: "dot")
Returns a Graphviz digraph string. Local files are grouped into
subgraph cluster_* blocks by directory (and npm / node builtins into their
own clusters), so large codebases read as cluster-to-cluster structure rather
than a flat hairball. This is the format to use at scale.
const dot = await parseImports({ file: './src/main.ts', recursive: true, format: 'dot' });Render it with Graphviz (use sfdp for very large graphs):
dot -Tsvg deps.dot -o deps.svg
sfdp -Tsvg deps.dot -o deps.svg # better layout for thousands of nodesWriting to a File (output)
Set output to persist the rendered result. The function writes the file and
returns a confirmation string instead of the payload. Relative paths resolve
against the current working directory; the confirmation reports the absolute path.
// Write a DOT graph to disk
await parseImports({
file: './src/main.ts',
recursive: true,
format: 'dot',
output: 'deps.dot',
});
// → "Wrote dot output to /abs/path/deps.dot"
// Write pretty-printed JSON
await parseImports({ file: './src/main.ts', recursive: true, output: 'deps.json' });Rendering an existing result
The renderers are also exported as named functions, so you can analyze once and render the same result object multiple ways without re-parsing:
import parseImports, { renderMermaid, renderTree, renderDot } from '@flownet/lib-parse-imports-js';
const result = await parseImports({ file: './src/main.ts', recursive: true });
const mermaid = renderMermaid(result);
const tree = renderTree(result);
const dot = renderDot(result);CLI
When built as a Flownet node, the same options are available as CLI flags:
# Structured JSON to stdout
fnode cli --file src/main.ts --recursive
# Render a Mermaid / tree / dot graph
fnode cli --file src/main.ts --recursive --format tree
fnode cli --file src/main.ts --recursive --format mermaid
# Render DOT and write it to a file, then turn it into an SVG
fnode cli --file src/main.ts --recursive --format dot --output deps.dot
dot -Tsvg deps.dot -o deps.svgAcknowledgement
This library leverages several open-source tools, notably Babel's parser and
traverse modules, which parse and walk the codebase to extract import
statements efficiently, and Graphviz for the DOT output. The contributors to
these tools significantly aid the functionality provided by
"@flownet/lib-parse-imports-js".
Input Schema
$schema: https://json-schema.org/draft/2020-12/schema
type: object
properties:
file:
type: string
description: The path of the entry file to analyze.
recursive:
type: boolean
description: Whether or not to analyze imports recursively.
default: false
verbose:
type: boolean
description: Whether to enable verbose logging for debugging purposes.
default: false
format:
type: string
enum:
- json
- mermaid
- tree
- dot
default: json
description: Output representation. 'json' (default) returns the structured
analysis object. 'mermaid' returns a flowchart diagram string. 'tree'
returns an ASCII dependency tree string. 'dot' returns a Graphviz DOT
string with directory clustering (scales to large codebases; render with
`dot -Tsvg` or `sfdp -Tsvg`).
output:
type: string
description: Optional file path to write the result to (relative paths resolve
against the current working directory). 'json' is written as
pretty-printed JSON; other formats are written as-is. When set, the
function writes the file and returns a short confirmation string instead
of the payload. Omit to return the result to the caller / stdout as
before.
required:
- file
Output Schema
$schema: https://json-schema.org/draft/2020-12/schema
description: Analysis result when input 'format' is 'json' (the default). When
'format' is 'mermaid', 'tree', or 'dot', the output is instead a presentation
string rendered from this same data.
type: object
properties:
all:
type: array
description: List containing information on all modules detected in the file and
its dependencies.
items:
$ref: "#/$defs/moduleInfo"
unreferenced:
type: array
description: List of modules that are imported but never used in the code.
items:
$ref: "#/$defs/moduleInfo"
unnecessary:
type: array
description: List of modules that are neither used nor necessary according to
the dependency graph.
items:
$ref: "#/$defs/moduleInfo"
required:
type: array
description: List of modules that are used according to the dependency graph.
items:
$ref: "#/$defs/moduleInfo"
required:
- all
- unreferenced
- unnecessary
- required
$defs:
moduleInfo:
type: object
properties:
type:
type: string
enum:
- local
- node
- npm
description: Type of the module, indicating whether it's a local, node built-in,
or npm package.
path:
type: string
description: File path for the local module or the module name for node and npm
types.
importedBy:
type: array
description: Details of files that import this module.
items:
type: object
properties:
path:
type: string
description: Relative path of the file that imports this module.
used:
type: boolean
description: Indicates whether the module is utilized in the importing file.
required:
- path
- used
usesJSX:
type: boolean
description: Flag to indicate if the module file uses JSX syntax.
usedByRequireOrDynamicImport:
type: boolean
description: Flag to indicate if the module is used by require() or dynamic
import().
required:
- type
- path
- importedBy
- usesJSX
- usedByRequireOrDynamicImport
