@samitouri / QOS-React-2 / commits / b65e6fc58b

Revert [eprh] Remove hermes-parser (#34747)

Adds back HermesParser to eslint-plugin-react-hooks. There are still [external users of Flow](https://github.com/facebook/react/pull/34719#issuecomment-3368137743) using the plugin, so we shouldn't break the plugin for them. However, we still have the problem of double parsing: once from eslint (which we discard) and then another via babel/hermes parser. In the long run we should investigate a translation layer from estree to babel (or alternatively, update the compiler to take estree as input). But for now, I am reverting the PR. This does mean that [Sandpack in react.dev](https://github.com/reactjs/react.dev/blob/11cb6b591571caf5fa2a192117b6a6445c3f2027/src/components/MDX/Sandpack/runESLint.tsx#L31) cannot update to the latest eprh as HermesParser does not appear to be able to be run in a browser. I discovered this while trying to update eprh on react.dev last week, but didn't investigate deeply. I'll need to double check that again to find out more.

lauren committed Oct 6, 2025 at 12:43 UTC b65e6fc58b8c9a35e2c2ea7d1952fc1499cef09b
2 files changed +24 -8
packages/eslint-plugin-react-hooks/package.json
+1
@@ -41,6 +41,7 @@
41 "dependencies": {
42 "@babel/core": "^7.24.4",
43 "@babel/parser": "^7.24.4",
44 + "hermes-parser": "^0.25.1",
45 "zod": "^3.22.4 || ^4.0.0",
46 "zod-validation-error": "^3.0.3 || ^4.0.0"
47 },
packages/eslint-plugin-react-hooks/src/shared/RunReactCompiler.ts
+23 -8
@@ -17,6 +17,7 @@ import BabelPluginReactCompiler, {
17 LoggerEvent,
18 } from 'babel-plugin-react-compiler';
19 import type {SourceCode} from 'eslint';
20 +import * as HermesParser from 'hermes-parser';
21 import {isDeepStrictEqual} from 'util';
22 import type {ParseResult} from '@babel/parser';
23
@@ -113,14 +114,28 @@ function runReactCompilerImpl({
114 }
115
116 let babelAST: ParseResult<File> | null = null;
116 - try {
117 - babelAST = babelParse(sourceCode.text, {
118 - sourceFilename: filename,
119 - sourceType: 'unambiguous',
120 - plugins: ['typescript', 'jsx'],
121 - });
122 - } catch (err: unknown) {
123 - /* empty */
117 +
118 + if (filename.endsWith('.tsx') || filename.endsWith('.ts')) {
119 + try {
120 + babelAST = babelParse(sourceCode.text, {
121 + sourceFilename: filename,
122 + sourceType: 'unambiguous',
123 + plugins: ['typescript', 'jsx'],
124 + });
125 + } catch {
126 + /* empty */
127 + }
128 + } else {
129 + try {
130 + babelAST = HermesParser.parse(sourceCode.text, {
131 + babel: true,
132 + enableExperimentalComponentSyntax: true,
133 + sourceFilename: filename,
134 + sourceType: 'module',
135 + });
136 + } catch {
137 + /* empty */
138 + }
139 }
140
141 if (babelAST != null) {