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

Overview

cyclops

cyclops is a minimalist developer tool that can be used to generate directed graphs from your Node.js project. It can automatically 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.

Note

Unlike madge, cyclops is not meant to represent all the file tree structure but was designed to only include dependencies that are currently being used in the project based on the entrypoint.

  • Works for JavaScript (ES6 and CommonJS modules)
  • Deeply detects circular dependencies in an efficient way
  • Deeply collect all dependencies on which a graph node depends on
  • Parent and child dependencies traversals

Examples

import cyclops from "cyclops";

const { graph, files, circularDependencies } = await cyclops({
  entrypoint: "index.js"
});
Comments
  • Add support for `npx skott`

    Add support for `npx skott`

    The CLI doesn't seem to work when run via npx:

    Screen Shot 3

    If it's available globally, then npx will also work, so make sure you uninstall the global version before attempting this.

    bug road-to-v1 
    opened by fregante 8
  • FeatureRequest | Typescript support

    FeatureRequest | Typescript support

    Feature Request

    Will skott support typescript projects?

    Our use case is an Nx monorepo with Nextjs as the main app with several react libraries. Thanks for this interesting library!

    enhancement 
    opened by ild0tt0re 6
  • Skott own modules are not installed

    Skott own modules are not installed

    Hi, Thanks for your work. I've installed your package globally but I get an error

    Error

    ➜  sgo ✗ skott src/App.tsx
    
     Running Skott from entrypoint: src/App.tsx
     Processed 1 file (2.285ms)
     ✓ no circular dependencies found (depth=Infinity)
     Third-party dependencies: ❌
     --> Use --trackThirdPartyDependencies to enable tracking.
     Built-in dependencies: ❌
     --> Use --trackBuiltinDependencies to enable tracking.
     Type-level only dependencies: ✅
    
     Skott exited with code 1
    node:fs:1438
      handleErrorFromBinding(ctx);
      ^
    
    Error: ENOENT: no such file or directory, scandir '/Users/aze/.config/yarn/global/node_modules/skott/node_modules/skott-webapp/dist'
        at readdirSync (node:fs:1438:3)
        at totalist (/Users/aze/.config/yarn/global/node_modules/totalist/sync/index.js:6:12)
        at module.exports (/Users/aze/.config/yarn/global/node_modules/sirv/build.js:149:3)
        at openWebApplication (file:///Users/aze/.config/yarn/global/node_modules/skott/dist/bin/ui/webapp.js:45:20)
        at displaySkott (file:///Users/aez/.config/yarn/global/node_modules/skott/dist/bin/main.js:134:9) {
      errno: -2,
      syscall: 'scandir',
      code: 'ENOENT',
      path: '/Users/aze/.config/yarn/global/node_modules/skott/node_modules/skott-webapp/dist'
    }
    

    I checked here /Users/aze/.config/yarn/global/node_modules/skott and found out that packages are not installed. Tried to install them myself using yarn installbut I end up on a maybe encrypted variable @skott%2fconfig

    Yarn-error.log

    Arguments: 
      /Users/aze/.nvm/versions/node/v16.19.0/bin/node /opt/homebrew/Cellar/yarn/1.22.19/libexec/bin/yarn.js install
    
    PATH: 
      /Users/aze/.nvm/versions/node/v16.19.0/bin:/Users/aze/.rbenv/shims:/Users/aze/Library/Caches/fnm_multishells/1122_1671351776860/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Applications/Visual Studio Code.app/Contents/Resources/app/bin:/Users/aze/Library/Android/sdk/emulator:/Users/aze/Library/Android/sdk/platform-tools:/Users/aze/Library/Android/sdk/tools:/Users/aze/Library/Android/sdk/tools/bin
    
    Yarn version: 
      1.22.19
    
    Node version: 
      16.19.0
    
    Platform: 
      darwin arm64
    
    Trace: 
      Error: https://registry.yarnpkg.com/@skott%2fconfig: Not found
          at Request.params.callback [as _callback] (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:66145:18)
          at Request.self.callback (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:140890:22)
          at Request.emit (node:events:513:28)
          at Request.<anonymous> (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:141862:10)
          at Request.emit (node:events:513:28)
          at IncomingMessage.<anonymous> (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:141784:12)
          at Object.onceWrapper (node:events:627:28)
          at IncomingMessage.emit (node:events:525:35)
          at endReadableNT (node:internal/streams/readable:1358:12)
          at processTicksAndRejections (node:internal/process/task_queues:83:21)
    
    npm manifest: 
      {
        "name": "skott",
        "version": "0.12.1",
        "description": "Automatically construct and visualize Graphs generated from your JavaScript and TypeScript project",
        "author": "Antoine Coulon",
        "license": "MIT",
        "repository": {
          "type": "git",
          "url": "git+https://github.com/antoine-coulon/skott.git"
        },
        "bugs": {
          "url": "https://github.com/antoine-coulon/skott/issues"
        },
        "main": "dist/index.js",
        "bin": {
          "skott": "./dist/bin/cli.js"
        },
        "type": "module",
        "exports": {
          ".": "./dist/index.js"
        },
        "types": "./dist/index.d.ts",
        "dependencies": {
          "@typescript-eslint/typescript-estree": "^5.40.0",
          "compression": "^1.7.4",
          "digraph-js": "^2.0.2",
          "estree-walker": "^3.0.1",
          "fs-tree-structure": "0.0.1",
          "kleur": "^4.1.5",
          "ligie": "^0.0.6",
          "meriyah": "^4.2.1",
          "openurl": "^1.1.1",
          "ora": "^6.1.2",
          "polka": "^0.5.2",
          "sade": "^1.8.1",
          "sirv": "^2.0.2",
          "skott-webapp": "0.0.3",
          "table": "^6.8.0"
        },
        "devDependencies": {
          "@nodesecure/eslint-config": "^1.3.0",
          "@skott/config": "0.0.1",
          "@types/chai": "^4.3.0",
          "@types/compression": "^1.7.2",
          "@types/mocha": "^9.0.0",
          "@types/node": "^16.11.12",
          "@types/polka": "^0.5.4",
          "@types/sade": "^1.7.4",
          "chai": "^4.3.4",
          "eslint": "^8.4.1",
          "eslint-config-prettier": "^8.3.0",
          "eslint-import-resolver-typescript": "^2.5.0",
          "eslint-plugin-import": "^2.26.0",
          "eslint-plugin-prettier": "^4.0.0",
          "memfs": "^3.4.6",
          "mocha": "^9.1.4",
          "prettier": "^2.5.1",
          "rimraf": "^3.0.2",
          "ts-node": "^10.8.1",
          "typescript": "^4.5.2"
        },
        "files": [
          "dist",
          "./README.md"
        ],
        "keywords": [
          "javascript",
          "graph",
          "nodejs",
          "visualization",
          "module",
          "dependencies"
        ],
        "scripts": {
          "build": "rimraf ./dist && tsc --project tsconfig.build.json",
          "lint": "eslint .",
          "prestart": "pnpm run build",
          "start": "node dist/bin/cli.js",
          "test": "mocha --parallel"
        }
      }
    
    yarn manifest: 
      No manifest
    
    Lockfile: 
      No lockfile
    

    Any idea how to solve this ?

    opened by bam-charlesbo 5
  • It doesn't seem to correctly find aliases in tsconfig

    It doesn't seem to correctly find aliases in tsconfig

    You can see my config at https://github.com/pixiebrix/pixiebrix-extension/blob/ae55fca9e0c610c801f05107f2cde021db09ef0f/tsconfig.json#L19-L26

    I'm using a similar config in Madge and I think that one works: https://github.com/pixiebrix/pixiebrix-extension/blob/ae55fca9e0c610c801f05107f2cde021db09ef0f/package.json#L22

     npx skott src/pageScript/pageScript.ts --trackBuiltinDependencies --trackThirdPartyDependencies --displayMode=file-tree
    
     Running Skott from entrypoint: src/pageScript/pageScript.ts
    
     Processed 1 file (13.471ms)
    
     ✓ no circular dependencies found (depth=Infinity)
    
      pageScript.ts
    
     npm third-party dependencies: 
    
      @/contentScript (imports=1)
      @/frameworks (imports=1)
      @/messaging (imports=1)
      @/pageScript (imports=1)
      @/runtime (imports=1)
      @/types (imports=1)
      @/utils (imports=1)
      @/vendors (imports=1)
      lodash (imports=1)
    
     ✓ no builtin dependencies found
    
     Skott exited with code 0
    
    bug 
    opened by fregante 3
  • Allow Skott to perform a global analysis without specifying an entrypoint

    Allow Skott to perform a global analysis without specifying an entrypoint

    Following #2 #4 which were both resolved in #3, the only missing piece to use Skott in most cases is the ability to perform a global analysis without specifying any entrypoint.

    The reason for that is that some projects such as Next.js use file-system based routing which implicitly create links between files (without using any import/export statement, thing that Skott relies on to create the graph).

    Consequently the goal is to be able to deeply collect a specific set of independent files (basically .ts, .js, .tsx, .jsx) which are not linked by any import/export statement. This would allow Skott to produce sub graphs and unify them as a single project graph.

    In the context of monorepo/workspaces, this could also be useful. Given two independent libs that are evolving independently (without any dependency toward each other):

    |__lib-a/ 
               a.js
               root-a.js
    |__lib-b/
               b.js
               root-b.js
    

    The resulting graph could be:

    
    graph TB;
    
    a.js --> root-a.js
    b.js --> root-b.js
    
    
    enhancement 
    opened by antoine-coulon 1
  • Exported namespaces from third-party dependencies are reported as a specific dependency instead of being part of the same one

    Exported namespaces from third-party dependencies are reported as a specific dependency instead of being part of the same one

    skott can track third-party dependencies using the --trackThirdPartyDependencies option, and I currently noticed a problem where npm dependencies were reported more than once where accessing namespaces from them:

    @effect-ts/core/Effect and @effect-ts/core/Effect/Layer should be part of the same dependency which is indeed @effect-ts/core. Currently, both are reported as distinct dependencies.

    opened by antoine-coulon 0
  • feat: Support TypeScript

    feat: Support TypeScript

    This PR will enable the support of TypeScript, linked to #2

    This feature notably requires skott to:

    • [X] Be able to parse TypeScript or JavaScript files depending on the provided entrypoint (dynamic loading only)
    • [X] Resolve TypeScript index files through the path of the parent directory => import "./lib" should eventually resolve to import "./lib/index.ts"
    • [x] Handle imports specific to TypeScript =>import type { Foo } from "./foo" should create a link even if it's not an ESTree module declaration
    • [x] Handle TypeScript + ECMAScript modules => import "./foo/bar.js" should resolve anyway to import "./foo/bar.ts
    • [x] Handle path aliases => @my-lib/util should not be considered as a third-party dependency if there is a path alias connected in the nearest tsconfig.json
    opened by antoine-coulon 0
  • Skott webapp - Allow cycles to be fetched in a non-blocking way

    Skott webapp - Allow cycles to be fetched in a non-blocking way

    Currently, once the webapp opens up (when using --displayMode=webapp) all the data generated by the analysis is pre-fetched,including cyclic dependencies, which can be expensive hence blocking the graph from being displayed while computing the cycles.

    Given that we don't render the cycles on the first paint, it would be useful to compute and fetch the circular dependencies only once we decide to display them (and not while rendering for the first time).

    It could be provided via a new endpoint /cycles triggered once the display of this data is requested from the UI.

    enhancement road-to-v1 
    opened by antoine-coulon 0
  • Make incremental comparison consistent for all types of project structure

    Make incremental comparison consistent for all types of project structure

    Since v0.12.1, incremental mode was enabled by default. It turns out that this works well for JavaScript/TypeScript standard configurations but lacks off consistency when being used with more advanced configurations (specifically TypeScript deep path aliases #20).

    From now on with #21 until a fix (will be resolved with this issue), incremental will be disabled by default (can still be used with the flag incremental: true).

    This feature will eventually be enabled by default once we find it stable enough given all feedbacks across all types of projects.

    enhancement information road-to-v1 
    opened by antoine-coulon 0
  • UX - Webapp display - search is difficult

    UX - Webapp display - search is difficult

    I really like your tool,

    Therefore I am making suggestions to see it evolve.

    Once the graph is displayed, like this : Capture d’écran 2022-12-19 à 18 02 15

    It would be great to add these features :

    • underline the specified file as parameter
      • with command for example skott src/pages/PaymentPage/PaymentPage.component.tsx, I would like to see the item PaymentPage.component.tsx highlighted
    • allow browser text search (cmd + F)
      • OR create your own search and highlight searched item

    By the way I would be pleased to help you on this.

    Let me know if you find my suggestions useful,

    You can contact me on : [email protected]

    enhancement road-to-v1 
    opened by bam-charlesbo 1
  • View unused modules in a monorepo for dead code elimination

    View unused modules in a monorepo for dead code elimination

    I would like to see unused modules so that I can easily remove dead code from the codebase.

    Note: Since the module can be used in NOT production code like tests, storybook and other tooling files, there should be an option to skip them

    enhancement road-to-v1 
    opened by ild0tt0re 1
Releases(v0.12.3)
Owner
Antoine Coulon
Software Engineer, @NodeSecure core member. I occasionally write technical stuff about JavaScript & Node.js
Antoine Coulon
Contains html file showcasing Earthquake related data generated in the form of VR model, ArcGIS API with real-time earthquake feed and video of simulation of earthquake generated in blender

Module-EADGI-Project-All about Earthquakes Introduction Contains html file showcasing Earthquake related data generated in the form of VR model, ArcGI

Abhishek Rawat 2 Jun 9, 2022
This project provides a CDK construct creating AWS organizations.

AWS Organizations This project provides a CDK construct creating AWS organizations. Currently, there is no @aws-cdk/aws-organizations available. See t

Pepperize 107 Dec 29, 2022
This is the team project of construct week unit-3 (js201)

This is the team project of construct week unit-3 (js201) I. Project's Title => Clone of Mytheresa.com (E-commerce website) II. Project Description =>

Brajesh Lovanshi 5 Sep 28, 2022
An open-development real-time strategy (RTS) game project made in Construct.

Command & Construct This is an open-development real-time strategy (RTS) game project made in Construct. Read more about it and follow along the devel

Ashley (Scirra) 36 Dec 20, 2022
Automatically generated documentation for the Valorant API endpoints the client uses internally.

Valorant API Docs To read documentation and get started, see Docs This is a project designed to automatically document Valorant endpoints based on a J

Techdoodle 223 Dec 25, 2022
Build Schema.org graphs for JavaScript Runtimes (Browser, Node, etc). Improve your sites SEO with quick and easy Rich Results.

schema-org-graph-js The quickest and easiest way to build Schema.org graphs for JavaScript Runtimes (Browser, Node, etc). Status: ?? In Development Pl

Harlan Wilton 17 Dec 21, 2022
CDK construct to periodically take snapshots of RDS databases, sanitize them, and share with selected accounts.

CDK Construct for RDS Sanitized Snapshots Periodically take snapshots of RDS databases, sanitize them, and share with selected accounts. Use this to a

CloudSnorkel 6 Dec 7, 2022
View maps, graphs, and tables of your save and compete in a casual, evergreen leaderboard of EU4 achievement speed runs. Upload and share your save with the world.

PDX Tools PDX Tools is a modern EU4 save file analyzer that allow users to view maps, graphs, and data tables of their save all within the browser. If

PDX Tools 24 Dec 27, 2022
Construct ANSI colors strings from object descriptors.

ansi-construct Construct ANSI colors strings from object descriptors. Usage import { ansi } from 'ansi-construct' const item = ansi({ text: 'foo', co

Anthony Fu 22 Sep 8, 2022
JSON Visio is data visualization tool for your json data which seamlessly illustrates your data on graphs without having to restructure anything, paste directly or import file.

JSON Visio is data visualization tool for your json data which seamlessly illustrates your data on graphs without having to restructure anything, paste directly or import file.

Aykut Saraç 20.6k Jan 4, 2023
A lightweight SolidJS component for building interactive node-based diagrams and graphs.

Convert Your Ideas To Graphs With Solid Graph! Solid Graph A lightweight and minimal Solid component for building interactive graphs and node-based ed

Ali Sal 26 Dec 8, 2022
A lightweight SolidJS component for building interactive node-based diagrams and graphs.

Convert Your Ideas To A Simple And Excitig Journay With Odysea! Odysea A lightweight and minimal Solid component for building interactive graphs and n

Ali Sal 21 Aug 15, 2022
Easiest 1-click way to install and use Stable Diffusion on your own computer. Provides a browser UI for generating images from text prompts and images. Just enter your text prompt, and see the generated image.

Stable Diffusion UI Easiest way to install and use Stable Diffusion on your own computer. No dependencies or technical knowledge required. 1-click ins

null 3.5k Dec 30, 2022
Get dynamically generated your github contributor stats on your READMEs!

GitHub Readme Contributor Stats Get dynamically generated your github contributor stats on your READMEs! Features GitHub Contributor Stats Card Themes

Taehyun Hwang 20 Dec 11, 2022
100% type-safe query builder for node-postgres :: Generated types, call any function, tree-shakable, implicit type casts, and more

⚠️ This library is currently in alpha. Contributors wanted! tusken Postgres client from a galaxy far, far away. your database is the source-of-truth f

alloc 54 Dec 29, 2022
portfolio-project is a npm package to automatically update your projects section in your portfolio website. It will fetch the selected repositories directly from your GitHub account.

portfolio-project Those days of manually updating portfolio website after every new project made are gone ⚡ Yesss . . . you read that right. ?? portfo

Gaurav Gulati 15 Aug 3, 2021
Project generated via @wayfair-incubator oss-template

node-froid: NodeJS - Federated Relay Object Identification Table of Contents About The Project The problem The solution Getting Started Library API ha

Wayfair Tech – Incubator 11 Nov 22, 2022
A Kubernetes monitoring tool to visualize large-scale activity and real-time comprehensive metrics within your cluster.

Armada A light-weight Kubernetes health monitoring tool. Summary Armada is an open-source tool for monitoring the health of your Kubernetes cluster. I

OSLabs Beta 81 Nov 2, 2022
ClickCat is a firendly user interface that lets you search,explore and visualize your ClickHouse Data.

ClickCat is a firendly user interface that lets you search,explore and visualize your ClickHouse Data. We provides the following features,you can acce

海博科技 34 Dec 13, 2022