Commit Graph

39 Commits

Author SHA1 Message Date
Joseph Savona
88b40f6e41
Enable ref validation in linter (#34044)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34044).
* #34027
* __->__ #34044
2025-07-29 12:30:29 -07:00
lauren
7ee7571212
[compiler] Enable validateNoVoidUseMemo in eslint & playground (#34022)
Enables `validateNoVoidUseMemo` by default only in eslint (it defaults
to false otherwise) as well as the playground.
2025-07-28 13:42:14 -04:00
Joseph Savona
7f510554ad
[compiler] Cleanup diagnostic messages (#33765)
Minor sytlistic cleanup

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33765).
* #33981
* #33777
* #33767
* __->__ #33765
2025-07-24 15:45:17 -07:00
Joseph Savona
707e321f8f
[compiler][wip] Improve diagnostic infra (#33751)
Work in progress, i'm experimenting with revamping our diagnostic infra.
Starting with a better format for representing errors, with an ability
to point ot multiple locations, along with better printing of errors. Of
course, Babel still controls the printing in the majority case so this
still needs more work.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33751).
* #33981
* #33777
* #33767
* #33765
* #33760
* #33759
* #33758
* __->__ #33751
* #33752
* #33753
2025-07-24 15:37:06 -07:00
Joseph Savona
0d39496eab
[compiler] Enable additional lints by default (#33752)
Enable more validations to help catch bad patterns, but only in the
linter. These rules are already enabled by default in the compiler _if_
violations could produce unsafe output.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33752).
* #33981
* #33777
* #33767
* #33765
* #33760
* #33759
* #33758
* #33751
* __->__ #33752
* #33753
2025-07-24 15:36:54 -07:00
lauren
ff697fc58b
[eprh] Temporarily disable ref access in render validation (#32839)
This rule currently has a few false positives, so let's disable it for
now (just in the eslint rule, it's still enabled in the compiler) while
we iterate on it.
2025-04-09 14:49:31 -04:00
Niklas Holm
ada8bbbd6a
[eslint-plugin-react-compiler] Fix type error with recommended config (#32666)
## Summary

In the recommended configuration for `eslint-plugin-react-compiler`,
i.e. `reactCompiler.configs.recommended`, the rule is typed as `string`
rather than `eslint.Linter.RuleEntry` or anything assignable thereto,
which results in the following type error if you type check your eslint
configuration:
```
Property ''react-compiler/react-compiler'' is incompatible with index signature.
  Type 'string' is not assignable to type 'RuleEntry | undefined'.
```
Simply adding a const assertion fixes the error.

## How did you test this change?

I emitted declarations for the module and confirmed that the rule is now
typed as the string literal `'error'`
2025-03-19 14:58:08 -04:00
lauren
f31779a112
[ez] Run Prettier on eslint-plugin-react-compiler/src/types (#32590)
Extracting portions of #32416 for easier review.

This PR contains small formatting fixes.

Co-authored-by: michael faith <michaelfaith@users.noreply.github.com>
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32590).
* #32592
* #32591
* __->__ #32590
* #32589
* #32588

---------

Co-authored-by: michael faith <michaelfaith@users.noreply.github.com>
2025-03-12 19:12:22 -04:00
lauren
00aa0043c7
[compiler] Migrate compiler packages to tsup (#32550)
Currently in the `compiler` workspace, we invoke esbuild directly to
build most packages (with the exception of `snap`). This has been mostly
fine, but does not allow us to do things like generate type declaration
files.

I would like #32416 to be able to consume the merged
eslint-plugin-react-compiler from source rather than via npm, and one of
the things that has come up from my exploration in that stack using the
compiler from source is that babel-plugin-react-compiler is missing type
declarations. This is primarily because React's build process uses
rollup + rollup-plugin-typescript, which runs tsc. So the merged plugin
needs to typecheck properly in order to build. An alternative might be
to migrate to something like babel with rollup instead to simply strip
types rather than typecheck before building. The minor downside of that
approach is that we would need to manually maintain a d.ts file for
eslint-plugin-react-hooks. For now I would like to see if this PR helps
us make progress rather than go for the slightly worse alternative.

[`tsup`](https://github.com/egoist/tsup) is esbuild based so build
performance is comparable. It is slower when generating d.ts files, but
it's still much faster than rollup which we used prior to esbuild. For
now, I have turned off `dts` by default, and it is only passed when
publishing on npm.

If you want to also generate d.ts files you can run `yarn build --dts`.

```
# BEFORE: build all compiler packages (esbuild)
$ time yarn build

  Done in 15.61s.
yarn build  13.82s user 1.54s system 96% cpu 15.842 total

# ---

# AFTER: build all compiler packages (tsup)
$ time yarn build

  Done in 12.39s.
yarn build  12.58s user 1.68s system 106% cpu 13.350 total

# ---

# AFTER: build all compiler packages and type declarations (tsup)
$ time yarn build --dts

  Done in 30.69s.
yarn build  43.57s user 3.20s system 150% cpu 31.061 total
```

I still need to test if this unblocks #32416 but this stack can be
landed independently though as we could probably just release type
declarations on npm. No one should be using the compiler directly, but
if they really wanted to, lack of type declarations would not stop them
(cf React secret internals).

Note that I still kept esbuild as we still use it directly for forgive.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32550).
* #32551
* __->__ #32550
2025-03-07 16:41:55 -05:00
Orta Therox
18eaf51bd5
Support eslint 8+ flat plugin syntax out of the box for eslint-plugin-react-compiler (#32120)
## Summary

The current docs for the react compiler eslint plugin is based on
integrating with the old-style eslint config format. This is generally
fine, but most plugins (and the [official
docs](https://eslint.org/docs/latest/use/configure/configuration-files#configuration-file))
are now describing themselves in the new format.

This PR has two changes:

- Update the exports to include a "flat configuration"
- Adds a README change describing how to handle both configs

The solution is semi-based on @guillaumebrunerie's answer in
https://github.com/reactwg/react-compiler/discussions/25 mixed with
reading the source code for
[eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/src/index.ts)

## How did you test this change?

I faked this API in the most recent deploy:

![Screenshot 2025-01-18 at 19 58
44](https://github.com/user-attachments/assets/ae0e4bea-fb96-4073-a5f7-c886d087b6af)

Then used that in my app:

![Screenshot 2025-01-18 at 20 04
33](https://github.com/user-attachments/assets/21f77158-7535-453a-b988-49cf59d22d71)

and get myself some compiler messages:

```
/Users/orta/dev/app/apps/puzzmo.com/src/palette/HoverPopover.tsx
  31:37  error  Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning)  react-compiler/react-compiler

/Users/orta/dev/app/apps/puzzmo.com/src/components/gameplay/PlayGamePauseOverlay.tsx
   33:7   error  Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)  react-compiler/react-compiler
   35:5   error  Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)  react-compiler/react-compiler
```
2025-01-18 17:41:34 -05:00
michael faith
b3a95caf61
fix(eslint-plugin-react-compiler): support v9 context api (#32045)
## Summary

This change fixes a gap in the plugin's support of eslint v9. In one
place that it's using the `SourceCode` api, it's correctly considering
v9's api. But in the other place where `SourceCode` is used, it's only
using the legacy api, which was removed in v9.
2025-01-13 13:49:31 -05:00
mofeiZ
b9b510df2a
Revert "Replace deprecated dependency in eslint-plugin-react-compiler" (#31665)
Reverts facebook/react#31629

`@babel/plugin-proposal-private-methods` is not compatible with
`@babel/traverse` versions < 7.25 (see
https://github.com/babel/babel/issues/16851). Internally we have
partners that use a less modern babel version, and we expect this to be
an issue for older codebases in OSS as well.
2024-12-03 11:46:08 -05:00
Pavel
7670501b0d
Replace deprecated dependency in eslint-plugin-react-compiler (#31629) 2024-11-24 23:32:11 -05:00
mofeiZ
a99d8e8d97
[compiler][eslint] Report bailout diagnostics with correct column # (#30977)
Compiler bailout diagnostics should now highlight only the first line of
the source location span.

(Resubmission of #30423 which was reverted due to invalid column
number.)
2024-09-16 15:56:24 -04:00
Lauren Tan
b57d282369
Revert "[compiler][eslint] remove compilationMode override; report bailouts on first line"
This reverts commit b34b750729.

This hack doesn't play well internally so I'm reverting this for now
(but keeping the compilationMode override). I'll audit the locations we
report later and try to make them more accurate so we won't need this
workaround.

ghstack-source-id: b6be29c11d
Pull Request resolved: https://github.com/facebook/react/pull/30792
2024-08-22 15:04:39 -04:00
Lauren Tan
34edf3b684
[compiler] Surface unused opt out directives in eslint
This PR updates the eslint plugin to report unused opt out directives.
One of the downsides of the opt out directive is that it opts the
component/hook out of compilation forever, even if the underlying issue
was fixed in product code or fixed in the compiler.

ghstack-source-id: 81deb5c11b
Pull Request resolved: https://github.com/facebook/react/pull/30721
2024-08-16 18:12:05 -04:00
Mike Vitousek
5edbe29dbe [compiler] Make ref enforcement on by default
Summary:
The change earlier in this stack makes it less safe to have ref enforcement disabled. This diff enables it by default.

ghstack-source-id: d3ab5f1b28b7aed0f0d6d69547bb638a1e326b66
Pull Request resolved: https://github.com/facebook/react/pull/30716
2024-08-16 13:27:14 -04:00
Mike Vitousek
9eb288e657 [compiler][ez] Default to using flow suppressions
ghstack-source-id: b6592650e0
Pull Request resolved: https://github.com/facebook/react/pull/30622
2024-08-06 23:47:09 -07:00
Mofei Zhang
b34b750729 [compiler][eslint] remove compilationMode override; report bailouts on first line
ghstack-source-id: 1870c7aa09
Pull Request resolved: https://github.com/facebook/react/pull/30423
2024-07-23 14:24:36 -04:00
Jan Kassens
fd2b3e13d3
Compiler: unfork prettier config (#30205)
Updates the prettier config to format all `.ts` and `.tsx` files in the
repo using the existing defaults and removing overrides.

The first commit in this PR contains the config changes, the second is
just the result of running `yarn prettier-all`.
2024-07-18 17:00:24 -04:00
Mofei Zhang
1f60a41801 [compiler][eslint] Add donotuse flag for bailouts
---
Adding an experimental / donotuse flag for small Meta internal usecase

ghstack-source-id: 908ef1e150c9fef1347616c9c4dc6bf3316900b0
Pull Request resolved: https://github.com/facebook/react/pull/30342
2024-07-15 17:56:04 -04:00
Mofei Zhang
e307a49544 [compiler][eslint] Use logger callback instead of exceptions to report eslint diagnostics
---
* panicThreshold: `all_errors` -> `none`
* inject an error logger through compiler config (instead of using exceptions)

We currently report at most one lint warning per file, this lets us exhaustively report all available ones (see new
test fixture for example)

ghstack-source-id: 5299315574d11929efc39ee8f6033e3035d1e378
Pull Request resolved: https://github.com/facebook/react/pull/30336
2024-07-15 17:56:04 -04:00
Mofei Zhang
6cca9c3184 [compiler][be] Fix lint violations in eslint-plugin
ghstack-source-id: 7c11dce833fcf8f46aaa23858ac94a05e870fae8
Pull Request resolved: https://github.com/facebook/react/pull/30335
2024-07-15 17:56:04 -04:00
Lauren Tan
113c8e7f72 [compiler:eslint] Don't crash if hermes parser fails to parse
Eslint rules should never throw, so if we fail to parse with Babel or
Hermes, we should just ignore the error. This should fix issues such as
trying to run the eslint rule on non tsx|ts|jsx|js files, Hermes parser
not supporting certain JS syntax, etc.

I didn't add a test for this as our eslint-rule-tester config uses
hermes-eslint parser, so it wasn't possible to add a top level await as
it would crash hermes-eslint before our rule was triggered. Similarly I
couldn't add a test for non-JS files as it would not be parseable by
hermes-eslint.

Fixes #29107

ghstack-source-id: 60afcdb89ab4a8d2e4697cc50c5490803e7cbeac
Pull Request resolved: https://github.com/facebook/react/pull/29631
2024-06-01 08:04:41 +09:00
Lauren Tan
9d530e94c4 [compiler:babel] Don't read config files when not running as part of
user's pipeline

When the user app has a babel.config file that is missing the compiler,
strange things happen as babel does some strange merging of options from
the user's config and in various callsites like in our eslint rule and
healthcheck script. To minimize odd behavior, we default to not reading
the user's babel.config

Fixes #29135

ghstack-source-id: d6fdc43c5c
Pull Request resolved: https://github.com/facebook/react/pull/29211
2024-05-29 11:46:27 +09:00
Kirill Zyusko
e8779a9a9a
[React Compiler] use filename instead of context.filename in ESLint plugin (#29104)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

Use `filename` instead of `context.filename` in eslint compiler.

The problem is that in `react-native` + `typescript` project the context
may not have `filename`:

<img width="384" alt="image"
src="https://github.com/facebook/react/assets/22820318/e5d184fa-5ac9-4512-96b9-644baa3d5f25">

And eslint will crash with:

```bash
TypeError: Error while loading rule 'react-compiler/react-compiler': Cannot read properties of undefined (reading 'endsWith')
```

But in fact we already derive `filename` variable earlier so we can
simply reuse the variable (I guess).

## How did you test this change?

- add `eslint` plugin to RN project;
- run eslint
2024-05-16 12:35:52 -04:00
Lauren Tan
cf7d895db6 [compiler:eslint] Fix false positive with TS type param syntax
Previously we would attempt to parse code in the eslint plugin with the
HermesParser first as it can handle some TS syntax. However, this was
leading to a mis-parse of React hook calls with type params (eg,
`useRef<null>()` as a BinaryExpression rather than a CallExpression with
a type param. This triggered our validation that Hooks should not be
used as normal values.

To fix this, we now try to parse with the babel parser (with TS support)
for filenames that end with ts/tsx, and fallback to HermesParser for
regular JS files.

ghstack-source-id: 5b7231031c
Pull Request resolved: https://github.com/facebook/react/pull/29081
2024-05-15 15:44:21 -07:00
Lauren Tan
d0a51e7dfc Allow eslint rule reportable severity to be set
During the demo I might show an example of fixing a
CannotPreserveMemoization error. But I don't want to make that
reportable by default, so this PR allows configuration like so

```js
module.exports = {
  root: true,
  plugins: [
    'eslint-plugin-react-compiler',
  ],
  rules: {
    'react-compiler/react-compiler': [
      'error', {
        reportableLevels: new Set([
          'InvalidJs',
          'InvalidReact',
          'CannotPreserveMemoization'
        ])
      }
     ]
  }
}
```

ghstack-source-id: 984c6d3cb7e19c8fea2bb88108dd26335c031573
Pull Request resolved: https://github.com/facebook/react-forget/pull/2936
2024-05-06 20:07:36 -04:00
Lauren Tan
84d28ebcc5 Default to raising all errors in eslint plugin
We control what gets reported via another function anyway so it's better
to raise everything at the compiler config level. This lets us configure
what level of diagnostic is reportable later

ghstack-source-id: 996d3cbb8d8f3e1bbe943210b8d633420e0f3f3b
Pull Request resolved: https://github.com/facebook/react-forget/pull/2935
2024-05-06 20:07:35 -04:00
Joe Savona
1c8f8bfb89 Rename ReactForgetBabelPlugin locals
ghstack-source-id: 9cd5fe41ae322632dfeb3d5c7468268678006d94
Pull Request resolved: https://github.com/facebook/react-forget/pull/2929
2024-05-02 17:14:25 -07:00
Joe Savona
48e0c70292 Rename babel plugin
ghstack-source-id: bb66913e2d3c814696311371ed655f3da03d1199
Pull Request resolved: https://github.com/facebook/react-forget/pull/2926
2024-05-02 14:12:33 -07:00
Sathya Gunsasekaran
8d234c64eb [hir] Remove hermes parser
Exporting the hermes parser breaks the playground
as the hermes parser can not work in the browser.

No one is using this directly anyway -- snap and
others bundle hermes parser on their own, so,
let's remove it.

ghstack-source-id: d448c346eb137f8ba6ada4ad113e41a90b29baff
Pull Request resolved: https://github.com/facebook/react-forget/pull/2890
2024-04-23 12:28:42 +01:00
Lauren Tan
ec05176fb3 Make string values for config case-insensitive
Fixes a tiny inconsistency with compiler options where one was all
uppercase and one all lowercase by normalizing to lowercase regardless
of the casing of the user's config.

ghstack-source-id: fe60a3259de89a1b3fdd7475950e16e96cc57f6b
Pull Request resolved: https://github.com/facebook/react-forget/pull/2832
2024-04-11 10:45:35 -04:00
Lauren Tan
1f35f7e320 Add new ErrorSeverity.CannotPreserveMemoization
This adds a new category of error where the compiler cannot preserve
memoization exactly how as it was originally authored. We're adding a
new category here because it's not an actionable error, and allows us to
more specifically control whether it's reportable or not.

ghstack-source-id: 9693cd42ca64b980248c6202091bdd4c827e1cd4
Pull Request resolved: https://github.com/facebook/react-forget/pull/2824
2024-04-08 11:00:41 -04:00
Jan Kassens
76bb13cd26 First attempt at making the linter work with advanced TypeScript syntax
First attempt at making the linter work with advanced TypeScript syntax 

Falls back to the babel parser for some advanced syntax like string template 
syntax. 

This is pretty hacky as it doesn't take in any parsing options that are 
configured for the outer ESLint parser, not sure how that could be handled.
2024-04-04 18:31:31 -04:00
Lauren Tan
f4229cdb7f Rename error type 2024-03-28 10:40:04 -04:00
Jan Kassens
72d374e978 [linter] rename ReactForgetDiagnostics to ReactCompilerRule
[linter] rename ReactForgetDiagnostics to ReactCompilerRule
2024-03-14 11:53:32 -04:00
Jan Kassens
b666bd1637 [lint] do not report issues when a matching flow suppression is present
Based on implementation of a similar case in D54776832.
2024-03-13 11:40:35 -04:00
Jan Kassens
da7c466f07 Rename eslint-plugin-react-forget to eslint-plugin-react-compiler
Rename eslint-plugin-react-forget to eslint-plugin-react-compiler
2024-01-16 17:36:37 -05:00