104 lines
2.7 KiB
Markdown
104 lines
2.7 KiB
Markdown
|
# Detective-AMD [![npm](http://img.shields.io/npm/v/detective-amd.svg)](https://npmjs.org/package/detective-amd) [![npm](http://img.shields.io/npm/dm/detective-amd.svg)](https://npmjs.org/package/detective-amd)
|
||
|
|
||
|
Returns a list of dependencies for a given JavaScript file or AST using any of the AMD module syntaxes.
|
||
|
|
||
|
*Inspired by substack/node-detective but built for AMD.*
|
||
|
|
||
|
`npm install --save detective-amd`
|
||
|
|
||
|
* Supports JSX code via [node-source-walk](https://github.com/mrjoelkemp/node-source-walk).
|
||
|
|
||
|
### Usage
|
||
|
|
||
|
Let's say we have the following file definitions:
|
||
|
|
||
|
```javascript
|
||
|
|
||
|
// a.js
|
||
|
define(['./b', './c'], function (b, c) {
|
||
|
console.log(b, c);
|
||
|
});
|
||
|
|
||
|
// b.js
|
||
|
define({
|
||
|
name: 'foo'
|
||
|
});
|
||
|
|
||
|
// c.js
|
||
|
define(function () {
|
||
|
return 'bar';
|
||
|
});
|
||
|
|
||
|
```
|
||
|
|
||
|
Here's how you can grab the list of dependencies of `a.js` **synchronously**.
|
||
|
|
||
|
```javascript
|
||
|
var detective = require('detective-amd');
|
||
|
|
||
|
var srca = fs.readFileSync('a.js', 'utf8');
|
||
|
|
||
|
// Pass in the source code or an AST (if you've already parsed the file)
|
||
|
console.log(detective(srca)); // prints ['./b', './c']
|
||
|
|
||
|
```
|
||
|
|
||
|
You may also (optionally) configure the detective via a second object argument `detective(src, options)` that supports the following options:
|
||
|
|
||
|
* `skipLazyLoaded`: (Boolean) whether or not to omit inner requires in the list of extracted dependencies.
|
||
|
- Note: this does not affect the REM form since those inner requires are not "lazily" fetched.
|
||
|
|
||
|
### Syntax Support
|
||
|
|
||
|
**Supports the 4 forms of AMD module syntax:**
|
||
|
|
||
|
* "named": `define('name', [deps], func)`
|
||
|
* "dependency list": `define([deps], func)`
|
||
|
* "factory": `define(func(require))`
|
||
|
* "no dependencies": `define({})`
|
||
|
|
||
|
**Extra forms:**
|
||
|
|
||
|
* "driver script" (or entry-point) syntax: `require([deps], func)`
|
||
|
* "REM" (or CommonJS-like) form: `define(function(require, exports, module) {})`.
|
||
|
|
||
|
Also handles dynamically loaded dependencies (ex: inner requires).
|
||
|
|
||
|
**Supports driver scripts**
|
||
|
|
||
|
You can also find the dependencies from a script that has a top-level require (an app initialization/driver/entry-point script):
|
||
|
|
||
|
```javascript
|
||
|
require([
|
||
|
'./a'
|
||
|
], function (a) {
|
||
|
// My app will get booted up from here
|
||
|
});
|
||
|
```
|
||
|
|
||
|
**Expression-based requires**
|
||
|
|
||
|
If there's a require call that doesn't have a string literal but an expression,
|
||
|
a string (escodegen-generated) representation will be returned.
|
||
|
|
||
|
For example, if `a.js` was of the "factory" form and contained a dynamic module name:
|
||
|
|
||
|
```javascript
|
||
|
// a.js
|
||
|
|
||
|
define(function (require) {
|
||
|
// Assume str is some variable that gets set to a string dynamically
|
||
|
// var str = ...
|
||
|
|
||
|
var b = require('./' + str),
|
||
|
c = require('./c');
|
||
|
|
||
|
console.log(b, c);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The dependency list will be: `[ '\'./\' + str', './c' ]`
|
||
|
|
||
|
* Even though that string representation isn't incredibly useful, it's
|
||
|
still added to the list to represent/count that dependency
|