README.md
# resolve-tree [![Build Status](https://api.travis-ci.org/h2non/resolve-tree.svg?branch=master&style=flat)](https://travis-ci.org/h2non/resolve-tree) [![Code Climate](https://codeclimate.com/github/h2non/resolve-tree/badges/gpa.svg)](https://codeclimate.com/github/h2non/resolve-tree) [![NPM](https://img.shields.io/npm/v/resolve-tree.svg)](https://www.npmjs.org/package/resolve-tree) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com)
Recursively resolve node.js modules and its dependencies looking in `node_modules` trees.
The module resolution algorithm behavies like [`require.resolve`](https://nodejs.org/docs/v0.4.8/api/all.html#all_Together...) in node.js.
It also mimics the recursive module resolution behavior used by `npm`.
## Features
- Recursively resolves a node_modules dependency tree
- Proper error reporting if some package cannot be resolved or is missing
- Detects repeated and circular dependencies across nested dependency trees.
- Module lookup algorithm behavies like [`require.resolve`](https://nodejs.org/docs/v0.4.8/api/all.html#all_Together...)
- Produces a detailed abstract dependency tree representation
- Provides convenient helpers that you will love
- Almost dependency free (only uses some stable tiny modules)
- Fast: all the I/O operations are executed asynchronously in parallel
## Not supported yet
- Semantic version operator based resolution
## Installation
```bash
npm install resolve-tree
```
## Usage
```js
const resolve = require('resolve-tree')
// Names of the packages to resolve
const names = ['foo', 'bar']
// Custom optional params for the resolution
const opts = {
basedir: process.cwd(),
lookups: ['dependencies', 'devDependencies']
}
resolve.packages(names, opts, function (err, tree) {
if (err) return console.error(err)
const json = JSON.stringify(tree, null, 2)
console.log(json)
})
```
The resolved dependency tree serialized to JSON looks like this:
```json
[{
"name": "foo",
"manifest": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/package.json",
"basedir": "/Users/h2non/Projects/resolve-tree/fixtures/simple",
"main": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/index.js",
"root": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo",
"version": "0.1.0",
"meta": {
"name": "foo",
"dependencies": {
"baz": "~0.1.0",
"bar": "~0.1.0",
"quz": "~0.1.0"
}
},
"dependencies": [{
"name": "baz",
"manifest": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/baz/package.json",
"basedir": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo",
"main": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/baz/index.js",
"root": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/baz",
"version": "0.1.0",
"meta": {
"name": "baz"
}
}, {
"name": "bar",
"manifest": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/bar/package.json",
"basedir": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo",
"main": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/bar/index.js",
"root": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/bar",
"version": "0.1.0",
"meta": {
"name": "bar",
"dependencies": {
"baz": "~0.1.0"
}
},
"dependencies": [{
"name": "baz",
"manifest": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/baz/package.json",
"basedir": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/bar",
"main": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/baz/index.js",
"root": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/baz",
"version": "0.1.0",
"meta": {
"name": "baz"
}
}]
}, {
"name": "quz",
"manifest": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/node_modules/quz/package.json",
"basedir": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo",
"main": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/node_modules/quz/index.js",
"root": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/node_modules/quz",
"version": "0.1.0",
"meta": {
"name": "quz",
"dependencies": {
"baz": "~0.0.1"
}
},
"dependencies": [{
"name": "baz",
"manifest": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/node_modules/quz/node_modules/baz/package.json",
"basedir": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/node_modules/quz",
"main": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/node_modules/quz/node_modules/baz/index.js",
"root": "/Users/h2non/Projects/resolve-tree/fixtures/simple/node_modules/foo/node_modules/quz/node_modules/baz",
"version": "0.1.0",
"meta": {
"name": "baz",
"version": "0.0.1"
}
}]
}]
}]
```
## API
### Supported options
- **basedir** `string` - Base directory path to start lookups. Default to `process.cwd()`.
- **lookups** `array<string>` - Dependency types to lookup. Allowed values are: `dependencies`, `devDependencies`, `peerDependencies`. Defaults to: `dependencies`
### resolve.packages(names, [ opts, ] cb)
Alias: `byName()`
Find and resolve modules and its dependencies recursively looking by package name.
### resolve.manifest(pkgManifest, [ opts, ] cb)
Resolve dependencies recursively reading the `package.json` metadata.
### resolve.flatten(tree) => `array<pkg>`
Flatten dependency tree to one level structure tree.
### resolve.flattenMap(tree, [ field ]) => `array<mixed>`
Flatten the given dependency tree mapping by dependency value field or custom mapper function.
### resolve.resolutions = `object`
Map of packages resolution mappings.
```js
{
'mz': 'mz/fs'
}
```
### resolve.packagesSync(names, [ opts ])
Alias: `byNameSync`
Synchronous version of `packages`.
Find and resolve modules and its dependencies recursively looking by package name.
### resolve.manifestSync(pkgManifest, [ opts ])
Synchronous version of `manifest`.
Resolve dependencies recursively reading the `package.json` metadata.
## License
MIT - Tomas Aparicio