JSPM

  • Created
  • Published
  • Downloads 41711
  • Score
    100M100P100Q144116F
  • License MIT

Automatically construct and visualize Graphs generated from your Node.js project

Package Exports

  • skott

Readme

skott

skott is a minimalist developer tool that can be used to efficiently generate directed graphs from your JavaScript/Node.js project. It can automatically collect metadata, detect circular dependencies and can be used to implement affected/incremental patterns as it exposes a way to know precisely dependencies for each graph node.

Graph Construction skott is powered by digraph-js, a 0 dependency Node.js library to make Directed Graph construction and traversal effortless.

Note

skott goal is to represent all the file tree structure but was designed to only include dependencies currently being used in the project based on the entrypoint. Consequently unused files (files that are not imported/exported by any other file) won't be included in the graph structure.

✅ Works for JavaScript/Node.js projects (ECMAScript and CommonJS modules)

✅ Deeply detects circular dependencies in an efficient way, with the ability to provide a max depth for the search

✅ Deeply collect all dependencies of the project graph

✅ Deep parent and child dependencies traversals

✅ Node.js core, binary and JSON modules are excluded by default

✅ Third-party libraries are excluded by default

Work in progress includes:

🛠 Allow unused dependency to be flagged

🛠 Caching on graph operations to provide better traversal efficiency

🛠 Collect metadata on the graph (unused imports, unoptimized imports)

🛠 Collect metadata on each traversed node (file size, number of other nodes depending on it, etc)

🛠 Resolve workspaces/monorepos graphs

How to use skott

API

import skott from "skott";

const { getStructure, findCircularDependencies, findParentsOf } = await skott({
  /**
   * The entrypoint of the project. Must be either a CommonJS or ES6 module.
   * No TypeScript files are supported as entrypoints.
   */ 
  entrypoint: "dist/index.js",
  /**
   * Define the max depth of for circular dependencies search. This can be useful 
   * for performance purposes. This defaults to POSITIVE_INFINITY.
   */
  circularMaxDepth: 20,
  /**
   * This defines whether the base directory of the entrypoint must be included
   * in all the relatives file paths.
   * For the specified `dist/index.js` above, it would consider the root path
   * to be `./` consequently `dist/` would never appear in any file paths.
   */
  includeBaseDir: false
});

Command line interface

skott exposes a CLI directly using features from the core library.

When the library installed locally you can run:

$ ./node_modules/.bin/skott src/index.js

When the library installed globally:

$ skott src/index.js

Here are some examples of output generated by the CLI:

Example targetting Fastify using "graph" display mode:

Using "file-tree" display mode:

When circular dependencies are met:

See all the options of the CLI running:

$ skott --help

Examples

To initialize the dependency graph, the default exported function must be used first. Once executed, the default function returns a set of functions to retrieve some information about the graph just built.

import skott from "skott";

const { getStructure } = await skott({
  entrypoint: "index.js",
  // ...rest of the config
});

const { graph, files } = getStructure();
console.log(graph); // logs { "index.js": { id: "index.js", adjacentTo: [], body: {...} } };
console.log(files); // logs [ "index.js" ]

Search for circular dependencies

import skott from "skott";

const { findCircularDependencies, hasCircularDependencies } = await skott({
  entrypoint: "index.js",
  // ...rest of the config
});

// Imagine that starting from "index.js" skott detects a circular dependency
// between "core.js" and "utils.js" files

console.log(findCircularDependencies()); // logs [ [ "core.js", "utils.js" ] ]
console.log(hasCircularDependencies()); // logs "true"

Search for leaves (nodes with no children)

leaf.js

console.log("I'm a leaf because I have no dependency");

index.js

import skott from "skott";

const { findLeaves } = await skott({
  entrypoint: "leaf.js",
  // ...rest of the config
});

console.log(findLeaves()); // logs [ "leaf.js" ]

Deeply search for parent dependencies of a given node

children.js

export const childrenFunction = () => {};

parent.js

import { childrenFunction } from "./children.js";

childrenFunction();

index.js

import skott from "skott";

const { findParentsOf } = await skott({
  entrypoint: "parent.js",
  // ...rest of the config
});

console.log(findParentsOf("children.js")); // logs [ "parent.js" ]