eslint-template-visitor
raw JSON → 2.3.2 verified Sat Apr 25 auth: no javascript
Simplify ESLint rule creation by visiting AST node templates instead of manually inspecting ESTree nodes. v2.3.2 supports ESLint >=7 and uses @babel/eslint-parser behind the scenes for template parsing. It offers a declarative API with template literals, variables, spread variables, and variable declaration variables. Maintained by futpib, with regular releases and active development. Differentiates from other template-based tools by integrating directly with ESLint's visitor pattern.
Common errors
error TypeError: templates.template is not a function ↓
cause Calling template on the default export directly without calling eslintTemplateVisitor first.
fix
Call eslintTemplateVisitor() to get the templates object, then use templates.template.
error Error: Template must have exactly one top-level node ↓
cause Template string contains multiple top-level statements or expressions.
fix
Wrap the template in a block or ensure only one top-level node.
error Cannot find module '@babel/eslint-parser' ↓
cause @babel/eslint-parser is required as a dependency since v2.3.0 but not installed.
fix
Install @babel/eslint-parser: npm install --save-dev @babel/eslint-parser
error TypeError: context.getMatch is not a function ↓
cause Accessing getMatch incorrectly (e.g., on context instead of template context).
fix
Use substrCallTemplate.context.getMatch(objVar) not context.getMatch.
error ReferenceError: eslintTemplateVisitor is not defined ↓
cause Forgetting to import/require the module.
fix
Add const eslintTemplateVisitor = require('eslint-template-visitor'); or import statement.
Warnings
breaking Upgraded parser from babel-eslint to @babel/eslint-parser in v2.3.0. Existing templates that relied on babel-eslint-specific behavior may break. ↓
fix Update parser options if needed, ensure @babel/eslint-parser is installed as a direct dependency.
deprecated The old babel-eslint parser is deprecated; v2.3.0 switched to @babel/eslint-parser. ↓
fix Upgrade to v2.3.0 or later to avoid deprecated babel-eslint.
gotcha Template cannot have more than one top-level node. Throws an error in v2.1.0+. ↓
fix Ensure template string contains exactly one top-level AST node.
gotcha Variable declaration variable (variableDeclarationVariable) must be used in place of the declaration keyword (const/let/var), not the entire declaration node. ↓
fix Use ${variableDeclarationVariable} x = y; instead of ${variableDeclarationVariable} x = y; with wrong placement.
gotcha Spread variable matches an array of nodes, not a single node. Mistaking it for a regular variable leads to incorrect type errors. ↓
fix Use templates.variable() for a single node match, templates.spreadVariable() for an array.
breaking Removal of support for ESLint <7.0.0. Peer dependency requires eslint >=7. ↓
fix Upgrade ESLint to version 7 or later.
Install
npm install eslint-template-visitor yarn add eslint-template-visitor pnpm add eslint-template-visitor Imports
- default wrong
const { eslintTemplateVisitor } = require('eslint-template-visitor');correctimport eslintTemplateVisitor from 'eslint-template-visitor'; - default (require) wrong
const { template } = require('eslint-template-visitor');correctconst eslintTemplateVisitor = require('eslint-template-visitor'); - template (after calling factory) wrong
const { template } = eslintTemplateVisitor();correctconst templates = eslintTemplateVisitor(); const { template } = templates;
Quickstart
const eslintTemplateVisitor = require('eslint-template-visitor');
const templates = eslintTemplateVisitor();
const objVar = templates.variable();
const argVar = templates.spreadVariable();
const substrCallTemplate = templates.template`${objVar}.substr(${argVar})`;
module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'Prefer String#slice() over String#substr()',
},
fixable: 'code',
},
create(context) {
return templates.visitor({
[substrCallTemplate](node) {
const objectNode = substrCallTemplate.context.getMatch(objVar);
const argumentNodes = substrCallTemplate.context.getMatch(argVar);
const problem = {
node,
message: 'Prefer `String#slice()` over `String#substr()`.',
};
if (argumentNodes.length === 0) {
problem.fix = fixer => fixer.replaceText(node, context.getSourceCode().getText(objectNode) + '.slice()');
}
context.report(problem);
},
});
},
};