Skip to content

Commit a37d32d

Browse files
authored
[Monorepo] Setup linters (#3503)
## Description This PR sets up `eslint`, `prettier` and `tsc` so that we can finally run lint checks in monorepo. Each workspace has `ts-check` and `lint-js` scripts which run in given workspace. Running those scripts in `root` results in running them in each workspace. > [!NOTE] > Running those scripts from `root` does not trigger any checks in `ExpoExample` and `MacOSExample`, as they only export app from `CommonApp` ## Test plan Run `yarn ts-check` and `yarn lint-js` from `root`.
1 parent dce6945 commit a37d32d

53 files changed

Lines changed: 800 additions & 1111 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.json

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"root": true,
23
"extends": [
34
"plugin:@typescript-eslint/recommended",
45
"plugin:@typescript-eslint/recommended-requiring-type-checking",
@@ -15,7 +16,7 @@
1516
"project": ["./tsconfig.json"]
1617
},
1718
"env": { "browser": true, "node": true, "jest/globals": true },
18-
"plugins": ["jest"],
19+
"plugins": ["react", "jest"],
1920
"ignorePatterns": ["packages/react-native-gesture-handler/lib/**/*"],
2021
"rules": {
2122
// removed in new jest-eslint-plugin, referenced in satya config
@@ -26,19 +27,28 @@
2627
"warn",
2728
{ "assertFunctionNames": ["expect*", "assert*"] }
2829
],
30+
"jest/no-conditional-expect": "warn",
31+
2932
// temporary, remove after we type internals better
3033
"@typescript-eslint/restrict-template-expressions": "warn",
3134
"@typescript-eslint/no-unsafe-member-access": "warn",
3235
"@typescript-eslint/no-unsafe-call": "warn",
3336
"@typescript-eslint/no-unsafe-assignment": "warn",
37+
"@typescript-eslint/no-unsafe-argument": "warn",
3438
"@typescript-eslint/no-unsafe-return": "warn",
39+
"@typescript-eslint/no-non-null-assertion": "warn",
3540
"@typescript-eslint/ban-types": "warn",
3641

3742
// common
3843
"@typescript-eslint/explicit-module-boundary-types": "off",
3944
"import/named": "off",
4045
"react/sort-comp": "off",
4146
"react/no-unused-prop-types": "warn",
47+
"react-hooks/exhaustive-deps": "warn",
48+
"@typescript-eslint/no-floating-promises": "warn",
49+
"@eslint-react/no-missing-component-display-name": "warn",
50+
"@eslint-react/no-nested-components": "warn",
51+
"@eslint-react/no-nested-component-definitions": "warn",
4252
"prefer-const": [
4353
"error",
4454
{
@@ -49,6 +59,13 @@
4959
"error",
5060
{ "argsIgnorePattern": "^_" }
5161
],
62+
"@typescript-eslint/no-explicit-any": "warn",
63+
"@typescript-eslint/no-redundant-type-constituents": "warn",
64+
"@typescript-eslint/no-empty-function": "error",
65+
"@typescript-eslint/no-misused-promises": "warn",
66+
"@eslint-react/no-array-index-key": "warn",
67+
"@eslint-react/hooks-extra/no-direct-set-state-in-use-effect": "warn",
68+
"@eslint-react/hooks-extra/prefer-use-state-lazy-initialization": "warn",
5269
"no-redeclare": "off",
5370
"@typescript-eslint/no-redeclare": "error",
5471
"no-use-before-define": "off",
@@ -61,6 +78,7 @@
6178
}
6279
],
6380
"curly": "error",
64-
"spaced-comment": "error"
81+
"spaced-comment": "error",
82+
"no-alert": "warn"
6583
}
6684
}

.github/workflows/android-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
cache: 'yarn'
3535
- name: Install node dependencies
3636
working-directory: ${{ matrix.working-directory }}
37-
run: yarn install --immutable && yarn postinstall
37+
run: yarn install --immutable
3838
- name: Build app
3939
working-directory: ${{ matrix.working-directory }}/android
4040
run: ./gradlew assembleDebug --console=plain -PreactNativeArchitectures=arm64-v8a

.github/workflows/ios-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
cache: 'yarn'
3737
- name: Install node dependencies
3838
working-directory: ${{ matrix.working-directory }}
39-
run: yarn install --immutable && yarn postinstall
39+
run: yarn install --immutable
4040
- name: Install pods
4141
if: ${{ matrix.working-directory == 'apps/BasicExample' }}
4242
working-directory: ${{ matrix.working-directory }}/ios

.github/workflows/static-example-apps-checks.yml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,11 @@ jobs:
2626
with:
2727
node-version: 18
2828
cache: 'yarn'
29-
- name: Install root node dependencies
30-
run: yarn --immutable && yarn prepare
31-
- name: Install ${{ matrix.working-directory }} app node dependencies
32-
working-directory: ${{ matrix.working-directory }}
33-
run: yarn
29+
- name: Install node dependencies
30+
run: yarn --immutable && yarn postinstall
3431
- name: Check types
3532
working-directory: ${{ matrix.working-directory }}
36-
run: yarn tsc --noEmit
33+
run: yarn ts-check
3734
- name: Lint
3835
working-directory: ${{ matrix.working-directory }}
39-
run: yarn lint-check
36+
run: yarn lint-js

.github/workflows/static-root-checks.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ jobs:
2626
node-version: 18
2727
cache: 'yarn'
2828
- name: Install node dependencies
29-
run: yarn
29+
run: yarn --immutable && yarn postinstall
3030
- name: Check types
3131
working-directory: ${{ env.WORKING_DIRECTORY }}
32-
run: yarn tsc --noEmit
32+
run: yarn ts-check
3333
- name: Lint
3434
working-directory: ${{ env.WORKING_DIRECTORY }}
35-
run: yarn lint:js-root
35+
run: yarn lint-js
3636
- name: Check for circular dependencies
3737
working-directory: ${{ env.WORKING_DIRECTORY }}
3838
run: yarn circular-dependency-check

.lintstagedrc.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
{
2-
"*.(js|jsx|ts|tsx)": ["yarn eslint", "yarn prettier --write"]
2+
"**/*.{ts,tsx}": "yarn format:js",
3+
"packages/react-native-gesture-handler/android/**/*.kt": "yarn format:android",
4+
"packages/react-native-gesture-handler/apple/**/*.{h,m,mm,cpp}": "yarn format:apple",
5+
"packages/react-native-gesture-handler/src/specs/*.ts": "yarn sync-architectures"
36
}

apps/BasicExample/.eslintrc.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

apps/BasicExample/package.json

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"lint": "eslint .",
99
"start": "react-native start",
1010
"test": "jest",
11-
"postinstall": ""
11+
"ts-check": "yarn tsc --noEmit",
12+
"lint-js": "eslint --ext '.js,.ts,.tsx' src/ && yarn prettier --check './src/**/*.{js,jsx,ts,tsx}'",
13+
"format-js": "prettier --write --list-different './src/**/*.{js,jsx,ts,tsx}'"
1214
},
1315
"dependencies": {
1416
"react": "19.0.0",
@@ -27,13 +29,20 @@
2729
"@react-native/metro-config": "0.79.0",
2830
"@react-native/typescript-config": "0.79.0",
2931
"@types/jest": "^29.5.13",
30-
"@types/react": "^19.0.0",
32+
"@types/react": "^19.0.12",
3133
"@types/react-test-renderer": "^19.0.0",
32-
"eslint": "^8.19.0",
34+
"@typescript-eslint/eslint-plugin": "^6.9.0",
35+
"@typescript-eslint/parser": "^6.9.0",
36+
"eslint": "^8.57.0",
37+
"eslint-config-satya164": "3.3.0",
38+
"eslint-import-resolver-babel-module": "^5.2.0",
39+
"eslint-plugin-jest": "27.4.3",
40+
"eslint-plugin-prettier": "^5.0.1",
41+
"eslint-plugin-react": "^7.37.5",
3342
"jest": "^29.6.3",
34-
"prettier": "2.8.8",
43+
"prettier": "3.3.3",
3544
"react-test-renderer": "19.0.0",
36-
"typescript": "5.0.4"
45+
"typescript": "~5.8.3"
3746
},
3847
"engines": {
3948
"node": ">=18"

apps/BasicExample/src/Navigator.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable react-native/no-inline-styles */
21
import React, { useEffect, useState } from 'react';
32
import { View, Text, Pressable, BackHandler } from 'react-native';
43

@@ -55,7 +54,7 @@ export default class Navigator {
5554

5655
goBack() {
5756
if (this.history.length === 1) {
58-
throw "Can't go back, no history";
57+
throw new Error("Can't go back, no history");
5958
}
6059
this.history.pop();
6160
this.setCurrentRoute(this.history[this.history.length - 1]);
@@ -79,6 +78,7 @@ export default class Navigator {
7978
this.setCurrentRoute = setCurrentRoute;
8079

8180
useEffect(() => {
81+
// eslint-disable-next-line @typescript-eslint/unbound-method
8282
return BackHandler.addEventListener('hardwareBackPress', this.backHandler)
8383
.remove;
8484
}, []);

apps/CommonApp/.eslintrc.js

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)