A utility that helps traverse code the way ESLint does. This allows you to test any utilities you write for ESLint rules.
npm install eslint-traverser
The module exposes a function that gets code and an optional config
object, and gets a traverser, with a get
function.
The get
function calls the callback for every node
of the type, with node
and context
parameters,
which are the same as the ones in ESLint itself.
const traverse = require('eslint-traverser')
traverse('var y = f(x)')
.get('CallExpression', (node, context) => {
console.log(node.callee.name) //logs `f`
sourceCode = context.getSourceCode()
//...
})
You can define a configuration to run your traversal (globals, settings, etc) in an additional parameter in the call to traverser
.
You may not use the rules
key in this configuration.
const traverse = require('eslint-traverser')
traverse('import foo from "bar"', {parserOptions: {sourceType: module}})
.get('Program:exit', (node, context) => {
console.log('Modules!')
})
As a shortcut, you can pass only the parserOptions object, and if your config only contains parserOptions keys, it will work normally.
const traverse = require('eslint-traverser')
traverse('import foo from "bar"', {sourceType: module})
.get('Program:exit', (node, context) => {
console.log('Modules!')
})
You can also filter results using a selector, which can be a function or any of the iteratees supplied by Lodash
const traverse = require('eslint-traverser')
traverse('f(); g(x)')
.get('CallExpression', node => node.arguments.length, (node, context) => {
console.log(node.callee.name) //logs `g`
//...
})
traverse('f(); g(x)')
.get('CallExpression', 'arguments.length', node => {
console.log(node.callee.name) //logs `g`
//...
})
traverse('f(); g(x)')
.get('CallExpression', ['arguments.length', 0], node => {
console.log(node.callee.name) //logs `f`
//...
})
traverse('f(); g(x)')
.get('CallExpression', {callee: {name: 'g'}}, node => {
console.log(node.callee.name) //logs `g`
//...
})
The first
method is the same as the get
method, except it only calls the callback on the first result, while get
calls it on all the results
const traverse = require('eslint-traverser')
traverse('f(); g()')
.get('CallExpression', node => {
console.log(node.callee.name)
})
// f
// g
traverse('f(); g()')
.first('CallExpression', node => {
console.log(node.callee.name)
})
// f
The visitAll
method gets two arguments: first, an optional visitors
object in the same structure as an ESLint rule visitor object.
The second is a callback, that gets called at the end of the code traversal with two arguments: the Program
node and the context.
const traverse = require('eslint-traverser')
traverse('var y = f(x)')
.visitAll((node, context) => {
console.log(node.type) //Program
})
traverse('var y = f(x)')
.visitAll({
CallExpression(node) { console.log('Call expression!')}
}, () => { console.log('finished!')})
// Call expression!
// finished!
The runRuleCode
method gets one argument: the rule. This runs an ESLint rule (a function that gets a context and returns a visitors object) on the specified code.
const traverse = require('eslint-traverser')
traverse('var y = f(x)')
.runRuleCode(context => ({
CallExpression(node) { console.log('Call expression!')}
}))
// Call expression!