Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(linting): Separate out framework and user linting config #11242

Merged
merged 1 commit into from
Aug 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 178 additions & 4 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const path = require('path')

const { findUp } = require('@redwoodjs/project-config')

// Framework Babel config is monorepo root ./babel.config.js
Expand All @@ -13,14 +11,33 @@ const findBabelConfig = (cwd = process.cwd()) => {
}

module.exports = {
extends: path.join(__dirname, 'packages/eslint-config/shared.js'),
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:prettier/recommended',
'plugin:jest-dom/recommended',
],
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 'latest',
babelOptions: {
configFile: findBabelConfig(),
},
},
settings: {
react: {
version: 'detect',
},
// For the import/order rule. Configures how it tells if an import is "internal" or not.
// An "internal" import is basically just one that's aliased.
//
// See...
// - https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#groups-array
// - https://github.com/import-js/eslint-plugin-import/blob/main/README.md#importinternal-regex
'import/internal-regex': '^src/',
},
ignorePatterns: [
'node_modules',
'dist',
'fixtures',
'packages/babel-config/src/plugins/__tests__/__fixtures__/**/*',
Expand All @@ -31,17 +48,174 @@ module.exports = {
'packages/core/config/storybook/**/*',
'packages/studio/dist-*/**/*',
],
plugins: ['unused-imports'],
plugins: [
'unused-imports',
'prettier',
'@babel',
'import',
'jsx-a11y',
'react',
'react-hooks',
'jest-dom',
'@redwoodjs',
],
rules: {
curly: 'error',
'unused-imports/no-unused-imports': 'error',
'@redwoodjs/process-env-computed': 'error',
'prettier/prettier': 'warn',
'no-console': 'off',
'prefer-object-spread': 'warn',
'prefer-spread': 'warn',
'no-unused-expressions': [
'error',
{ allowShortCircuit: true, allowTernary: true },
],
'no-useless-escape': 'off',
camelcase: ['warn', { properties: 'never' }],
'no-new': 'warn',
'new-cap': ['error', { newIsCap: true, capIsNew: false }],
'no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
// React rules
'react/prop-types': 'off',
'react/display-name': 'off',
'react-hooks/exhaustive-deps': 'warn',
'import/order': [
'error',
{
'newlines-between': 'always',
// We set this to an empty array to override the default value, which is `['builtin', 'external', 'object']`.
// Judging by the number of issues on the repo, this option seems to be notoriously tricky to understand.
// From what I can tell, if the value of this is `['builtin']` that means it won't sort builtins.
// But we have a rule for builtins below (react), so that's not what we want.
//
// See...
// - https://github.com/import-js/eslint-plugin-import/pull/1570
// - https://github.com/import-js/eslint-plugin-import/issues/1565
pathGroupsExcludedImportTypes: [],
// Only doing this to add internal. The order here maters.
// See https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md#groups-array
groups: [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index',
],
pathGroups: [
{
pattern: 'react',
group: 'builtin',
position: 'after',
},
{
pattern: '@redwoodjs/**',
group: 'external',
position: 'after',
},
{
// Matches...
// - src/directives/**/*.{js,ts}
// - src/services/**/*.{js,ts}
// - src/graphql/**/*.sdl.{js,ts}
//
// Uses https://github.com/isaacs/minimatch under the hood
// See https://github.com/isaacs/node-glob#glob-primer for syntax
// eslint-disable-next-line prettier/prettier
pattern: 'src/*/**/*.?(sdl.){js,ts}',
patternOptions: {
nobrace: true,
noglobstar: true,
},
group: 'internal',
position: 'before',
},
],
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
},
],
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['$api/*'],
message:
'Importing from $api is only supported in *.routeHooks.{js,ts} files',
},
],
},
],
},
env: {
// We use the most modern environment available. Then we rely on Babel to
// transpile it to something that can run on all node versions we support
es2022: true,
},
overrides: [
{
files: ['*.tsx', '*.js', '*.jsx'],
excludedFiles: ['api/src/**'],
rules: {
'react-hooks/rules-of-hooks': 'error',
},
},
{
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
extends: ['plugin:@typescript-eslint/recommended', 'prettier'],
rules: {
// TODO: look into enabling these eventually
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/prefer-function-type': 'off',

// Specific 'recommended' rules we alter
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-require-imports': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{ varsIgnorePattern: '^_', argsIgnorePattern: '^_' },
],
},
},
{
files: ['*.test.*', '**/__mocks__/**'],
env: {
node: true,
es6: true,
commonjs: true,
jest: true,
},
},
{
files: [
'.babelrc.js',
'babel.config.js',
'.eslintrc.js',
'*.config.js',
'jest.setup.js',
],
env: {
node: true,
commonjs: true,
jest: true,
},
},
{
files: [
'web/src/**/*.routeHooks.{js,ts}',
'web/src/entry.server.{jsx,tsx}',
],
rules: { 'no-restricted-imports': 'off' },
},
{
extends: ['plugin:@typescript-eslint/stylistic'],
files: ['*.ts', '*.tsx'],
Expand Down
Loading