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

rick-tracy

v0.0.7

Published

A pluggable dependency graph array generator. Detective Rick Tracy always catches mad modules!

Downloads

8

Readme

Rick Tracy Travis npm package

Detective Rick Tracy is a pluggable dependency graph array generator written in js.

This tool was designed to generated a very simple tree structure which I could use in a gulp workflow to look up the entry point js files from any level of dependency. How this differs from similar tools is that this is designed for projects that are mixed with ES6 imports and Common JS requires, it returns a usable final tree object, and it offers a lot of options for filtering and processing how modules are discovered.

Features

  • Works with ES6 import and Common JS require mixed in the same source files.
  • Has similar options to module-deps for filtering, mapping, and post-resolution filtering ids.
  • Uses a [labeled stream splicer](labeled stream splicer) to allow total manipulation of the stream pipeline.

Installation

To install from NPM:

sudo npm install rick-tracy

Manually via git:

git clone https://github.com/jayzawrotny/rick-tracy.git

In node (ES5):

var RickTracy = require('rick-tracy');

In node (ES6):

import RickTracy from 'rick-tracy';

Usage

import fs from 'fs';
import JSONStream from 'JSONStream';
import RickTracy from 'rick-tracy';

let rickTracy = new RickTracy({
 // the usual suspects ;)
 lineup: 'path/to/entry/points/**/*.js'
});

// Build the dependency graph and write to a writable stream
rickTracy.investigate()
  .then((caseFile) => {
    console.log(caseFile);
  })

// Or get the tree from the complete handler
rickTracy.investigate()
 .on('complete', (caseFile) => {
   console.log(caseFile);
 });

// Or create your own stream pipeline
rickTracy.read()
  .pipe(rickTracy.pipeline)
  // Could also be replaced with any writable stream
  .pipe(rickTracy.report((caseFile) => {
    console.log(caseFile);
  });

// Customizing the pipeline

rickTracy.pipeline.get('trace').unshift(through2.obj((file, enc, done) => {
  // Allows you to modify the vinyl entry point files before tracing begins.
  console.log(file);

  // Normal through stream stuff
  done(null, file);
}));

// Writes the dependency tree to a text file as part of the pipeline
let output = new fs.createWriteStream('tree.txt');

// Is appended to the pipeline after storing into the tree structure
rickTracy.pipline.get('store').push(output);

Options

lineup (string | array)

'**/*.js' ['**/*.js', '!**/_*.js']

A glob string to find entry points relative to process.cwd(). Used by vinyl-fs to send vinyl entry point files to the pipeline for tracing.

new RickTracy({
  lineup: '**/*.js',
});

filter (function:boolean)

function (id)

A filter function to run against new module paths as they are discovered and before RickTracy uses nodeResolve to find its absolute path. The function must return a boolean.

new RickTracy({
  trace: {
    filter: function (id) {
      return !id.includes('craiginald'); // Nobody wants anything to do with Craiginald.
    }
  }
})

The above example filters out any ids with the word 'craginald' in them.

postFilter (function:boolean)

function (id)

Another filter function to run against a resolved node module which may include an absolute path.

new RickTracy({
  trace: {
    postFilter: function (id) {
      return !id.includes('node_modules'); // Ignore any modules in the node_modules directory.
    }
  }
});

map (function:string)

function (id) { return id }

The map function allows you to modify module ids after they have been filtered, but before they get resolved to an actual location.

new RickTracy({
  trace: {
    map: function (id) {
      return path.join(__dirname, id);
    }
  }
})

The above example prepends the dirname to the module id if you had something like require('myfile') it would be mapped to /path/to/myfile;

compileES6Modules (boolean:true)

Specify if you want to compile the ES6 import statements to commonJS require statements.

new RickTracy({
  trace: {
    compileES6Modules: false, // Will speed up trace process if no ES6 imports are used.
  }
})

ignorePackages (boolean:true)

Specify if you want Rick Tracy to ignore npm packages in the dependency graph. The default is true. The intended use case is to generate a graph for the app source and not the modules.

new RickTracy({
  trace: {
    ignorePackages: false, // Will include node_module packages too
  }
})

Customization

Pipeline

The pipeline is a [labeled stream splicer](labeled stream splicer) generated with each new RickTracy instance. Each pipe in the pipeline is a type of stream consumer either a duplex stream or a transform stream. The stream splicer allows the post creation manipulation of each step in the flow. For instance, you can add a transform stream before any input is sent to the tracer to filter or generate more files to trace. After tracing you could then add another step to affect what is sent to the store. Then after the store you could add another transform stream to affect what is output at the end. The main idea here is that any step can be replaced, removed, prepended or appended to at your discretion.

Below is an example for adding a basic logging step.

import RickTracy from 'rick-tracy';

let rickTracy = new RickTracy({
  lineup: 'path/to/entry/points/**/*.js'
});

rickTracy.pipeline.get('trace').unshift(through.obj((file, enc, done) => {
  console.log("I'm the vinyl file before getting traced.", file.path);
  done(null, file);
}))

rickTracy.investigate()
  .then((caseFile) => {
    // Whatever you need the tree for.
  });

Trace

rickTracy.pipeline.get('trace')

Traces the input vinyl files through all their children and their children's dependencies. Emits each dependency that it finds.

Input: Vinyl file object

Output:

// Will be generated for each module it discovers and resolves
{
  suspect: '/entry/point/file.js',
  leads: [
    '/sub/dependency/of/entry/point.js',
    '/sub/depdendency/of/entry/point.js',
  ],
  source: null, // Used for sub dependencies of dependencies.
}

Store

rickTracy.pipeline.get('store')

Stores the module dependency in a flat array that it can then traverse later to build the final dependency tree.

Input:

{
  suspect: '/entry/point/file.js',
  leads: [
    '/sub/dependency/of/entry/point.js',
    '/sub/depdendency/of/entry/point.js',
  ],
  source: null, // Used for sub dependencies of dependencies.
}

Output:

// Final dependency graph tree
{
  '/entry/point/file.js': {
    '/sub/dep.js': {
      '/sub/sub/dep.js': {},
    },
    '/sub/dep2.js': {}
  }
}

CLI

Currently I have not added any CLI functionality. If you would like me to implement it please let me know. If you really want CLI you can create a pull request :smile:.

About

Credits

This tool was lovingly made for use at VenueBook.

License

BSD-3-Clause (c) 2016 VenueBook, Inc.