deps-walker
Graph traversal to walk through ES6/ES2015 module dependency graph for further static analysis. The traversal algorithm is classified as Breadth-first search (BFS).
Install
$ npm install deps-walker
Usage
Here is an example of an entry point module entry.js
with its dependencies, which in turn depend on their dependencies, which in turn depend on...
import a from './a.js';
import b from './b.js';
import b from './b.js';
import c from './c.js';
import d from './d.js';
import d from './d.js';
import b from './b.js';
In other words:
entry.js -> a.js
entry.js -> b.js
a.js -> b.js
a.js -> c.js
a.js -> d.js
c.js -> d.js
d.js -> b.js
deps-walker
is used to traverse entry.js
dependency graph:
const walk = require('deps-walker')();
walk('entry.js', (err, data) => {
if (err) {
return;
}
const { filePath, dependencies } = data;
});
The dependencies are traversed in the following order:
Async/await API
deps-walker
support async/await API, it can be used to await traverse completion:
async function traverse() {
await walk('entry.js', (err, data) => {});
console.log('Traverse is completed');
}
Multiple entry points
deps-walker
supports multiple roots:
walk(['entry1.js', 'entry2.js', 'entry3.js'], (err, data) => {});
Parsers
deps-walker
uses babylon parser with sourceType: 'module'
option by default, but you can customize any of default options:
const babylonParse = require('deps-walker/lib/parsers/babylon');
const walk = require('deps-walker')({
parse: (...args) =>
babylonParse(...args, {
sourceType: 'module',
plugins: ['jsx', 'flow']
})
});
or specify your own parse
implementation:
const walk = require('deps-walker')({
parse: (code, filePath) => {
}
});
Resolvers
It is not always obvious where import x from 'module'
should look to find the file behind module, it depends on module resolution algorithms, which are specific for module bundlers, module syntax specs, etc.. deps-walker
uses resolve package, which implements NodeJS module resolution behavior. You may configure NodeJS resolve
via available options:
const nodejsResolve = require('deps-walker/lib/resolvers/nodejs');
const walk = require('deps-walker')({
resolve: (...args) =>
nodejsResolve(...args, {
extensions: [ '.js' ]
paths: ['rootDir'],
moduleDirectory: 'node_modules'
})
});
You can also use other module resolution algorithms:
const walk = require('deps-walker')({
resolve: (filePath, contextPath) => {
}
});
Ignore
You may break traversal for some dependencies by specifying ignore
function:
const walk = require('deps-walker')({
ignore: (filePath) => /node_modules/.test(filePath)
});
Cache
Module parsing and resolving can be resource intensive operation (CPU, I/O), cache allows you to speed up consecutive runs:
const cache = require('deps-walker/cache');
const walk = require('deps-walker')({ cache });
await cache.load('./cache.json');
await walk('entry.js', (err, data) => {});
await cache.save('./cache.json');
License
MIT