You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
2.8 KiB
Markdown
114 lines
2.8 KiB
Markdown
7 years ago
|
# falafel
|
||
|
|
||
|
Transform the [ast](http://en.wikipedia.org/wiki/Abstract_syntax_tree) on a
|
||
|
recursive walk.
|
||
|
|
||
|
[![browser support](http://ci.testling.com/substack/node-falafel.png)](http://ci.testling.com/substack/node-falafel)
|
||
|
|
||
|
[![build status](https://secure.travis-ci.org/substack/node-falafel.png)](http://travis-ci.org/substack/node-falafel)
|
||
|
|
||
|
This module is like [burrito](https://github.com/substack/node-burrito),
|
||
|
except that it uses [esprima](http://esprima.org) instead of
|
||
|
[uglify](https://github.com/mishoo/UglifyJS)
|
||
|
for friendlier-looking ast nodes.
|
||
|
|
||
|
# example
|
||
|
|
||
|
## array.js
|
||
|
|
||
|
Put a function wrapper around all array literals.
|
||
|
|
||
|
``` js
|
||
|
var falafel = require('falafel');
|
||
|
|
||
|
var src = '(' + function () {
|
||
|
var xs = [ 1, 2, [ 3, 4 ] ];
|
||
|
var ys = [ 5, 6 ];
|
||
|
console.dir([ xs, ys ]);
|
||
|
} + ')()';
|
||
|
|
||
|
var output = falafel(src, function (node) {
|
||
|
if (node.type === 'ArrayExpression') {
|
||
|
node.update('fn(' + node.source() + ')');
|
||
|
}
|
||
|
});
|
||
|
console.log(output);
|
||
|
```
|
||
|
|
||
|
output:
|
||
|
|
||
|
```
|
||
|
(function () {
|
||
|
var xs = fn([ 1, 2, fn([ 3, 4 ]) ]);
|
||
|
var ys = fn([ 5, 6 ]);
|
||
|
console.dir(fn([ xs, ys ]));
|
||
|
})()
|
||
|
```
|
||
|
|
||
|
# methods
|
||
|
|
||
|
``` js
|
||
|
var falafel = require('falafel')
|
||
|
```
|
||
|
|
||
|
## falafel(src, opts={}, fn)
|
||
|
|
||
|
Transform the string source `src` with the function `fn`, returning a
|
||
|
string-like transformed output object.
|
||
|
|
||
|
For every node in the ast, `fn(node)` fires. The recursive walk is a
|
||
|
pre-traversal, so children get called before their parents.
|
||
|
|
||
|
Performing a pre-traversal makes it easier to write nested transforms since
|
||
|
transforming parents often requires transforming all its children first.
|
||
|
|
||
|
The return value is string-like (it defines `.toString()` and `.inspect()`) so
|
||
|
that you can call `node.update()` asynchronously after the function has
|
||
|
returned and still capture the output.
|
||
|
|
||
|
Instead of passing a `src` you can also use `opts.source`.
|
||
|
|
||
|
All of the `opts` will be passed directly to esprima except for `'range'` which
|
||
|
is always turned on because falafel needs it.
|
||
|
|
||
|
Some of the options you might want from esprima includes:
|
||
|
`'loc'`, `'raw'`, `'comments'`, `'tokens'`, and `'tolerant'`.
|
||
|
|
||
|
# nodes
|
||
|
|
||
|
Aside from the regular [esprima](http://esprima.org) data, you can also call
|
||
|
some inserted methods on nodes.
|
||
|
|
||
|
Aside from updating the current node, you can also reach into sub-nodes to call
|
||
|
update functions on children from parent nodes.
|
||
|
|
||
|
## node.source()
|
||
|
|
||
|
Return the source for the given node, including any modifications made to
|
||
|
children nodes.
|
||
|
|
||
|
## node.update(s)
|
||
|
|
||
|
Transform the source for the present node to the string `s`.
|
||
|
|
||
|
Note that in `'ForStatement'` node types, there is an existing subnode called
|
||
|
`update`. For those nodes all the properties are copied over onto the
|
||
|
`node.update()` function.
|
||
|
|
||
|
## node.parent
|
||
|
|
||
|
Reference to the parent element or `null` at the root element.
|
||
|
|
||
|
# install
|
||
|
|
||
|
With [npm](http://npmjs.org) do:
|
||
|
|
||
|
```
|
||
|
npm install falafel
|
||
|
```
|
||
|
|
||
|
# license
|
||
|
|
||
|
MIT
|
||
|
|