aspect-build / bazel-examples

Bazel examples
https://aspect.build
Apache License 2.0
106 stars 70 forks source link

How do we configure eslint binary for TypeScript projects #190

Closed tetsuok closed 1 year ago

tetsuok commented 1 year ago

I see there are three examples that define eslint_bin.eslint_test targets in this repo, but it is not trivial for me how to define eslint_bin.eslint_binary so that users can run the binary for TypeScript projects, using tsconfig.json and eslint config files that specify the tsconfig.json file in the parserOptions.project. It would be nice to have an example how to set up the eslint binary target.

I've been trying to figure it out by modifying the react-cra example. Below is local changes I have in my machine:

diff --git a/react-cra/.eslintrc.js b/react-cra/.eslintrc.js
new file mode 100644
index 0000000..2ab94f0
--- /dev/null
+++ b/react-cra/.eslintrc.js
@@ -0,0 +1,12 @@
+module.exports = {
+  extends: [
+    "react-app",
+    //"plugin:@typescript-eslint/recommended",
+  ],
+  parser: '@typescript-eslint/parser',
+  parserOptions: {
+    tsconfigRootDir: __dirname,
+    project: ['tsconfig.json'],
+  },
+  root: true,
+};
diff --git a/react-cra/BUILD.bazel b/react-cra/BUILD.bazel
index bd181cc..c6817ac 100644
--- a/react-cra/BUILD.bazel
+++ b/react-cra/BUILD.bazel
@@ -57,3 +57,9 @@ js_library(
     srcs = ["jest.config.js"],
     visibility = ["//visibility:public"],
 )
+
+js_library(
+    name = "eslintrc",
+    srcs = [".eslintrc.js"],
+    visibility = ["//visibility:public"],
+)
diff --git a/react-cra/src/BUILD.bazel b/react-cra/src/BUILD.bazel
index dd1705a..a4a86c9 100644
--- a/react-cra/src/BUILD.bazel
+++ b/react-cra/src/BUILD.bazel
@@ -83,3 +83,20 @@ eslint_bin.eslint_test(
         "//:node_modules/eslint-config-react-app",
     ] + glob(SRC_PATTERNS),
 )
+
+eslint_bin.eslint_binary(
+    name = "eslint_bin",
+    args = [
+        "--config $(location //:eslintrc)",
+        "--no-eslintrc",
+        "--ext .ts,.tsx",
+    ],
+    data = [
+        "//:eslintrc",
+        "//:node_modules/@typescript-eslint/eslint-plugin",
+        "//:node_modules/@typescript-eslint/parser",
+        "//:node_modules/eslint-config-react-app",
+        "//:package_json",
+        "//:tsconfig",
+    ],
+)

Below is the errors when I run the target src:eslint_bin

$ cd react-cra
$ bazel run src:eslint_bin -- $PWD/src
INFO: Analyzed target //src:eslint_bin (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //src:eslint_bin up-to-date:
  bazel-bin/src/eslint_bin.sh
INFO: Elapsed time: 0.111s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Running command line: bazel-bin/src/eslint_bin.sh --config ./.eslintrc.js --no-eslintrc --ext .ts,.tsx /Volumes/work/github/bazel-examples/react-cra/src
INFO: Build completed successfully, 1 total action

/Volumes/work/github/bazel-examples/react-cra/src/App.test.tsx
  0:0  error  Parsing error: ESLint was configured to run on `<tsconfigRootDir>/../../../../../../../../../../../../../Volumes/work/github/bazel-examples/react-cra/src/App.test.tsx` using `parserOptions.project`: <tsconfigRootDir>/tsconfig.json
However, that TSConfig does not include this file. Either:
- Change ESLint's list of included files to not include this file
- Change that TSConfig to include this file
- Create a new TSConfig that includes this file and include it in your parserOptions.project
See the TypeScript ESLint docs for more info: https://typescript-eslint.io/docs/linting/troubleshooting##i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file

/Volumes/work/github/bazel-examples/react-cra/src/App.tsx
  0:0  error  Parsing error: ESLint was configured to run on `<tsconfigRootDir>/../../../../../../../../../../../../../Volumes/work/github/bazel-examples/react-cra/src/App.tsx` using `parserOptions.project`: <tsconfigRootDir>/tsconfig.json
However, that TSConfig does not include this file. Either:
- Change ESLint's list of included files to not include this file
- Change that TSConfig to include this file
- Create a new TSConfig that includes this file and include it in your parserOptions.project
See the TypeScript ESLint docs for more info: https://typescript-eslint.io/docs/linting/troubleshooting##i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file

/Volumes/work/github/bazel-examples/react-cra/src/custom.d.ts
  0:0  error  Parsing error: ESLint was configured to run on `<tsconfigRootDir>/../../../../../../../../../../../../../Volumes/work/github/bazel-examples/react-cra/src/custom.d.ts` using `parserOptions.project`: <tsconfigRootDir>/tsconfig.json
However, that TSConfig does not include this file. Either:
- Change ESLint's list of included files to not include this file
- Change that TSConfig to include this file
- Create a new TSConfig that includes this file and include it in your parserOptions.project
See the TypeScript ESLint docs for more info: https://typescript-eslint.io/docs/linting/troubleshooting##i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file

/Volumes/work/github/bazel-examples/react-cra/src/index.tsx
  0:0  error  Parsing error: ESLint was configured to run on `<tsconfigRootDir>/../../../../../../../../../../../../../Volumes/work/github/bazel-examples/react-cra/src/index.tsx` using `parserOptions.project`: <tsconfigRootDir>/tsconfig.json
However, that TSConfig does not include this file. Either:
- Change ESLint's list of included files to not include this file
- Change that TSConfig to include this file
- Create a new TSConfig that includes this file and include it in your parserOptions.project
See the TypeScript ESLint docs for more info: https://typescript-eslint.io/docs/linting/troubleshooting##i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file

/Volumes/work/github/bazel-examples/react-cra/src/reportWebVitals.ts
  0:0  error  Parsing error: ESLint was configured to run on `<tsconfigRootDir>/../../../../../../../../../../../../../Volumes/work/github/bazel-examples/react-cra/src/reportWebVitals.ts` using `parserOptions.project`: <tsconfigRootDir>/tsconfig.json
However, that TSConfig does not include this file. Either:
- Change ESLint's list of included files to not include this file
- Change that TSConfig to include this file
- Create a new TSConfig that includes this file and include it in your parserOptions.project
See the TypeScript ESLint docs for more info: https://typescript-eslint.io/docs/linting/troubleshooting##i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file

✖ 5 problems (5 errors, 0 warnings)
tetsuok commented 1 year ago

I'd like to define the binary target to apply auto fix using the eslint's --fix option. I want to avoid installing eslint using package managers such as npm or pnpm.

gregmagolan commented 1 year ago

eslint is a tricky one; this thread on Bazel slack may help https://bazelbuild.slack.com/archives/CEZUUKQ6P/p1677122456932899

tetsuok commented 1 year ago

@gregmagolan Thanks for the info, I'll take a look!

alexeagle commented 1 year ago

My plan for this is to make first-class support for eslint (with TypeScript of course) under https://github.com/aspect-build/rules_lint Come chat with us in slack.bazel.build in the #linting-wg channel if you'd like to get involved :)