go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/.eslintrc.js (about)

     1  // Copyright 2023 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // eslint-disable-next-line no-undef
    16  module.exports = {
    17    env: {
    18      browser: true,
    19      es2021: true,
    20    },
    21    plugins: ['react', '@typescript-eslint', 'prettier', 'jsx-a11y', 'import'],
    22    extends: [
    23      'eslint:recommended',
    24      'plugin:react/recommended',
    25      'plugin:react/jsx-runtime',
    26      'plugin:react-hooks/recommended',
    27      'google',
    28      'plugin:@typescript-eslint/recommended',
    29      'plugin:import/recommended',
    30      'plugin:import/typescript',
    31      'plugin:jsx-a11y/recommended',
    32      // "plugin:prettier/recommended" needs to be added last because it needs to
    33      // disable rules that are incompatible with the prettier.
    34      'plugin:prettier/recommended',
    35    ],
    36    settings: {
    37      react: {
    38        version: 'detect',
    39      },
    40      'import/parsers': {
    41        '@typescript-eslint/parser': ['.ts', '.tsx'],
    42      },
    43      'import/resolver': {
    44        typescript: {},
    45      },
    46    },
    47    parser: '@typescript-eslint/parser',
    48    parserOptions: {
    49      ecmaFeatures: {
    50        jsx: true,
    51      },
    52      ecmaVersion: 'latest',
    53      sourceType: 'module',
    54    },
    55    rules: {
    56      '@typescript-eslint/no-unused-vars': [
    57        'error',
    58        {
    59          // Use cases:
    60          // - declare a function property with a default value
    61          // - ignore some function parameters when writing a callback function
    62          // See http://b/182855639.
    63          argsIgnorePattern: '^_',
    64          // Use cases:
    65          // - explicitly ignore some elements from a destructed array
    66          // - explicitly ignore some inferred type parameters
    67          // See http://b/182855639.
    68          varsIgnorePattern: '^_',
    69        },
    70      ],
    71  
    72      // Code generated from protobuf may contain '_' in the identifier name,
    73      // (e.g. `BuilderMask_BuilderMaskType`) and therefore triggering the error.
    74      // `"ignoreImports": true` doesn't fix the issue because checks are still
    75      // applied where the imported symbol is used.
    76      //
    77      // Since this rule doesn't add a lot of value (it only checks whether there
    78      // are '_' in non-leading/trailing positions), disable it to reduce noise.
    79      //
    80      // Note that we should still generally use camelcase.
    81      camelcase: 0,
    82  
    83      // `==` may perform type conversion in some cases and is unintuitive.
    84      eqeqeq: ['error', 'always'],
    85  
    86      // We need to import Lit component definition file separately as a
    87      // side-effect (e.g. `import './a_component'`) because type-only imports
    88      // (e.g. `import { AComponent } from './a_component'`) may get optimized
    89      // away by the bundler.
    90      'import/no-duplicates': 0,
    91  
    92      // See https://vitejs.dev/guide/api-plugin.html#virtual-modules-convention.
    93      'import/no-unresolved': ['error', { ignore: ['^virtual:'] }],
    94  
    95      // Group internal dependencies together.
    96      'import/order': [
    97        'error',
    98        {
    99          pathGroups: [
   100            {
   101              pattern: '@root/**',
   102              group: 'external',
   103              position: 'after',
   104            },
   105            {
   106              pattern: '@/**',
   107              group: 'external',
   108              position: 'after',
   109            },
   110          ],
   111          alphabetize: {
   112            order: 'asc',
   113            orderImportKind: 'asc',
   114          },
   115          'newlines-between': 'always',
   116        },
   117      ],
   118  
   119      'no-restricted-imports': [
   120        'error',
   121        {
   122          patterns: [
   123            {
   124              group: ['lodash-es'],
   125              importNames: ['chain'],
   126              message: '`chain` from `lodash-es` does not work with tree-shaking',
   127            },
   128            {
   129              group: ['lodash-es/chain'],
   130              importNames: ['default'],
   131              message: '`chain` from `lodash-es` does not work with tree-shaking',
   132            },
   133            // Ban the use of `useSearchParams` because it may accidentally
   134            // override search params when updater pattern is used.
   135            {
   136              group: ['react-router-dom'],
   137              importNames: ['useSearchParams'],
   138              message: 'use `useSyncedSearchParams` instead',
   139            },
   140          ],
   141        },
   142      ],
   143  
   144      // Generated protobuf types could be very long (e.g.
   145      // `ClusterResponse_ClusteredTestResult_ClusterEntry`). Set a high max-len
   146      // so we don't need to disable this rule whenever those long types are used.
   147      //
   148      // Note that the prettier will still try to reformat the code into 80 cols
   149      // when appropriate. And we should generally fit our code in 80 cols too.
   150      'max-len': [
   151        'error',
   152        { code: 140, ignoreUrls: true, ignoreRegExpLiterals: true },
   153      ],
   154  
   155      // Ban `console.log` to encourage displaying message via DOM and prevent
   156      // debugging statements from being accidentally left in the codebase.
   157      // `console.error/warn` is still useful for error reporting from our users
   158      // (most of them know how to work with the browser dev console). But they
   159      // should be accessed via `@/common/tools/logging`.
   160      'no-console': ['error'],
   161  
   162      // Modify the prettier config to make it match the eslint rule from other
   163      // presets better.
   164      'prettier/prettier': [
   165        'error',
   166        {
   167          singleQuote: true,
   168        },
   169      ],
   170  
   171      // Ban the usage of `dangerouslySetInnerHTML`.
   172      //
   173      // Note that this rule does not catch the usage of `dangerouslySetInnerHTML`
   174      // in non-native components [1].
   175      // [1]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3434
   176      'react/no-danger': ['error'],
   177  
   178      // See https://emotion.sh/docs/eslint-plugin-react.
   179      'react/no-unknown-property': ['error', { ignore: ['css'] }],
   180  
   181      // JSDoc related rules are deprecated [1].
   182      // Also with TypeScript, a lot of the JSDoc are unnecessary.
   183      // [1]: https://eslint.org/blog/2018/11/jsdoc-end-of-life/
   184      'require-jsdoc': 0,
   185      'valid-jsdoc': 0,
   186    },
   187    overrides: [
   188      {
   189        files: ['src/**/*.test.ts', 'src/**/*.test.tsx'],
   190        plugins: ['jest'],
   191        extends: ['plugin:jest/recommended'],
   192      },
   193      {
   194        files: ['src/**/*.test.ts', 'src/**/*.test.tsx', '**/testing_tools/**'],
   195        rules: {
   196          // Allow assertion to make it easier to write test cases.
   197          // All incorrect assertion will be caught during test execution anyway.
   198          '@typescript-eslint/no-non-null-assertion': 0,
   199  
   200          // It's very common to use an empty mock implementation in tests.
   201          '@typescript-eslint/no-empty-function': 0,
   202  
   203          // Don't need to restrict imports in test files.
   204          'no-restricted-imports': 0,
   205        },
   206      },
   207    ],
   208  };