eslint-plugin-react icon indicating copy to clipboard operation
eslint-plugin-react copied to clipboard

Rule Proposal: Enforce JSX Presence in `.tsx` Files (`no-tsx-without-jsx`)

Open HesamSe opened this issue 1 year ago • 5 comments

Description:

I would like to propose a new rule for eslint-plugin-react that enforces the presence of JSX elements in files with a .tsx extension. This rule would help maintain consistency and clarity in TypeScript projects using React or other JSX-based libraries.

Problem Statement:

Currently, it’s possible to create .tsx files without any JSX elements. This can lead to:

  • Confusion: Developers might use the .tsx extension unnecessarily for files that do not contain any JSX, potentially causing confusion about the file's intended purpose.
  • Consistency Issues: Keeping .ts and .tsx file distinctions clear ensures that the purpose of each file is easily understood by other developers working on the project.

Proposed Rule: no-tsx-without-jsx

  • This rule would throw an error if a file with the .tsx extension does not contain any JSX elements.
  • The rule would suggest renaming the file to a .ts extension if JSX is not present.

Example Use Cases:

  • Valid (Contains JSX):

    // myComponent.tsx
    import React from 'react';
    
    const MyComponent = () => <div>Hello, World!</div>;
    
    export default MyComponent;
    
  • Invalid (No JSX, should be .ts):

    // utilityFunction.tsx
    export function utilityFunction() {
        return 42;
    }
    

Benefits:

  • Improves Code Clarity: By ensuring that .tsx files contain JSX, the codebase remains easier to navigate and understand.
  • Encourages Best Practices: This rule will encourage developers to use .tsx only when necessary, and .ts otherwise, maintaining clearer file distinctions.
  • Aligns with TypeScript-First Principles: This rule fits well within a TypeScript-specific plugin, helping developers make the best use of TypeScript’s features and extensions.

Similar Rules and Why This Is Unique:

  • The react/jsx-filename-extension rule in eslint-plugin-react allows configuring when JSX is allowed in certain extensions but does not specifically target .tsx files and their usage within TypeScript projects.

Additional Context:

I have developed a prototype version of this rule in a custom ESLint plugin. You can check that at https://github.com/HesamSe/eslint-plugin-recommended/blob/main/src/rules/noTsxWithoutJsx.ts

HesamSe avatar Oct 22 '24 04:10 HesamSe

seems like jsx-filename-extension could just be extended via an option to cover tsx.

ljharb avatar Oct 22 '24 05:10 ljharb

@ljharb So, should I open another proposal or would this one be enough?

HesamSe avatar Nov 05 '24 18:11 HesamSe

This one is fine.

ljharb avatar Nov 06 '24 02:11 ljharb

I wasn't sure how no-tsx-without-jsx would work in jsx-filename-extension (it kinda seems like the opposite, though I may be misunderstanding). I threw together and published eslint-plugin-no-tsx-without-jsx to use myself instead at least until something more official lands here in eslint-plugin-react.

@HesamSe - Thanks for the prototype -- I jumpstarted with that code~

AnthonyAstige avatar Mar 15 '25 18:03 AnthonyAstige

@AnthonyAstige a PR would be welcome.

Yes, I agree that unless you care about file extensions meaning something, such that .jsx and .tsx are only used when there's JSX in the file, and .js and .ts and .mjs and .cjs etc NEVER have jsx in the file, the rule this issue is asking for wouldn't make any sense to use.

ljharb avatar Mar 15 '25 20:03 ljharb