ESLint (.eslintrc.json/.cjs)
Note: generally, the stricter the better (also, I generally start out with the T3 Stack standard vs "Aaron's Personal Preference")
.json vs .cjs
The difference in the file formats for ESLint configuration—.eslintrc.json
versus .eslintrc.cjs
—stems from the way ESLint allows configurations to be defined and the specific needs or constraints of your project. Let's explore the key differences and reasons:
.eslintrc.json
.eslintrc.json
Format: JSON format.
Usage: It's a static configuration file. It's straightforward and widely used for simpler configurations.
Limitation: Being JSON, it doesn't support comments or dynamic configuration logic. It's purely declarative.
.eslintrc.cjs
.eslintrc.cjs
Format: CommonJS module (JavaScript).
Usage: This format is used when you need a more dynamic or complex configuration. It allows the use of JavaScript to define the config, enabling conditional configurations, variables, comments, and other JavaScript features.
Common in TypeScript Projects: Especially useful in TypeScript projects where you might need to reference TypeScript types or enums in your ESLint configuration, as seen in your file with
/** @type {import("eslint").Linter.Config} */
.Required in Certain Environments: If you're working in a project that uses ES Modules extensively, you might need to use
.cjs
for configuration files to ensure they are interpreted as CommonJS modules, particularly in Node.js environments where ES Module support is enabled.
Specifics in Your .eslintrc.cjs
Configuration:
.eslintrc.cjs
Configuration:Dynamic Features: Your configuration utilizes JavaScript features like comments and variables, which aren't possible in plain JSON.
TypeScript Integration: The
@type
comment indicates TypeScript type checking for the config object. This enhances the configuration process by providing type safety and autocompletion in compatible editors.Customized Rules: It includes custom rules and settings that are more sophisticated than a typical JSON config might support, like setting up specific options for rules (
"@typescript-eslint/no-unused-vars"
, for example).
Choosing the Right Format:
Project Complexity: If your project requires a complex, dynamic ESLint configuration, or if you need to include comments for clarity,
.eslintrc.cjs
is a better choice.Simplicity and Standards: For simpler projects, or to adhere to more standard configurations,
.eslintrc.json
is sufficient and easier to manage.
Each format has its use case, and the choice largely depends on the specific needs of your project and your team's preferences. The .cjs
format offers more flexibility at the cost of slightly increased complexity, which can be valuable in larger or more complex projects, particularly those using TypeScript.
Sample setup (from T3 Stack + some custom modifications)
/** @type {import("eslint").Linter.Config} */
const config = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
},
plugins: ["@typescript-eslint"],
extends: [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked",
],
rules: {
// These opinionated rules are enabled in stylistic-type-checked above.
// Feel free to reconfigure them to your own preference.
"@typescript-eslint/array-type": "off",
"@typescript-eslint/consistent-type-definitions": "off",
// custom
"@typescript-eslint/no-empty-interface": "off", // can have empty Props {} interface (e.g. starting new components)
"@typescript-eslint/ban-ts-comment": "off", // can use ts-ignore
"@typescript-eslint/ban-ts-ignore": "off", // can use ts-ignore
"@typescript-eslint/consistent-type-imports": [
"warn",
{
prefer: "type-imports",
fixStyle: "inline-type-imports",
},
],
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
"@typescript-eslint/no-misused-promises": [
2,
{
checksVoidReturn: { attributes: false },
},
],
},
};
module.exports = config;
Aaron's Personal Preference
...not sure yet, but here is a recommended setup by ChatGPT (with the condition of "preferring to be on the stricter side of type-checking and ensuring certain formats, for clarity, consistency, maintainability")
{
"extends": [
"eslint:recommended",
"@typescript-eslint/recommended",
"plugin:react/recommended"
],
"env": {
"browser": true,
"node": true,
"es6": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"plugins": [
"@typescript-eslint",
"react"
],
"rules": {
"eqeqeq": ["error", "always"],
"curly": "error",
"complexity": ["warn", 10],
"consistent-return": "error",
"arrow-parens": ["error", "always"],
"no-unused-vars": "warn",
"no-console": "warn",
"no-debugger": "warn",
"no-trailing-spaces": "error",
"no-use-before-define": "error",
"prefer-const": "error",
"quotes": ["error", "single", { "avoidEscape": true }],
"semi": ["error", "always"],
"indent": ["error", 2],
"linebreak-style": ["error", "unix"],
"eol-last": ["error", "always"],
"array-callback-return": "warn",
"no-multiple-empty-lines": ["error", { "max": 1 }],
"@typescript-eslint/no-explicit-any": "warn",
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off"
},
"settings": {
"react": {
"version": "detect"
}
}
}
This configuration:
Extends from
eslint:recommended
,@typescript-eslint/recommended
, andplugin:react/recommended
to include a robust set of standard, TypeScript, and React rules.Sets the environment to browser, Node.js, and ES6 for global variables.
Uses the TypeScript parser for ESLint and sets ECMAScript 2020 as the version, with JSX support.
Includes rules for equality checks, curly braces usage, complexity limits, consistent return statements, arrow function parentheses, usage of
const
, single quotes, semicolons, indentation, linebreak style, end-of-line characters, array callback returns, and limiting multiple empty lines.Warns against unused variables, console statements, and the use of
any
in TypeScript, encouraging a stricter type-checking approach.Disables some React-specific rules (
jsx-uses-react
andreact-in-jsx-scope
) that are not necessary with the latest React versions due to the new JSX transform.
Popular Options
extends
(Extend Configurations):Description: Extends a set of configurations from an existing configuration.
Popular Use: Commonly, projects extend from configurations like
"eslint:recommended"
for a good base set of rules, or"plugin:react/recommended"
for React projects.
env
(Environment):Description: Specifies environments which provide predefined global variables.
Popular Use: Environments like
{ "browser": true, "node": true }
are commonly used to indicate that the code runs in both browser and Node.js environments.
parserOptions
(Parser Options):Description: Provides options for the parsing engine.
Popular Use: For TypeScript, using
"@typescript-eslint/parser"
with options like{ "ecmaVersion": 2020, "sourceType": "module" }
is common.
rules
(Rules Configuration):Description: Customizes rules to enable, disable, or adjust their error levels.
Popular Use: Overriding specific rules like
"no-console": "warn"
to display a warning for console statements or"eqeqeq": "error"
to enforce strict equality.
plugins
(Plugins):Description: Extends ESLint with additional rules, environments, or configurations from third-party plugins.
Popular Use: Plugins like
"@typescript-eslint/eslint-plugin"
for TypeScript projects, or"react"
for React projects.
globals
(Global Variables):Description: Declares global variables that should not be considered as undefined.
Popular Use: Defining globals like
{ "jQuery": "readonly" }
in projects using jQuery.
parser
(The Parser):Description: Specifies the parser to be used by ESLint.
Popular Use: In TypeScript projects, using
"@typescript-eslint/parser"
.
ignorePatterns
(Ignore Patterns):Description: Specifies patterns of files to ignore.
Popular Use: Common patterns include
"/node_modules/"
,"/build/"
, or specific files like"webpack.config.js"
.
overrides
(Overrides for Specific Files):Description: Overrides specific configurations for certain file patterns.
Popular Use: Overriding rules or settings for files like
*.test.js
or files in a specific directory.
settings
(Shared Settings):Description: Provides shared settings for use by rules.
Popular Use: Useful in plugins like
"react"
where you can specify React version.
Additional Options
noUseBeforeDefine
(No Use Before Define):Description: Disallows the use of variables before they are defined.
Popular Use:
"no-use-before-define": "error"
to prevent reference errors caused by using a variable before it's declared.
maxParams
(Maximum Parameters in Function Definition):Description: Enforces a maximum number of parameters in function definitions.
Popular Use:
"max-params": ["warn", 3]
to warn when a function has more than three parameters, promoting functions that are easier to understand and maintain.
complexity
(Cyclomatic Complexity):Description: Enforces a maximum cyclomatic complexity allowed in a program.
Popular Use:
"complexity": ["warn", 10]
to warn about functions that are too complex, which might be hard to understand and maintain.
noImplicitAny
(No Implicitany
Type in TypeScript):Description: Disallows the use of the
any
type without explicit declaration in TypeScript.Popular Use:
"@typescript-eslint/no-explicit-any": "error"
to ensure strict typing in TypeScript projects.
consistent-return
(Enforce Consistent Return):Description: Enforces that functions either always or never specify return types.
Popular Use:
"consistent-return": "error"
to ensure that functions are clear about their return values.
indent
(Indentation):Description: Enforces a specific indentation style.
Popular Use:
"indent": ["error", 2]
or"indent": ["error", "tab"]
to enforce a consistent indentation style of either spaces or tabs.
no-trailing-spaces
(No Trailing Spaces):Description: Disallows trailing whitespace at the end of lines.
Popular Use:
"no-trailing-spaces": "error"
to keep the codebase clean and avoid unnecessary whitespace.
curly
(Curly Brace Convention):Description: Enforces consistent use of curly braces in control statements.
Popular Use:
"curly": "error"
to ensure thatif
,else if
,else
,for
,while
, anddo
statements are always block-scoped with curly braces, improving readability and reducing errors.
linebreak-style
(Linebreak Style):Description: Enforces a consistent linebreak style.
Popular Use:
"linebreak-style": ["error", "unix"]
or"linebreak-style": ["error", "windows"]
based on your development environment.
quotes
(Quotation Marks):Description: Enforces the consistent use of either backticks, double, or single quotes.
Popular Use:
"quotes": ["error", "single", { "avoidEscape": true }]
to enforce single quotes but allow double quotes to avoid escaping.
no-unused-vars
(No Unused Variables):Description: Disallows unused variables.
Popular Use:
"no-unused-vars": ["warn"]
to catch and clean up variables that are declared but not used.
prefer-const
(Preferconst
):Description: Suggest using
const
for variables that are never reassigned after declared.Popular Use:
"prefer-const": "error"
to encourage the use ofconst
overlet
where possible, which can make code clearer and reduce potential bugs.
array-callback-return
(Enforce Return in Array Method Callbacks):Description: Enforces return statements in callbacks of array’s methods like
.map()
,.forEach()
,.filter()
, etc.Popular Use:
"array-callback-return": "warn"
to ensure that these callbacks explicitly return values when expected.
no-multiple-empty-lines
(No Multiple Empty Lines):Description: Disallows multiple empty lines.
Popular Use:
"no-multiple-empty-lines": ["error", { "max": 1 }]
to keep the code clean and readable.
eol-last
(End of Line Requirement for Files):Description: Enforces that files end with a newline.
Popular Use:
"eol-last": ["error", "always"]
to ensure files end with a line break, which can improve compatibility with various tools and systems.
d
Last updated