Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: Custom rule & plugin tutorial (#17024)
* Start copy edits * checkpoint * docs update * docs update * Add intro * Copy edits * remove old draft of tutorial * Fix take ii * update tutorial * Apply suggestions from code review Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com> * update src code names * rename tutorial * update code examples to match updated code * additional fixes * implement additional NZ feedback * Apply suggestions from code review Co-authored-by: Nitin Kumar <snitin315@gmail.com> Co-authored-by: Samuel Roldan <sroldan24@gmail.com> Co-authored-by: moniuch <moniuch@gmail.com> * draft tutorial changes * copy edits * fix lint err * Apply suggestions from code review Co-authored-by: Nitin Kumar <snitin315@gmail.com> * add file overviews * copy edits on step 8 intro * Apply suggestions from code review Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com> * implement NZ feedback * Apply suggestions from code review Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com> * Apply suggestions from code review Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com> * Apply suggestions from code review * Apply suggestions from code review * Apply suggestions from code review * update rule name to "enforce-foo-bar" * Apply suggestions from code review * implement MD feedback * Apply suggestions from code review Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com> * implement MD feedback * copy edit * Apply suggestions from code review Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com> * move tutorial to _examples dir * undo big change * Fix broken example * Apply suggestions from code review Co-authored-by: Nitin Kumar <snitin315@gmail.com> --------- Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com> Co-authored-by: Nitin Kumar <snitin315@gmail.com> Co-authored-by: Samuel Roldan <sroldan24@gmail.com> Co-authored-by: moniuch <moniuch@gmail.com> Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
- Loading branch information
1 parent
8e51ea9
commit e0cf0d8
Showing
11 changed files
with
652 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
57 changes: 57 additions & 0 deletions
57
docs/_examples/custom-rule-tutorial-code/enforce-foo-bar.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/** | ||
* @fileoverview Rule to enforce that `const foo` is assigned "bar". | ||
* @author Ben Perlmutter | ||
*/ | ||
|
||
"use strict"; | ||
|
||
// The enforce-foo-bar rule definition | ||
module.exports = { | ||
meta: { | ||
type: "problem", | ||
docs: { | ||
description: "Enforce that a variable named `foo` can only be assigned a value of 'bar'." | ||
}, | ||
fixable: "code", | ||
schema: [] | ||
}, | ||
create(context) { | ||
return { | ||
|
||
// Performs action in the function on every variable declarator | ||
VariableDeclarator(node) { | ||
|
||
// Check if a `const` variable declaration | ||
if (node.parent.kind === "const") { | ||
|
||
// Check if variable name is `foo` | ||
if (node.id.type === "Identifier" && node.id.name === "foo") { | ||
|
||
// Check if value of variable is "bar" | ||
if (node.init && node.init.type === "Literal" && node.init.value !== "bar") { | ||
|
||
/* | ||
* Report error to ESLint. Error message uses | ||
* a message placeholder to include the incorrect value | ||
* in the error message. | ||
* Also includes a `fix(fixer)` function that replaces | ||
* any values assigned to `const foo` with "bar". | ||
*/ | ||
context.report({ | ||
node, | ||
message: 'Value other than "bar" assigned to `const foo`. Unexpected value: {{ notBar }}.', | ||
data: { | ||
notBar: node.init.value | ||
}, | ||
fix(fixer) { | ||
return fixer.replaceText(node.init, '"bar"'); | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
|
34 changes: 34 additions & 0 deletions
34
docs/_examples/custom-rule-tutorial-code/enforce-foo-bar.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* @fileoverview Tests for enforce-foo-bar.js rule. | ||
* @author Ben Perlmutter | ||
*/ | ||
"use strict"; | ||
|
||
const {RuleTester} = require("eslint"); | ||
const fooBarRule = require("./enforce-foo-bar"); | ||
|
||
const ruleTester = new RuleTester({ | ||
// Must use at least ecmaVersion 2015 because | ||
// that's when `const` variable were introduced. | ||
parserOptions: { ecmaVersion: 2015 } | ||
}); | ||
|
||
// Throws error if the tests in ruleTester.run() do not pass | ||
ruleTester.run( | ||
"enforce-foo-bar", // rule name | ||
fooBarRule, // rule code | ||
{ // checks | ||
// 'valid' checks cases that should pass | ||
valid: [{ | ||
code: "const foo = 'bar';", | ||
}], | ||
// 'invalid' checks cases that should not pass | ||
invalid: [{ | ||
code: "const foo = 'baz';", | ||
output: 'const foo = "bar";', | ||
errors: 1, | ||
}], | ||
} | ||
); | ||
|
||
console.log("All tests passed!"); |
9 changes: 9 additions & 0 deletions
9
docs/_examples/custom-rule-tutorial-code/eslint-plugin-example.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* @fileoverview Example an ESLint plugin with a custom rule. | ||
* @author Ben Perlmutter | ||
*/ | ||
"use strict"; | ||
|
||
const fooBarRule = require("./enforce-foo-bar"); | ||
const plugin = { rules: { "enforce-foo-bar": fooBarRule } }; | ||
module.exports = plugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @fileoverview Example ESLint config file that uses the custom rule from this tutorial. | ||
* @author Ben Perlmutter | ||
*/ | ||
"use strict"; | ||
|
||
// Import the ESLint plugin | ||
const eslintPluginExample = require("./eslint-plugin-example"); | ||
|
||
module.exports = [ | ||
{ | ||
files: ["**/*.js"], | ||
languageOptions: { | ||
sourceType: "commonjs", | ||
ecmaVersion: "latest", | ||
}, | ||
// Using the eslint-plugin-example plugin defined locally | ||
plugins: {"example": eslintPluginExample}, | ||
rules: { | ||
"example/enforce-foo-bar": "error", | ||
}, | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* @fileoverview Example of a file that will fail the custom rule in this tutorial. | ||
* @author Ben Perlmutter | ||
*/ | ||
"use strict"; | ||
|
||
/* eslint-disable no-unused-vars -- Disable other rule causing problem for this file */ | ||
|
||
// To see the error in the terminal, run the following command: | ||
// npx eslint example.js | ||
|
||
// To fix the error, run the following command: | ||
// npx eslint example.js --fix | ||
|
||
function correctFooBar() { | ||
const foo = "bar"; | ||
} | ||
|
||
function incorrectFoo(){ | ||
const foo = "baz"; // Problem! | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "eslint-plugin-example", | ||
"version": "1.0.0", | ||
"description": "ESLint plugin for enforce-foo-bar rule.", | ||
"main": "eslint-plugin-example.js", | ||
"keywords": [ | ||
"eslint", | ||
"eslintplugin", | ||
"eslint-plugin" | ||
], | ||
"peerDependencies": { | ||
"eslint": ">=8.0.0" | ||
}, | ||
"scripts": { | ||
"test": "node enforce-foo-bar.test.js" | ||
}, | ||
"author": "", | ||
"license": "ISC", | ||
"devDependencies": { | ||
"eslint": "^8.36.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.