mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-09-29 16:57:00 +08:00
It should be OK to have some allowed rules in the .docs.ts files that differ from the reset of DevTools. Bug: none Change-Id: I0dde28db88a784338a5b4bc638c6015dc8def669 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7207245 Commit-Queue: Nikolay Vitkov <nvitkov@chromium.org> Reviewed-by: Kim-Anh Tran <kimanh@chromium.org>
917 lines
26 KiB
JavaScript
917 lines
26 KiB
JavaScript
// Copyright 2025 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import stylisticPlugin from '@stylistic/eslint-plugin';
|
|
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
import eslintPlugin from 'eslint-plugin-eslint-plugin';
|
|
import importPlugin from 'eslint-plugin-import';
|
|
import jsdocPlugin from 'eslint-plugin-jsdoc';
|
|
import litPlugin from 'eslint-plugin-lit';
|
|
import mochaPlugin from 'eslint-plugin-mocha';
|
|
import globals from 'globals';
|
|
import { join } from 'node:path';
|
|
import typescriptEslint from 'typescript-eslint';
|
|
|
|
import devToolsPlugin from './scripts/eslint_rules/plugin.mjs';
|
|
|
|
export default defineConfig([
|
|
globalIgnores([
|
|
// Git submodules that are not in third_party
|
|
'build/',
|
|
'buildtools/',
|
|
|
|
// Don't include the common build directory
|
|
'out/',
|
|
// Don't include third party code
|
|
'third_party/',
|
|
|
|
'front_end/diff/diff_match_patch.js',
|
|
'front_end/models/javascript_metadata/NativeFunctions.js',
|
|
// All of these scripts are auto-generated so don't lint them.
|
|
'front_end/generated/ARIAProperties.js',
|
|
'front_end/generated/Deprecation.ts',
|
|
'front_end/generated/InspectorBackendCommands.ts',
|
|
'front_end/generated/protocol-mapping.d.ts',
|
|
'front_end/generated/protocol-proxy-api.d.ts',
|
|
'front_end/generated/protocol.ts',
|
|
// Any third_party addition has its source code checked out into
|
|
// third_party/X/package, so we ignore that code as it's not code we author or
|
|
// own.
|
|
'front_end/third_party/*/package/',
|
|
// Any JS files are also not authored by devtools-frontend, so we ignore those.
|
|
'front_end/third_party/**/*',
|
|
// Lighthouse doesn't have a package/ folder but has other nested folders, so
|
|
// we ignore any folders within the lighthouse directory.
|
|
'front_end/third_party/lighthouse/*/',
|
|
// The CodeMirror bundle file is auto-generated and rolled-up as part of the',
|
|
// install script, so we don't need to lint it.
|
|
'front_end/third_party/codemirror.next/bundle.ts',
|
|
// Lit lib files are auto-generated and rolled up as part of the install script.
|
|
'front_end/third_party/lit/src/*.ts',
|
|
// @puppeteer/replay is auto-generated.
|
|
'front_end/third_party/puppeteer-replay/**/*.ts',
|
|
// Third party code we did not author for extensions
|
|
'extensions/cxx_debugging/third_party/**/*',
|
|
|
|
'**/node_modules',
|
|
'scripts/build/typescript/tests',
|
|
'scripts/migration/**/*.js',
|
|
'scripts/protocol_typescript/*.js',
|
|
'scripts/deps/tests/fixtures',
|
|
'test/**/fixtures/',
|
|
'test/e2e/**/*.js',
|
|
'test/shared/**/*.js',
|
|
]),
|
|
{
|
|
name: 'JavaScript files',
|
|
plugins: {
|
|
'@typescript-eslint': typescriptEslint.plugin,
|
|
'@stylistic': stylisticPlugin,
|
|
'@eslint-plugin': eslintPlugin,
|
|
mocha: mochaPlugin,
|
|
'@devtools': devToolsPlugin,
|
|
import: importPlugin,
|
|
jsdoc: jsdocPlugin,
|
|
lit: litPlugin,
|
|
},
|
|
|
|
languageOptions: {
|
|
ecmaVersion: 'latest',
|
|
sourceType: 'module',
|
|
globals: {
|
|
...globals.browser,
|
|
},
|
|
},
|
|
|
|
linterOptions: {
|
|
reportUnusedDisableDirectives: 'error',
|
|
reportUnusedInlineConfigs: 'error',
|
|
},
|
|
|
|
rules: {
|
|
// syntax preferences
|
|
'@stylistic/quotes': [
|
|
'error',
|
|
'single',
|
|
{
|
|
avoidEscape: true,
|
|
allowTemplateLiterals: 'always',
|
|
},
|
|
],
|
|
|
|
'@stylistic/semi': 'error',
|
|
'@stylistic/no-extra-semi': 'error',
|
|
'@stylistic/comma-style': ['error', 'last'],
|
|
'@stylistic/wrap-iife': ['error', 'inside'],
|
|
|
|
'@stylistic/spaced-comment': [
|
|
'error',
|
|
'always',
|
|
{
|
|
markers: ['*'],
|
|
},
|
|
],
|
|
|
|
eqeqeq: 'error',
|
|
|
|
'accessor-pairs': [
|
|
'error',
|
|
{
|
|
getWithoutSet: false,
|
|
setWithoutGet: false,
|
|
},
|
|
],
|
|
|
|
curly: 'error',
|
|
'@stylistic/new-parens': 'error',
|
|
'@stylistic/function-call-spacing': 'error',
|
|
'@stylistic/arrow-parens': ['error', 'as-needed'],
|
|
'@stylistic/eol-last': 'error',
|
|
'object-shorthand': ['error', 'properties'],
|
|
'no-useless-rename': 'error',
|
|
|
|
// anti-patterns
|
|
'no-caller': 'error',
|
|
'no-case-declarations': 'error',
|
|
'no-cond-assign': 'error',
|
|
|
|
'no-console': [
|
|
'error',
|
|
{
|
|
allow: [
|
|
'assert',
|
|
'context',
|
|
'error',
|
|
'timeStamp',
|
|
'time',
|
|
'timeEnd',
|
|
'warn',
|
|
],
|
|
},
|
|
],
|
|
|
|
'no-debugger': 'error',
|
|
'no-dupe-keys': 'error',
|
|
'no-duplicate-case': 'error',
|
|
|
|
'no-else-return': [
|
|
'error',
|
|
{
|
|
allowElseIf: false,
|
|
},
|
|
],
|
|
|
|
'no-empty': [
|
|
'error',
|
|
{
|
|
allowEmptyCatch: true,
|
|
},
|
|
],
|
|
'no-lonely-if': 'error',
|
|
|
|
'no-empty-character-class': 'error',
|
|
'no-global-assign': 'error',
|
|
'no-implied-eval': 'error',
|
|
'no-labels': 'error',
|
|
'no-multi-str': 'error',
|
|
'no-object-constructor': 'error',
|
|
'no-octal-escape': 'error',
|
|
'no-self-compare': 'error',
|
|
'no-shadow-restricted-names': 'error',
|
|
'no-unreachable': 'error',
|
|
'no-unsafe-negation': 'error',
|
|
|
|
'no-unused-vars': [
|
|
'error',
|
|
{
|
|
args: 'none',
|
|
vars: 'local',
|
|
},
|
|
],
|
|
|
|
'no-var': 'error',
|
|
'no-with': 'error',
|
|
'prefer-const': 'error',
|
|
radix: 'error',
|
|
'valid-typeof': 'error',
|
|
'no-return-assign': ['error', 'always'],
|
|
'no-implicit-coercion': ['error', { allow: ['!!'] }],
|
|
|
|
'no-array-constructor': 'error',
|
|
|
|
// es2015 features
|
|
'require-yield': 'error',
|
|
'@stylistic/template-curly-spacing': ['error', 'never'],
|
|
|
|
// file whitespace
|
|
'@stylistic/no-multiple-empty-lines': [
|
|
'error',
|
|
{
|
|
max: 1,
|
|
},
|
|
],
|
|
'@stylistic/no-mixed-spaces-and-tabs': 'error',
|
|
'@stylistic/no-trailing-spaces': 'error',
|
|
'@stylistic/linebreak-style': ['error', 'unix'],
|
|
|
|
/**
|
|
* Disabled, aspirational rules
|
|
*/
|
|
'@stylistic/indent': [
|
|
'off',
|
|
2,
|
|
{
|
|
SwitchCase: 1,
|
|
CallExpression: {
|
|
arguments: 2,
|
|
},
|
|
MemberExpression: 2,
|
|
},
|
|
],
|
|
|
|
// brace-style is disabled, as eslint cannot enforce 1tbs as default, but allman for functions
|
|
'@stylistic/brace-style': [
|
|
'off',
|
|
'allman',
|
|
{
|
|
allowSingleLine: true,
|
|
},
|
|
],
|
|
|
|
// key-spacing is disabled, as some objects use value-aligned spacing, some not.
|
|
'@stylistic/key-spacing': [
|
|
'off',
|
|
{
|
|
beforeColon: false,
|
|
afterColon: true,
|
|
align: 'value',
|
|
},
|
|
],
|
|
|
|
'@stylistic/quote-props': ['error', 'as-needed'],
|
|
|
|
// no-implicit-globals will prevent accidental globals
|
|
'no-implicit-globals': 'off',
|
|
'no-unused-private-class-members': 'error',
|
|
'no-useless-constructor': 'error',
|
|
|
|
// Sort imports first
|
|
'import/first': 'error',
|
|
// Closure does not properly typecheck default exports
|
|
'import/no-default-export': 'error',
|
|
/**
|
|
* Catch duplicate import paths. For example this would catch the following example:
|
|
* import {Foo} from './foo.js'
|
|
* import * as FooModule from './foo.js'
|
|
**/
|
|
'import/no-duplicates': 'error',
|
|
/**
|
|
* Provides more consistency in the imports.
|
|
*/
|
|
'import/order': [
|
|
'error',
|
|
{
|
|
// We need to group the builtin and external as clang-format
|
|
// can't differentiate the two
|
|
groups: [['builtin', 'external'], 'parent', 'sibling', 'index'],
|
|
'newlines-between': 'always',
|
|
// clang-format has it's own logic overriding this
|
|
named: false,
|
|
alphabetize: {
|
|
order: 'asc',
|
|
caseInsensitive: true,
|
|
},
|
|
},
|
|
],
|
|
'import/enforce-node-protocol-usage': ['error', 'always'],
|
|
// Try to spot '// console.log()' left over from debugging
|
|
'@devtools/no-commented-out-console': 'error',
|
|
// Prevent imports being commented out rather than deleted.
|
|
'@devtools/no-commented-out-import': 'error',
|
|
/**
|
|
* Enforce some consistency and usefulness of JSDoc comments, to make sure
|
|
* we actually benefit from them.
|
|
*/
|
|
'jsdoc/check-alignment': 'error',
|
|
'jsdoc/check-tag-names': [
|
|
'error',
|
|
{
|
|
definedTags: [
|
|
'attribute', // @attribute is used by lit-analyzer (through web-component-analyzer)
|
|
'meaning', // @meaning is used by localization
|
|
],
|
|
},
|
|
],
|
|
'jsdoc/empty-tags': 'error',
|
|
'jsdoc/multiline-blocks': 'error',
|
|
'jsdoc/no-bad-blocks': 'error',
|
|
'jsdoc/no-blank-blocks': [
|
|
'error',
|
|
{
|
|
enableFixer: true,
|
|
},
|
|
],
|
|
'jsdoc/require-asterisk-prefix': 'error',
|
|
'jsdoc/require-param-name': 'error',
|
|
'jsdoc/require-hyphen-before-param-description': ['error', 'never'],
|
|
'jsdoc/sort-tags': 'error',
|
|
},
|
|
},
|
|
{
|
|
name: 'TypeScript files',
|
|
files: ['**/*.ts'],
|
|
|
|
languageOptions: {
|
|
ecmaVersion: 'latest',
|
|
sourceType: 'module',
|
|
|
|
parser: typescriptEslint.parser,
|
|
parserOptions: {
|
|
allowAutomaticSingleRunInference: true,
|
|
project: join(
|
|
import.meta.dirname,
|
|
'config',
|
|
'typescript',
|
|
'tsconfig.eslint.json',
|
|
),
|
|
},
|
|
},
|
|
|
|
rules: {
|
|
'@typescript-eslint/array-type': [
|
|
'error',
|
|
{
|
|
default: 'array-simple',
|
|
},
|
|
],
|
|
'@typescript-eslint/no-explicit-any': [
|
|
'error',
|
|
{
|
|
ignoreRestArgs: true,
|
|
},
|
|
],
|
|
|
|
'@typescript-eslint/explicit-member-accessibility': [
|
|
'error',
|
|
{
|
|
accessibility: 'no-public',
|
|
},
|
|
],
|
|
|
|
// run just the TypeScript unused-vars rule, else we get duplicate errors
|
|
'no-unused-vars': 'off',
|
|
'@typescript-eslint/no-unused-vars': [
|
|
'error',
|
|
{
|
|
argsIgnorePattern: '^_',
|
|
},
|
|
],
|
|
|
|
'@stylistic/member-delimiter-style': [
|
|
'error',
|
|
{
|
|
multiline: {
|
|
delimiter: 'semi',
|
|
requireLast: true,
|
|
},
|
|
|
|
singleline: {
|
|
delimiter: 'comma',
|
|
requireLast: false,
|
|
},
|
|
|
|
overrides: {
|
|
interface: {
|
|
singleline: {
|
|
delimiter: 'semi',
|
|
requireLast: false,
|
|
},
|
|
|
|
multiline: {
|
|
delimiter: 'semi',
|
|
requireLast: true,
|
|
},
|
|
},
|
|
|
|
typeLiteral: {
|
|
singleline: {
|
|
delimiter: 'comma',
|
|
requireLast: false,
|
|
},
|
|
|
|
multiline: {
|
|
delimiter: 'comma',
|
|
requireLast: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
|
|
'@typescript-eslint/no-floating-promises': [
|
|
'error',
|
|
{
|
|
ignoreVoid: true,
|
|
},
|
|
],
|
|
|
|
/**
|
|
* Enforce that enum members are explicitly defined:
|
|
* const enum Foo { A = 'a' } rather than const enum Foo { A }
|
|
*/
|
|
'@typescript-eslint/prefer-enum-initializers': 'error',
|
|
/**
|
|
* Ban non-null assertion operator, e.g.:
|
|
* this.foo!.toLowerCase()
|
|
*/
|
|
'@typescript-eslint/no-non-null-assertion': 'error',
|
|
'@typescript-eslint/consistent-type-imports': 'error',
|
|
|
|
'@typescript-eslint/naming-convention': [
|
|
'error',
|
|
// Forbids interfaces starting with an I prefix.
|
|
{
|
|
selector: 'interface',
|
|
format: ['PascalCase'],
|
|
|
|
custom: {
|
|
regex: '^I[A-Z]',
|
|
match: false,
|
|
},
|
|
},
|
|
{
|
|
selector: [
|
|
'function',
|
|
'accessor',
|
|
'method',
|
|
'property',
|
|
'parameterProperty',
|
|
],
|
|
format: ['camelCase'],
|
|
},
|
|
{
|
|
selector: 'variable',
|
|
|
|
filter: {
|
|
// Ignore localization variables.
|
|
regex: '^(UIStrings|str_)$',
|
|
match: false,
|
|
},
|
|
|
|
format: ['camelCase'],
|
|
},
|
|
{
|
|
// We are using camelCase, PascalCase and UPPER_CASE for top-level constants, allow the for now.
|
|
selector: 'variable',
|
|
modifiers: ['const'],
|
|
filter: {
|
|
// Ignore localization variables.
|
|
regex: '^(UIStrings|str_)$',
|
|
match: false,
|
|
},
|
|
|
|
format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
|
|
},
|
|
{
|
|
selector: 'classProperty',
|
|
modifiers: ['static', 'readonly'],
|
|
format: ['UPPER_CASE', 'camelCase'],
|
|
},
|
|
{
|
|
selector: 'enumMember',
|
|
format: ['UPPER_CASE'],
|
|
},
|
|
{
|
|
selector: ['typeLike'],
|
|
format: ['PascalCase'],
|
|
},
|
|
{
|
|
selector: 'parameter',
|
|
format: ['camelCase'],
|
|
leadingUnderscore: 'allow',
|
|
},
|
|
{
|
|
// Public methods are currently in transition and may still have leading underscores.
|
|
selector: 'method',
|
|
modifiers: ['public'],
|
|
format: ['camelCase'],
|
|
leadingUnderscore: 'allow',
|
|
},
|
|
{
|
|
selector: 'property',
|
|
modifiers: ['public'],
|
|
format: ['camelCase'],
|
|
leadingUnderscore: 'allow',
|
|
},
|
|
{
|
|
// Object literals may be constructed as arguments to external libraries which follow different styles.
|
|
selector: ['objectLiteralMethod', 'objectLiteralProperty'],
|
|
modifiers: ['public'],
|
|
format: null,
|
|
},
|
|
{
|
|
// Ignore type properties that require quotes
|
|
selector: 'typeProperty',
|
|
format: null,
|
|
modifiers: ['requiresQuotes'],
|
|
},
|
|
],
|
|
|
|
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
|
|
|
|
// Disable eslint base rule
|
|
'no-throw-literal': 'off',
|
|
'@typescript-eslint/only-throw-error': 'error',
|
|
|
|
// Disabled this rule while investigating why it creates
|
|
// certain TypeScript compilation errors after fixes
|
|
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
|
|
|
|
'@typescript-eslint/no-inferrable-types': 'error',
|
|
|
|
'@typescript-eslint/consistent-generic-constructors': [
|
|
'error',
|
|
'constructor',
|
|
],
|
|
|
|
// This is more performant
|
|
// And should provide better stack trace when debugging
|
|
// see https://v8.dev/blog/fast-async.
|
|
'@typescript-eslint/return-await': ['error', 'always'],
|
|
|
|
'@typescript-eslint/ban-ts-comment': [
|
|
'error',
|
|
{
|
|
// Change after we add some placeholder for old errors
|
|
minimumDescriptionLength: 0,
|
|
'ts-check': false,
|
|
'ts-expect-error': 'allow-with-description',
|
|
'ts-ignore': true,
|
|
'ts-nocheck': true,
|
|
},
|
|
],
|
|
|
|
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
|
|
'@typescript-eslint/no-unsafe-function-type': 'error',
|
|
|
|
'@typescript-eslint/no-empty-object-type': [
|
|
'error',
|
|
{
|
|
allowInterfaces: 'with-single-extends',
|
|
},
|
|
],
|
|
|
|
'no-array-constructor': 'off',
|
|
'@typescript-eslint/no-array-constructor': 'error',
|
|
|
|
'@typescript-eslint/consistent-indexed-object-style': 'error',
|
|
|
|
'no-useless-constructor': 'off',
|
|
'@typescript-eslint/no-useless-constructor': 'error',
|
|
|
|
'@devtools/no-underscored-properties': 'error',
|
|
'@devtools/inline-type-imports': 'error',
|
|
|
|
'@devtools/enforce-default-import-name': [
|
|
'error',
|
|
{
|
|
// Enforce that any import of models/trace/trace.js names the import Trace.
|
|
modulePath: join(
|
|
import.meta.dirname,
|
|
'front_end',
|
|
'models',
|
|
'trace',
|
|
'trace.js',
|
|
),
|
|
importName: 'Trace',
|
|
},
|
|
],
|
|
|
|
'@devtools/validate-timing-types': 'error',
|
|
|
|
// Disallow redundant (and potentially conflicting) type information
|
|
// within JSDoc comments.
|
|
'jsdoc/no-types': 'error',
|
|
'jsdoc/require-returns-description': 'error',
|
|
},
|
|
},
|
|
{
|
|
name: 'Scripts files',
|
|
files: ['scripts/**/*'],
|
|
rules: {
|
|
'no-console': 'off',
|
|
'@devtools/es-modules-import': 'off',
|
|
'import/no-default-export': 'off',
|
|
},
|
|
},
|
|
{
|
|
name: 'Front-end files',
|
|
files: ['front_end/**/*'],
|
|
rules: {
|
|
// L10n rules are only relevant in 'front_end'.
|
|
'@devtools/l10n-filename-matches': [
|
|
'error',
|
|
{
|
|
rootFrontendDirectory: join(import.meta.dirname, 'front_end'),
|
|
},
|
|
],
|
|
'@devtools/l10n-i18nString-call-only-with-uistrings': 'error',
|
|
'@devtools/l10n-no-i18nString-calls-module-instantiation': 'error',
|
|
'@devtools/l10n-no-locked-or-placeholder-only-phrase': 'error',
|
|
'@devtools/l10n-no-uistrings-export': 'error',
|
|
'@devtools/l10n-no-unused-message': 'error',
|
|
},
|
|
},
|
|
{
|
|
name: 'Front-end TypeScript files',
|
|
files: ['front_end/**/*.ts'],
|
|
rules: {
|
|
'@typescript-eslint/explicit-function-return-type': [
|
|
'error',
|
|
{
|
|
allowExpressions: true,
|
|
allowConciseArrowFunctionExpressionsStartingWithVoid: true,
|
|
allowIIFEs: true,
|
|
},
|
|
],
|
|
'@devtools/no-imperative-dom-api': 'error',
|
|
'@devtools/no-lit-render-outside-of-view': 'error',
|
|
'@devtools/no-importing-images-from-src': 'error',
|
|
'@devtools/enforce-custom-event-names': 'error',
|
|
'@devtools/set-data-type-reference': 'error',
|
|
'@devtools/no-bound-component-methods': 'error',
|
|
'@devtools/no-adopted-style-sheets': 'error',
|
|
'@devtools/no-customized-builtin-elements': 'error',
|
|
'@devtools/no-deprecated-component-usages': 'error',
|
|
'@devtools/no-self-closing-custom-element-tagnames': 'error',
|
|
'@devtools/no-a-tags-in-lit': 'error',
|
|
'@devtools/check-css-import': 'error',
|
|
'@devtools/enforce-optional-properties-last': 'error',
|
|
'@devtools/check-enumerated-histograms': 'error',
|
|
'@devtools/require-super-calls-in-overridden-methods': [
|
|
'error',
|
|
{
|
|
methodNames: ['wasShown', 'willHide'],
|
|
},
|
|
],
|
|
'@devtools/static-custom-event-names': 'error',
|
|
'@devtools/lit-no-attribute-quotes': 'error',
|
|
'@devtools/lit-template-result-or-nothing': 'error',
|
|
'@devtools/inject-checkbox-styles': 'error',
|
|
'@devtools/jslog-context-list': 'error',
|
|
'@devtools/es-modules-import': 'error',
|
|
'@devtools/html-tagged-template': 'error',
|
|
'@devtools/enforce-ui-kit-named-import': 'error',
|
|
'@devtools/enforce-custom-element-definitions-location': [
|
|
'error',
|
|
{
|
|
rootFrontendDirectory: join(import.meta.dirname, 'front_end'),
|
|
},
|
|
],
|
|
'@devtools/enforce-ui-strings-as-const': 'error',
|
|
'@devtools/no-new-lit-element-components': 'error',
|
|
'@devtools/enforce-custom-element-prefix': 'error',
|
|
|
|
// Lit recommended
|
|
'lit/attribute-value-entities': 'error',
|
|
'lit/binding-positions': 'error',
|
|
'lit/no-duplicate-template-bindings': 'error',
|
|
'lit/no-invalid-html': 'error',
|
|
// TODO: enable this once we figure ot the custom directive
|
|
// 'lit/no-legacy-template-syntax': 'error',
|
|
'lit/no-property-change-update': 'error',
|
|
|
|
// Lit DevTools preferred
|
|
'lit/prefer-nothing': 'error',
|
|
'lit/value-after-constraints': 'error',
|
|
'lit/quoted-expressions': ['error', 'never'],
|
|
},
|
|
},
|
|
{
|
|
name: 'Front-end meta files',
|
|
files: ['front_end/**/*-meta.ts'],
|
|
rules: {
|
|
'@typescript-eslint/naming-convention': [
|
|
'error',
|
|
{
|
|
selector: 'parameter',
|
|
format: ['camelCase', 'PascalCase'],
|
|
leadingUnderscore: 'allow',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
name: 'Front-end docs files',
|
|
files: ['front_end/**/*.docs.ts'],
|
|
rules: {
|
|
'no-console': 'off',
|
|
},
|
|
},
|
|
{
|
|
name: 'TypeScript test files',
|
|
files: [
|
|
'*.test.ts',
|
|
// This makes the specificity greater than the front-end ts files
|
|
'front_end/**/*.test.ts',
|
|
'test/**/*.ts',
|
|
'**/testing/*.ts',
|
|
'scripts/eslint_rules/test/**/*',
|
|
'extensions/cxx_debugging/e2e/**',
|
|
],
|
|
|
|
rules: {
|
|
// errors on {describe, it}.only
|
|
'mocha/no-exclusive-tests': 'error',
|
|
|
|
'mocha/no-async-describe': 'error',
|
|
'mocha/no-global-tests': 'error',
|
|
'mocha/no-nested-tests': 'error',
|
|
|
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
|
|
'@typescript-eslint/only-throw-error': [
|
|
'error',
|
|
{
|
|
allow: [
|
|
{
|
|
// Chai AssertionError does not extend Error
|
|
from: 'package',
|
|
package: 'chai',
|
|
name: ['AssertionError'],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
|
|
'@devtools/check-test-definitions': 'error',
|
|
'@devtools/no-assert-strict-equal-for-arrays-and-objects': 'error',
|
|
'@devtools/no-assert-deep-strict-equal': 'error',
|
|
'@devtools/no-assert-equal': 'error',
|
|
'@devtools/no-assert-equal-boolean-null-undefined': 'error',
|
|
'@devtools/no-capture-screenshot': 'error',
|
|
'@devtools/no-imperative-dom-api': 'off',
|
|
'@devtools/no-lit-render-outside-of-view': 'off',
|
|
'@devtools/prefer-assert-instance-of': 'error',
|
|
'@devtools/prefer-assert-is-ok': 'error',
|
|
'@devtools/prefer-assert-length-of': 'error',
|
|
'@devtools/prefer-assert-strict-equal': 'error',
|
|
'@devtools/prefer-sinon-assert': 'error',
|
|
'@devtools/prefer-url-string': 'error',
|
|
'@devtools/trace-engine-test-timeouts': 'error',
|
|
'@devtools/no-document-body-mutation': 'error',
|
|
'@devtools/enforce-custom-element-definitions-location': 'off',
|
|
'@devtools/enforce-custom-element-prefix': 'off',
|
|
},
|
|
|
|
settings: {
|
|
'mocha/additionalCustomNames': [
|
|
{
|
|
name: 'describeWithDevtoolsExtension',
|
|
type: 'suite',
|
|
interfaces: ['BDD', 'TDD'],
|
|
},
|
|
{
|
|
name: 'describeWithEnvironment',
|
|
type: 'suite',
|
|
interfaces: ['BDD', 'TDD'],
|
|
},
|
|
{
|
|
name: 'describeWithLocale',
|
|
type: 'suite',
|
|
interfaces: ['BDD', 'TDD'],
|
|
},
|
|
{
|
|
name: 'describeWithMockConnection',
|
|
type: 'suite',
|
|
interfaces: ['BDD', 'TDD'],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
name: 'Use private class members rule',
|
|
files: [
|
|
'front_end/panels/**/components/*.ts',
|
|
'front_end/ui/components/**/*.ts',
|
|
'front_end/entrypoints/**/*.ts',
|
|
],
|
|
|
|
rules: {
|
|
'@devtools/prefer-private-class-members': 'error',
|
|
},
|
|
},
|
|
{
|
|
name: 'Ignore private class members rule',
|
|
files: [
|
|
'front_end/panels/recorder/**/*.ts',
|
|
'front_end/ui/components/suggestion_input/*.ts',
|
|
],
|
|
rules: {
|
|
// TODO(crbug/1402569): Reenable once https://github.com/microsoft/TypeScript/issues/48885 is closed.
|
|
'@devtools/prefer-private-class-members': 'off',
|
|
},
|
|
},
|
|
{
|
|
name: 'Supported CSS properties rules',
|
|
files: ['front_end/generated/SupportedCSSProperties.js'],
|
|
rules: {
|
|
'@devtools/jslog-context-list': 'error',
|
|
},
|
|
},
|
|
{
|
|
name: 'EsLint rules test',
|
|
files: ['scripts/eslint_rules/tests/**/*'],
|
|
rules: {
|
|
'@eslint-plugin/no-only-tests': 'error',
|
|
},
|
|
},
|
|
{
|
|
name: 'Legacy test runner',
|
|
files: ['front_end/legacy_test_runner/**/*'],
|
|
rules: {
|
|
'@devtools/es-modules-import': 'off',
|
|
},
|
|
},
|
|
{
|
|
name: 'Front-end component docs',
|
|
files: ['front_end/ui/components/docs/**/*.ts', '**/*.docs.ts'],
|
|
rules: {
|
|
// This makes the component doc examples very verbose and doesn't add
|
|
// anything, so we leave return types to the developer within the
|
|
// component_docs folder.
|
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
// We use Lit to help render examples sometimes and we don't use
|
|
// {host: this} as often the `this` is the window.
|
|
'@devtools/lit-host-this': 'off',
|
|
'@devtools/no-imperative-dom-api': 'off',
|
|
'@devtools/no-lit-render-outside-of-view': 'off',
|
|
},
|
|
},
|
|
{
|
|
name: 'Keep models/trace isolated',
|
|
files: ['front_end/models/trace/**/*.ts'],
|
|
ignores: ['front_end/models/trace/**/*.test.ts'],
|
|
rules: {
|
|
'@devtools/no-imports-in-directory': [
|
|
'error',
|
|
{
|
|
bannedImportPaths: [
|
|
{
|
|
bannedPath: join(
|
|
import.meta.dirname,
|
|
'front_end',
|
|
'core',
|
|
'sdk',
|
|
'sdk.js',
|
|
),
|
|
allowTypeImports: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
name: 'Recorder injected code',
|
|
files: ['front_end/panels/recorder/injected/**/*.ts'],
|
|
rules: {
|
|
// The code is rolled up and tree-shaken independently from the regular entrypoints.
|
|
'@devtools/es-modules-import': 'off',
|
|
},
|
|
},
|
|
{
|
|
name: 'Performance panel file',
|
|
files: ['front_end/ui/legacy/components/perf_ui/**/*.ts'],
|
|
rules: {
|
|
// Enable tracking of canvas save() and
|
|
// restore() calls to try and catch bugs. Only
|
|
// enabled in this folder because it is an
|
|
// expensive rule to run and we do not need it
|
|
// for any code that doesn't use Canvas.
|
|
'@devtools/canvas-context-tracking': 'error',
|
|
},
|
|
},
|
|
{
|
|
name: 'TypeScript type-definitions',
|
|
files: ['**/*.d.ts'],
|
|
rules: {
|
|
// Not a useful rule for .d.ts files where we are
|
|
// representing an existing module.
|
|
'import/no-default-export': 'off',
|
|
},
|
|
},
|
|
{
|
|
name: 'Config files',
|
|
files: ['eslint.config.mjs', '**/*/rollup.config.mjs'],
|
|
rules: {
|
|
// The config operate on the default export
|
|
// So allow it for them
|
|
'import/no-default-export': 'off',
|
|
},
|
|
},
|
|
]);
|