-
-
Notifications
You must be signed in to change notification settings - Fork 727
feat(linter): add react/jsx-fragments rule #12988
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
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. |
CodSpeed Instrumentation Performance ReportMerging #12988 will not alter performanceComparing Summary
Footnotes |
93a4521 to
c9c7e68
Compare
camc314
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks! this is great
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds the react/jsx-fragments rule to the linter, which enforces consistent usage of React fragments by preferring either the shorthand syntax (<></>) or the standard element form (<React.Fragment></React.Fragment>).
- Implements the core rule logic with configurable modes (
syntaxandelement) - Adds comprehensive test coverage with pass/fail cases and fix expectations
- Includes automatic fixing functionality to transform between fragment forms
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
crates/oxc_linter/src/rules/react/jsx_fragments.rs |
Main implementation with rule logic, configuration handling, and fragment detection |
crates/oxc_linter/src/rules.rs |
Registers the new rule in the linter's rule collection |
crates/oxc_linter/src/snapshots/react_jsx_fragments.snap |
Test snapshots showing expected diagnostic output |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
| } | ||
| } | ||
|
|
||
| fn is_jsx_fragment(elem: &JSXOpeningElement) -> bool { |
Copilot
AI
Aug 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is duplicated from jsx_no_useless_fragment.rs as mentioned in the PR description. Consider extracting this to a shared utility module to avoid code duplication and maintain consistency across rules.
- Verified self-closing fragment handling is correct (already implemented) - Extracted duplicated is_jsx_fragment function to shared utils - All jsx-related tests passing (49/49) - Code properly formatted - Review comments from PR #12988 addressed Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
- Verified self-closing fragment handling is correct (already implemented) - Extracted duplicated is_jsx_fragment function to shared utils - All jsx-related tests passing (49/49) - Code properly formatted - Review comments from PR #12988 addressed Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
…ared utils (#13093) This PR addresses review comments from PR #12988 by extracting the duplicated `is_jsx_fragment` function that was present in both `jsx_fragments.rs` and `jsx_no_useless_fragment.rs` rules. ## Changes Made ### Code Deduplication - **Extracted** `is_jsx_fragment` function from both React linting rules - **Moved** the function to `crates/oxc_linter/src/utils/react.rs` as a shared utility - **Updated** both `jsx_fragments` and `jsx_no_useless_fragment` rules to use the shared function - **Removed** duplicate implementations and cleaned up unused imports ### Self-Closing Fragment Handling The review also mentioned handling self-closing fragments (e.g., `<Fragment />`). Upon investigation, this was already correctly implemented in the original code: ```rust let Some(closing_element) = &jsx_elem.closing_element else { return; // Skip self-closing elements }; ``` Self-closing fragments cannot be converted to shorthand syntax (`<></>`) and should not trigger the rule, which is the correct behavior already in place. ## Function Details The extracted `is_jsx_fragment` function recognizes both forms of React fragments: - `<Fragment>` (identifier reference) - `<React.Fragment>` (member expression) ```rust pub fn is_jsx_fragment(elem: &JSXOpeningElement) -> bool { match &elem.name { JSXElementName::IdentifierReference(ident) => ident.name == "Fragment", JSXElementName::MemberExpression(mem_expr) => { if let JSXMemberExpressionObject::IdentifierReference(ident) = &mem_expr.object { ident.name == "React" && mem_expr.property.name == "Fragment" } else { false } } _ => false, } } ``` ## Testing - ✅ All existing tests continue to pass (755/755) - ✅ Specific jsx-related tests pass (49/49) - ✅ Both `jsx_fragments` and `jsx_no_useless_fragment` rules maintain their behavior - ✅ Self-closing fragment test cases verify correct behavior (included in existing test suite) This refactoring eliminates code duplication while maintaining full backward compatibility and correctness of both linting rules. <!-- START COPILOT CODING AGENT TIPS --> --- 💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click [here](https://survey.alchemer.com/s3/8343779/Copilot-Coding-agent) to start the survey. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
Adds the
react/jsx-fragmentsrule. Replaced the eslint auto-generated tests with much simpler ones since the ones there seem outdated and/or esoteric. It might be worth checking if the import renamesFragmentto something else, but we don't do this forreact/jsx-no-useless-fragment(see https://github.com/oxc-project/oxc/blob/234abd465396c799f7cea1f6e41d44fcda6f54eb/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs#L324-L338). Thus, not gonna do it here. Might be worth adding a utility function file foris_jsx_fragmentsince I copy-pasted it, but seems pedantic imo.works towards #1022