-
Notifications
You must be signed in to change notification settings - Fork 35.5k
Custom eslint rules
VS Code use a set of custom ESLint to enforce repo specific coding rules and styles. These custom rules are run in addition to many standard ESLine rules we enable in the project. Some example custom rules includes:
- Enforcing proper code layering
- Preventing checking in of
test.only(...)
- Enforcing conventions in
vscode.d.ts
Custom rules are mostly used for enforcing or banning certain coding patterns. We tend to leave stylistic choices up to area owners unless there's a good reason to enforce something project wide.
This doc provides a brief overview of how these rules are setup and how you can add a new one.
- ESLint rules — General documentation about writing eslint rules
- TypeScript ASTs and eslint — Look at how ESLint works with TS programs
- ESTree selectors — Info about the selector syntax rules use to target specific nodes in an AST. Works similarly to css selectors.
- TypeScript ESLint playground — Useful tool for figuring out the structure of TS programs and debugging custom rule selectors
Custom rules are defined in the .eslint-plugin-local
folder. Each rule is defined in its own TypeScript file. These follow the naming convention:
-
code-RULE-NAME.ts
— General rules that apply to the entire repo. -
vscode-dts-RULE-NAME.ts
— Rules that apply just tovscode.d.ts
.
These rules are then enabled in the eslint.config.js
file. This is the main eslint configuration for our repo. It defines a set of file scopes which rules should apple to files in those scopes.
For example, here's a configuration that enables the no test.only
rule in all *.test.ts
files in the VS Code repo:
{
// Define which files these rules apply to
files: [
'**/*.test.ts'
],
languageOptions: { parser: tseslint.parser, },
plugins: {
'local': pluginLocal,
},
rules: {
// Enable the rule from .eslint-plugin-local/code-no-test-only.ts
'local/code-no-test-only': 'error',
}
}
This walks through the steps to create a new eslint rule:
-
Create a new rule file under
.eslint-plugin-local
. Generally you should call itcode-YOUR-RULE-NAME.ts
, for example,.eslint-plugin-local/code-no-not-null-assertions-on-undefined-values.ts
-
In this file, add the rule. Here's a template:
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as eslint from 'eslint'; export = new class YourRuleName implements eslint.Rule.RuleModule { readonly meta: eslint.Rule.RuleMetaData = { messages: { customMessageName: 'message text shown in errors/warnings', }, schema: false, }; create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { return { [SELECTOR]: (node: any) => { // Report errors if needed return context.report({ node, messageId: 'customMessageName' }); } }; } };
- Update the name of the class to match the name of your rule
- Add message entries for any errors you want to report
- Update
SELECTOR
with the ESTree selector needed to target the nodes you are interested in. Use the TypeScript ESLint playground to figure out which nodes you need and debug selectors
-
Register the rule in
eslint.config.js
Generally this is just turning on the rule in the rule list like so:
rules: { // Name should match file name 'local/code-no-not-null-assertions-on-undefined-values': 'warn', ... }
Rules can also take custom arguments. For example, here's how we can pass arguments to a custom rule in the eslint.config.js
:
rules: {
'local/code-no-not-null-assertions-on-undefined-values': ['warn', { testsOk: true }],
...
}
In these cases amek sure to update the meta.schema
property on your rule with the JSON schema for the arguments. You can access these arguments using context.options
in the rule create
function
Fixes are a useful way to mechanically fix basic linting issues, such as auto inserting semicolons. These fix typically work at the AST level, say they are more reliable way to perform bulk fixes compared to find/replaces
To add a fix for a custom rule:
-
On the
meta
for your rule, addfixable: 'code'
-
When reporting an error in the rule, also include a
fix
. This is a function that takes afixer
argument and returns one or more fixes.
See the Double quoted to single quoted string covert fix for an example. The ESLint docs also have details on adding fixes and the fixer api
The fixes can be run using npx eslint --fix
in the VS Code repo
Project Management
- Roadmap
- Iteration Plans
- Development Process
- Issue Tracking
- Build Champion
- Release Process
- Running the Endgame
- Related Projects
Contributing
- How to Contribute
- Submitting Bugs and Suggestions
- Feedback Channels
- Source Code Organization
- Coding Guidelines
- Testing
- Dealing with Test Flakiness
- Contributor License Agreement
- Extension API Guidelines
- Accessibility Guidelines
- Custom ESLint rules
Documentation