378 lines
19 KiB
JavaScript
378 lines
19 KiB
JavaScript
require('@rushstack/eslint-config/patch/modern-module-resolution');
|
|
module.exports = {
|
|
extends: ['@microsoft/eslint-config-spfx/lib/profiles/react'],
|
|
parserOptions: { tsconfigRootDir: __dirname },
|
|
overrides: [
|
|
{
|
|
files: ['*.ts', '*.tsx'],
|
|
parser: '@typescript-eslint/parser',
|
|
'parserOptions': {
|
|
'project': './tsconfig.json',
|
|
'ecmaVersion': 2018,
|
|
'sourceType': 'module'
|
|
},
|
|
rules: {
|
|
// Prevent usage of the JavaScript null value, while allowing code to access existing APIs that may require null. https://www.npmjs.com/package/@rushstack/eslint-plugin
|
|
'@rushstack/no-new-null': 1,
|
|
// Require Jest module mocking APIs to be called before any other statements in their code block. https://www.npmjs.com/package/@rushstack/eslint-plugin
|
|
'@rushstack/hoist-jest-mock': 1,
|
|
// Require regular expressions to be constructed from string constants rather than dynamically building strings at runtime. https://www.npmjs.com/package/@rushstack/eslint-plugin-security
|
|
'@rushstack/security/no-unsafe-regexp': 1,
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/adjacent-overload-signatures': 1,
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
//
|
|
// CONFIGURATION: By default, these are banned: String, Boolean, Number, Object, Symbol
|
|
'@typescript-eslint/ban-types': [
|
|
1,
|
|
{
|
|
'extendDefaults': false,
|
|
'types': {
|
|
'String': {
|
|
'message': 'Use \'string\' instead',
|
|
'fixWith': 'string'
|
|
},
|
|
'Boolean': {
|
|
'message': 'Use \'boolean\' instead',
|
|
'fixWith': 'boolean'
|
|
},
|
|
'Number': {
|
|
'message': 'Use \'number\' instead',
|
|
'fixWith': 'number'
|
|
},
|
|
'Object': {
|
|
'message': 'Use \'object\' instead, or else define a proper TypeScript type:'
|
|
},
|
|
'Symbol': {
|
|
'message': 'Use \'symbol\' instead',
|
|
'fixWith': 'symbol'
|
|
},
|
|
'Function': {
|
|
'message': 'The \'Function\' type accepts any function-like value.'
|
|
}
|
|
}
|
|
}
|
|
],
|
|
// RATIONALE: Code is more readable when the type of every variable is immediately obvious.
|
|
// Even if the compiler may be able to infer a type, this inference will be unavailable
|
|
// to a person who is reviewing a GitHub diff. This rule makes writing code harder,
|
|
// but writing code is a much less important activity than reading it.
|
|
//
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/explicit-function-return-type': [
|
|
1,
|
|
{
|
|
'allowExpressions': true,
|
|
'allowTypedFunctionExpressions': true,
|
|
'allowHigherOrderFunctions': false
|
|
}
|
|
],
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
// Rationale to disable: although this is a recommended rule, it is up to dev to select coding style.
|
|
// Set to 1 (warning) or 2 (error) to enable.
|
|
'@typescript-eslint/explicit-member-accessibility': 0,
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/no-array-constructor': 1,
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
//
|
|
// RATIONALE: The "any" keyword disables static type checking, the main benefit of using TypeScript.
|
|
// This rule should be suppressed only in very special cases such as JSON.stringify()
|
|
// where the type really can be anything. Even if the type is flexible, another type
|
|
// may be more appropriate such as "unknown", "{}", or "Record<k,V>".
|
|
'@typescript-eslint/no-explicit-any': 1,
|
|
// RATIONALE: The #1 rule of promises is that every promise chain must be terminated by a catch()
|
|
// handler. Thus wherever a Promise arises, the code must either append a catch handler,
|
|
// or else return the object to a caller (who assumes this responsibility). Unterminated
|
|
// promise chains are a serious issue. Besides causing errors to be silently ignored,
|
|
// they can also cause a NodeJS process to terminate unexpectedly.
|
|
'@typescript-eslint/no-floating-promises': 2,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'@typescript-eslint/no-for-in-array': 2,
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/no-misused-new': 2,
|
|
// RATIONALE: The "namespace" keyword is not recommended for organizing code because JavaScript lacks
|
|
// a "using" statement to traverse namespaces. Nested namespaces prevent certain bundler
|
|
// optimizations. If you are declaring loose functions/variables, it's better to make them
|
|
// static members of a class, since classes support property getters and their private
|
|
// members are accessible by unit tests. Also, the exercise of choosing a meaningful
|
|
// class name tends to produce more discoverable APIs: for example, search+replacing
|
|
// the function "reverse()" is likely to return many false matches, whereas if we always
|
|
// write "Text.reverse()" is more unique. For large scale organization, it's recommended
|
|
// to decompose your code into separate NPM packages, which ensures that component
|
|
// dependencies are tracked more conscientiously.
|
|
//
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/no-namespace': [
|
|
1,
|
|
{
|
|
'allowDeclarations': false,
|
|
'allowDefinitionFiles': false
|
|
}
|
|
],
|
|
// RATIONALE: Parameter properties provide a shorthand such as "constructor(public title: string)"
|
|
// that avoids the effort of declaring "title" as a field. This TypeScript feature makes
|
|
// code easier to write, but arguably sacrifices readability: In the notes for
|
|
// "@typescript-eslint/member-ordering" we pointed out that fields are central to
|
|
// a class's design, so we wouldn't want to bury them in a constructor signature
|
|
// just to save some typing.
|
|
//
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
// Set to 1 (warning) or 2 (error) to enable the rule
|
|
'@typescript-eslint/no-parameter-properties': 0,
|
|
// RATIONALE: When left in shipping code, unused variables often indicate a mistake. Dead code
|
|
// may impact performance.
|
|
//
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/no-unused-vars': [
|
|
1,
|
|
{
|
|
'vars': 'all',
|
|
// Unused function arguments often indicate a mistake in JavaScript code. However in TypeScript code,
|
|
// the compiler catches most of those mistakes, and unused arguments are fairly common for type signatures
|
|
// that are overriding a base class method or implementing an interface.
|
|
'args': 'none'
|
|
}
|
|
],
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/no-use-before-define': [
|
|
2,
|
|
{
|
|
'functions': false,
|
|
'classes': true,
|
|
'variables': true,
|
|
'enums': true,
|
|
'typedefs': true
|
|
}
|
|
],
|
|
// Disallows require statements except in import statements.
|
|
// In other words, the use of forms such as var foo = require("foo") are banned. Instead use ES6 style imports or import foo = require("foo") imports.
|
|
'@typescript-eslint/no-var-requires': 'error',
|
|
// RATIONALE: The "module" keyword is deprecated except when describing legacy libraries.
|
|
//
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'@typescript-eslint/prefer-namespace-keyword': 1,
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
// Rationale to disable: it's up to developer to decide if he wants to add type annotations
|
|
// Set to 1 (warning) or 2 (error) to enable the rule
|
|
'@typescript-eslint/no-inferrable-types': 0,
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
// Rationale to disable: declaration of empty interfaces may be helpful for generic types scenarios
|
|
'@typescript-eslint/no-empty-interface': 0,
|
|
// RATIONALE: This rule warns if setters are defined without getters, which is probably a mistake.
|
|
'accessor-pairs': 1,
|
|
// RATIONALE: In TypeScript, if you write x["y"] instead of x.y, it disables type checking.
|
|
'dot-notation': [
|
|
1,
|
|
{
|
|
'allowPattern': '^_'
|
|
}
|
|
],
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
'eqeqeq': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'for-direction': 1,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'guard-for-in': 2,
|
|
// RATIONALE: If you have more than 2,000 lines in a single source file, it's probably time
|
|
// to split up your code.
|
|
'max-lines': ['warn', { max: 2000 }],
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-async-promise-executor': 2,
|
|
// RATIONALE: Deprecated language feature.
|
|
'no-caller': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-compare-neg-zero': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-cond-assign': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-constant-condition': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-control-regex': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-debugger': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-delete-var': 2,
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-duplicate-case': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-empty': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-empty-character-class': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-empty-pattern': 1,
|
|
// RATIONALE: Eval is a security concern and a performance concern.
|
|
'no-eval': 1,
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-ex-assign': 2,
|
|
// RATIONALE: System types are global and should not be tampered with in a scalable code base.
|
|
// If two different libraries (or two versions of the same library) both try to modify
|
|
// a type, only one of them can win. Polyfills are acceptable because they implement
|
|
// a standardized interoperable contract, but polyfills are generally coded in plain
|
|
// JavaScript.
|
|
'no-extend-native': 1,
|
|
// Disallow unnecessary labels
|
|
'no-extra-label': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-fallthrough': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-func-assign': 1,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'no-implied-eval': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-invalid-regexp': 2,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'no-label-var': 2,
|
|
// RATIONALE: Eliminates redundant code.
|
|
'no-lone-blocks': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-misleading-character-class': 2,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'no-multi-str': 2,
|
|
// RATIONALE: It's generally a bad practice to call "new Thing()" without assigning the result to
|
|
// a variable. Either it's part of an awkward expression like "(new Thing()).doSomething()",
|
|
// or else implies that the constructor is doing nontrivial computations, which is often
|
|
// a poor class design.
|
|
'no-new': 1,
|
|
// RATIONALE: Obsolete language feature that is deprecated.
|
|
'no-new-func': 2,
|
|
// RATIONALE: Obsolete language feature that is deprecated.
|
|
'no-new-object': 2,
|
|
// RATIONALE: Obsolete notation.
|
|
'no-new-wrappers': 1,
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-octal': 2,
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
'no-octal-escape': 2,
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-regex-spaces': 2,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'no-return-assign': 2,
|
|
// RATIONALE: Security risk.
|
|
'no-script-url': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-self-assign': 2,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'no-self-compare': 2,
|
|
// RATIONALE: This avoids statements such as "while (a = next(), a && a.length);" that use
|
|
// commas to create compound expressions. In general code is more readable if each
|
|
// step is split onto a separate line. This also makes it easier to set breakpoints
|
|
// in the debugger.
|
|
'no-sequences': 1,
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-shadow-restricted-names': 2,
|
|
// RATIONALE: Obsolete language feature that is deprecated.
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-sparse-arrays': 2,
|
|
// RATIONALE: Although in theory JavaScript allows any possible data type to be thrown as an exception,
|
|
// such flexibility adds pointless complexity, by requiring every catch block to test
|
|
// the type of the object that it receives. Whereas if catch blocks can always assume
|
|
// that their object implements the "Error" contract, then the code is simpler, and
|
|
// we generally get useful additional information like a call stack.
|
|
'no-throw-literal': 2,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'no-unmodified-loop-condition': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-unsafe-finally': 2,
|
|
// RATIONALE: Catches a common coding mistake.
|
|
'no-unused-expressions': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-unused-labels': 1,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-useless-catch': 1,
|
|
// RATIONALE: Avoids a potential performance problem.
|
|
'no-useless-concat': 1,
|
|
// RATIONALE: The "var" keyword is deprecated because of its confusing "hoisting" behavior.
|
|
// Always use "let" or "const" instead.
|
|
//
|
|
// STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json
|
|
'no-var': 2,
|
|
// RATIONALE: Generally not needed in modern code.
|
|
'no-void': 1,
|
|
// RATIONALE: Obsolete language feature that is deprecated.
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'no-with': 2,
|
|
// RATIONALE: Makes logic easier to understand, since constants always have a known value
|
|
// @typescript-eslinteslint-plugindistconfigseslint-recommended.js
|
|
'prefer-const': 1,
|
|
// RATIONALE: Catches a common coding mistake where "resolve" and "reject" are confused.
|
|
'promise/param-names': 2,
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'require-atomic-updates': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'require-yield': 1,
|
|
// "Use strict" is redundant when using the TypeScript compiler.
|
|
'strict': [
|
|
2,
|
|
'never'
|
|
],
|
|
// RATIONALE: Catches code that is likely to be incorrect
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
'use-isnan': 2,
|
|
// STANDARDIZED BY: eslint\conf\eslint-recommended.js
|
|
// Set to 1 (warning) or 2 (error) to enable.
|
|
// Rationale to disable: !!{}
|
|
'no-extra-boolean-cast': 0,
|
|
// ====================================================================
|
|
// @microsoft/eslint-plugin-spfx
|
|
// ====================================================================
|
|
'@microsoft/spfx/import-requires-chunk-name': 1,
|
|
'@microsoft/spfx/no-require-ensure': 2,
|
|
'@microsoft/spfx/pair-react-dom-render-unmount': 1
|
|
}
|
|
},
|
|
{
|
|
// For unit tests, we can be a little bit less strict. The settings below revise the
|
|
// defaults specified in the extended configurations, as well as above.
|
|
files: [
|
|
// Test files
|
|
'*.test.ts',
|
|
'*.test.tsx',
|
|
'*.spec.ts',
|
|
'*.spec.tsx',
|
|
|
|
// Facebook convention
|
|
'**/__mocks__/*.ts',
|
|
'**/__mocks__/*.tsx',
|
|
'**/__tests__/*.ts',
|
|
'**/__tests__/*.tsx',
|
|
|
|
// Microsoft convention
|
|
'**/test/*.ts',
|
|
'**/test/*.tsx'
|
|
],
|
|
rules: {
|
|
'no-new': 0,
|
|
'class-name': 0,
|
|
'export-name': 0,
|
|
forin: 0,
|
|
'label-position': 0,
|
|
'member-access': 2,
|
|
'no-arg': 0,
|
|
'no-console': 0,
|
|
'no-construct': 0,
|
|
'no-duplicate-variable': 2,
|
|
'no-eval': 0,
|
|
'no-function-expression': 2,
|
|
'no-internal-module': 2,
|
|
'no-shadowed-variable': 2,
|
|
'no-switch-case-fall-through': 2,
|
|
'no-unnecessary-semicolons': 2,
|
|
'no-unused-expression': 2,
|
|
'no-with-statement': 2,
|
|
semicolon: 2,
|
|
'trailing-comma': 0,
|
|
typedef: 0,
|
|
'typedef-whitespace': 0,
|
|
'use-named-parameter': 2,
|
|
'variable-name': 0,
|
|
whitespace: 0
|
|
}
|
|
}
|
|
]
|
|
}; |