-
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. Thees custom rules are run in addition to many standard ESLine rules. Example custom rules includes:
- Enforcing proper code layering
- Preventing checking in of
test.only(...)
- Enforcing conventions in
vscode.d.ts
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
- 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', ... }
If your rule takes custom arguments in the eslint.config.js
, for example:
rules: {
'local/code-no-not-null-assertions-on-undefined-values': ['warn', { testsOk: true }],
...
}
Make sure to update the meta.schema
property on your rule with the JSON schema for the arguments
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