-
Notifications
You must be signed in to change notification settings - Fork 294
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(eslint): upgrade eslint to v9 (#2716)
<!-- How to write a good PR title: - Start with a verb, for example: Add, Delete, Improve, Fix… - Give as much context as necessary and as little as possible --> ### WHY are these changes introduced? Fixes #191 <!-- Context about the problem that this PR is addressing. If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered. --> ### WHAT is this pull request doing? This PR: - upgrades eslint to v9 and its corresponding plugins, packages and configs - removes individual eslint from all of our packages, except `templates/skeleton` - unifies our basic lint configuation to be in the root of the monorepo (it was empty until now) - fixes our `lint-staged` script to run on the changed files - removes deprecated dependencies of remix-run lint plugin and hydrogen lint plugin (not maintained) ### The relevant files in the PR are: - **eslint.config.js** - this is the base eslint config for linting our codebase - **templates/skeleton/eslint.config.js** - this is the skeleton-specific configuration, and it can be removed by the skeleton users if they want. - the rest are (stylistic only) lint fixes I tried to find the best subset of rules so that we will be able to have even minimal linting over our codebase, but at the same time not to flood many warnings over packages that weren't linted until now. If in the future we will want to add/enable a new rule, we can do it and fix its errors. <!-- ℹ️ Delete the following for small / trivial changes --> ### HOW to test your changes? 1. `npm i && npm run lint` from the root folder 2. `npm i && npm run lint` from the `templates/skeleton` folder #### Checklist - [x] I've read the [Contributing Guidelines](https://github.com/Shopify/hydrogen/blob/main/CONTRIBUTING.md) - [x] I've considered possible cross-platform impacts (Mac, Linux, Windows) - [x] I've added a [changeset](https://github.com/Shopify/hydrogen/blob/main/CONTRIBUTING.md#changesets) if this PR contains user-facing or noteworthy changes - [ ] I've added [tests](https://github.com/Shopify/hydrogen/blob/main/CONTRIBUTING.md#testing) to cover my changes - [ ] I've added or updated the documentation <!-- THANK YOU for your pull request! Members from the Hydrogen team will review these changes and provide feedback as soon as they are available. -->
- Loading branch information
Showing
57 changed files
with
2,651 additions
and
2,290 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'@shopify/hydrogen-react': patch | ||
'skeleton': patch | ||
'@shopify/hydrogen': patch | ||
--- | ||
|
||
Upgrade eslint to version 9 and unify eslint config across all packages (with the exception of the skeleton, which still keeps its own config) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,318 @@ | ||
const {fixupConfigRules, fixupPluginRules} = require('@eslint/compat'); | ||
const js = require('@eslint/js'); | ||
const {FlatCompat} = require('@eslint/eslintrc'); | ||
const eslintComments = require('eslint-plugin-eslint-comments'); | ||
const react = require('eslint-plugin-react'); | ||
const reactHooks = require('eslint-plugin-react-hooks'); | ||
const jsxA11Y = require('eslint-plugin-jsx-a11y'); | ||
const tsdoc = require('eslint-plugin-tsdoc'); | ||
const jest = require('eslint-plugin-jest'); | ||
const simpleImportSort = require('eslint-plugin-simple-import-sort'); | ||
const tsParser = require('@typescript-eslint/parser'); | ||
const globals = require('globals'); | ||
|
||
const compat = new FlatCompat({ | ||
baseDirectory: __dirname, | ||
recommendedConfig: js.configs.recommended, | ||
allConfig: js.configs.all, | ||
}); | ||
|
||
const lintedTSPackages = [ | ||
'packages/hydrogen-react', | ||
'examples/express', | ||
'templates/skeleton', | ||
'docs/previews', | ||
]; | ||
|
||
module.exports = [ | ||
// Global ignores | ||
{ | ||
ignores: [ | ||
'**/node_modules/', | ||
'**/build/', | ||
'**/*.graphql.d.ts', | ||
'**/*.graphql.ts', | ||
'**/storefront-api-types.d.ts', | ||
'**/customer-account-api-types.d.ts', | ||
'**/codegen.ts', | ||
'**/dist/**/*', | ||
'**/coverage/**/*', | ||
'**/docs/**/*', | ||
'**/.eslintrc.cjs', | ||
'**/src/**/*.example.tsx', | ||
'**/src/**/*.example.ts', | ||
'**/src/**/*.example.jsx', | ||
'**/src/**/*.example.js', | ||
'**/eslint.config.cjs', | ||
'**/scripts/**/*', | ||
'bin/', | ||
'*.d.ts', | ||
'**/codegen.ts', | ||
'**/vite.config.ts', | ||
'**/vitest.setup.ts', | ||
'**/vitest.config.ts', | ||
'**/tsup.config.ts', | ||
'**/src/storefront-api-response.types.ts', | ||
'**/storefrontapi.generated.d.ts', | ||
], | ||
}, | ||
|
||
// Base configurations | ||
...fixupConfigRules( | ||
compat.extends( | ||
'plugin:node/recommended', | ||
'plugin:import/recommended', | ||
'plugin:import/typescript', | ||
'eslint:recommended', | ||
'plugin:eslint-comments/recommended', | ||
'plugin:react/recommended', | ||
'plugin:react-hooks/recommended', | ||
), | ||
), | ||
|
||
// Core configuration with plugins and general rules | ||
{ | ||
plugins: { | ||
'eslint-comments': fixupPluginRules(eslintComments), | ||
react: fixupPluginRules(react), | ||
'react-hooks': fixupPluginRules(reactHooks), | ||
'jsx-a11y': fixupPluginRules(jsxA11Y), | ||
}, | ||
settings: { | ||
'import/resolvers': { | ||
typescript: { | ||
project: [ | ||
'packages/*/tsconfig.json', | ||
'templates/*/tsconfig.json', | ||
'examples/*/tsconfig.json', | ||
'docs/*/tsconfig.json', | ||
], | ||
}, | ||
}, | ||
react: {version: 'detect'}, | ||
jest: {version: 28}, | ||
}, | ||
languageOptions: { | ||
parser: tsParser, | ||
parserOptions: { | ||
ecmaFeatures: {jsx: true}, | ||
}, | ||
globals: { | ||
...globals.browser, | ||
...globals.node, | ||
}, | ||
ecmaVersion: 2020, | ||
sourceType: 'module', | ||
}, | ||
linterOptions: { | ||
reportUnusedDisableDirectives: false, | ||
}, | ||
rules: { | ||
// React rules | ||
'react/display-name': 'off', | ||
'react/no-array-index-key': 'warn', | ||
'react/prop-types': 'off', | ||
'react/react-in-jsx-scope': 'off', | ||
'react/no-children-prop': 'off', | ||
'react/no-unescaped-entities': 'off', | ||
'react/jsx-no-target-blank': 'off', | ||
'react-hooks/exhaustive-deps': 'error', | ||
|
||
// Node rules | ||
'node/shebang': 'off', | ||
'node/no-unpublished-require': 'off', | ||
'node/no-unsupported-features/es-syntax': 'off', | ||
'node/no-missing-import': 'off', | ||
'node/no-extraneous-import': 'off', | ||
'node/no-unpublished-import': 'off', | ||
'node/no-unsupported-features/es-builtins': [ | ||
'error', | ||
{version: '>=14.0.0', ignores: []}, | ||
], | ||
'node/no-unsupported-features/node-builtins': [ | ||
'error', | ||
{version: '>=14.0.0', ignores: []}, | ||
], | ||
|
||
// TypeScript rules | ||
'@typescript-eslint/ban-ts-comment': 'off', | ||
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off', | ||
|
||
// General rules | ||
'object-shorthand': ['error', 'always', {avoidQuotes: true}], | ||
'prefer-const': ['warn', {destructuring: 'all'}], | ||
'no-prototype-builtins': 'off', | ||
'no-use-before-define': 'off', | ||
'no-warning-comments': 'off', | ||
'no-empty': 'off', | ||
'no-control-regex': 'off', | ||
'no-async-promise-executor': 'off', | ||
'eslint-comments/no-unused-disable': 'off', | ||
'jest/no-disabled-tests': 'off', | ||
'jest/no-export': 'off', | ||
'no-console': 'off', | ||
'no-ex-assign': 'off', | ||
'no-constant-condition': 'off', | ||
'no-useless-escape': 'off', | ||
'no-case-declarations': 'off', | ||
'no-process-exit': 'off', | ||
|
||
// Import rules | ||
'import/extensions': 'off', | ||
'import/no-unresolved': 'off', | ||
}, | ||
}, | ||
|
||
// Test files configuration | ||
...compat.extends('plugin:jest/recommended').map((config) => ({ | ||
...config, | ||
files: ['**/*.test.*'], | ||
})), | ||
{ | ||
files: ['**/*.test.*'], | ||
plugins: {jest}, | ||
languageOptions: { | ||
globals: { | ||
...globals.node, | ||
...globals.jest, | ||
}, | ||
}, | ||
}, | ||
|
||
// TypeScript files configuration | ||
{ | ||
files: ['**/*.ts', '**/*.tsx'], | ||
settings: { | ||
'import/resolvers': { | ||
typescript: { | ||
project: [ | ||
'packages/*/tsconfig.json', | ||
'templates/*/tsconfig.json', | ||
'examples/*/tsconfig.json', | ||
'docs/*/tsconfig.json', | ||
], | ||
}, | ||
}, | ||
}, | ||
languageOptions: { | ||
parser: tsParser, | ||
parserOptions: { | ||
projectService: true, | ||
tsconfigRootDir: __dirname, | ||
ecmaFeatures: {jsx: true}, | ||
}, | ||
}, | ||
rules: { | ||
'no-unused-vars': 'off', | ||
'no-undef': 'off', | ||
'prefer-const': 'off', | ||
}, | ||
}, | ||
|
||
// Server files configuration | ||
{ | ||
files: ['**/*.server.*'], | ||
rules: { | ||
'react-hooks/rules-of-hooks': 'off', | ||
}, | ||
}, | ||
|
||
// Linted TypeScript packages configuration | ||
{ | ||
files: [ | ||
...lintedTSPackages.flatMap((pkg) => [ | ||
`${pkg}/**/*.ts`, | ||
`${pkg}/**/*.tsx`, | ||
]), | ||
], | ||
rules: { | ||
'no-undef': 'off', | ||
'no-unused-vars': 'off', | ||
'tsdoc/syntax': 'error', | ||
'react/jsx-no-target-blank': 'error', | ||
'node/no-extraneous-import': [ | ||
'error', | ||
{ | ||
allowModules: [ | ||
'@shopify/hydrogen', | ||
'@shopify/react-testing', | ||
'@remix-run/web-fetch', | ||
'@total-typescript/ts-reset', | ||
], | ||
}, | ||
], | ||
'node/no-extraneous-require': [ | ||
'error', | ||
{ | ||
allowModules: ['@shopify/hydrogen'], | ||
}, | ||
], | ||
}, | ||
plugins: {tsdoc}, | ||
}, | ||
|
||
// TypeScript strict configuration for linted packages | ||
...fixupConfigRules( | ||
compat.extends( | ||
'plugin:@typescript-eslint/eslint-recommended', | ||
'plugin:@typescript-eslint/recommended', | ||
'plugin:@typescript-eslint/recommended-requiring-type-checking', | ||
'plugin:jsx-a11y/recommended', | ||
), | ||
).map((config) => ({ | ||
...config, | ||
files: [ | ||
...lintedTSPackages.flatMap((pkg) => [ | ||
`${pkg}/**/*.ts`, | ||
`${pkg}/**/*.tsx`, | ||
]), | ||
], | ||
languageOptions: { | ||
parser: tsParser, | ||
parserOptions: { | ||
projectService: true, | ||
tsconfigRootDir: __dirname, | ||
ecmaFeatures: {jsx: true}, | ||
}, | ||
}, | ||
rules: { | ||
'jsx-a11y/control-has-associated-label': 'off', | ||
'jsx-a11y/label-has-for': 'off', | ||
'@typescript-eslint/explicit-function-return-type': 'off', | ||
}, | ||
})), | ||
|
||
// Example files configuration | ||
{ | ||
files: [ | ||
'**/*.example.ts', | ||
'**/*.example.js', | ||
'**/*.example.tsx', | ||
'**/*.example.jsx', | ||
], | ||
rules: { | ||
'node/no-extraneous-import': 'off', | ||
'node/no-extraneous-require': 'off', | ||
'no-unused-vars': 'off', | ||
'no-undef': 'off', | ||
'import/no-duplicates': 'off', | ||
'react-hooks/exhaustive-deps': 'off', | ||
'prefer-const': 'off', | ||
'import/no-named-as-default': 'off', | ||
'node/no-missing-require': 'off', | ||
}, | ||
}, | ||
|
||
// Index files configuration | ||
{ | ||
files: ['**/src/index.ts'], | ||
plugins: {'simple-import-sort': simpleImportSort}, | ||
rules: {'simple-import-sort/exports': 'error'}, | ||
}, | ||
|
||
// Hydrogen package configuration | ||
{ | ||
files: ['packages/hydrogen/**/*.tsx', 'packages/hydrogen/**/*.ts'], | ||
rules: {'react-hooks/exhaustive-deps': 'off'}, | ||
}, | ||
]; |
Oops, something went wrong.