Skip to content
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

.ts barrel (index) file does not trigger warning #76

Open
githorse opened this issue Jan 16, 2025 · 3 comments
Open

.ts barrel (index) file does not trigger warning #76

githorse opened this issue Jan 16, 2025 · 3 comments

Comments

@githorse
Copy link

githorse commented Jan 16, 2025

I have a React component in Cat.tsx:

// Cat.tsx
export default function Cat() {
  return (
    <div>Fluffy</div>
  )
}

I have a barrel file animals/index.ts that exports the Cat component, along with a helper function (and potentially other React components):

export {default as Cat} from './Cat'
export {default as Bat} from './Bat'
export {default as Rat} from './Rat'

export function isThatCatFluffy() {
  return "yes"
}

As written, this file will not trigger the react-refresh warning, even though it exports both a React component and a non-React component. If I change the extension to .tsx, then the rule fires.

Since there's no JSX/TSX in the file, and no React import, there's no inherent reason to use the .tsx extension here. I probably have dozens or hundreds of these barrel files around, with a .ts extension, and if I'm understanding correctly it seems like currently they will break HMR but won't trigger a warning.

Questions:

  • As written, does this file break HMR and cause a full reload after any change to Cat, Bat, or Rat? (This is my assumption.)
  • If so, is there a way that this plugin can detect this without changing the extension to tsx? (I tried checkJS but that didn't seem to do it --maybe we need checkTS?)
  • Is there general guidance / best practice for using barrel (index) files in a way compatible with HMR? See related SO issue.
@githorse githorse changed the title .ts barrel file does not trigger warning .ts barrel (index) file does not trigger warning Jan 16, 2025
@ArnaudBarre
Copy link
Owner

along with a helper function (and potentially other React components)

Writing React component without the file being .tsx will be very limited, it would probably be something with only hooks and no UI. For now I think this is too rare to be worth activating the check on all TS files and maybe create a lot false positive

As written, does this file break HMR and cause a full reload after any change to Cat, Bat, or Rat?

Nope, if these files respect Fast Refresh rules, the update will not "bubble up" to cat/index.ts and HMR will be good

I tried checkJS but that didn't seem to do it

Yeah this flag is only for people using JSX inside JS files, which TS does not allow and the reason stated above I don't think having checkTS is a good direction

Is there general guidance / best practice for using barrel (index)

Barrel files are not great for HMR and mainly for Vite if you are using it, see this talk for an example of the impact it had at Shopify: https://www.youtube.com/watch?v=YcT2yP0nmm0

The only things that you should not do is having React component inside barrel files, but apart from that using them will make HMR ok for most updates and HMR a bit slower when editing non components. Having index files like this:

export {default Cat} from './Cat'
export {default as Bat} from './Bat'
export {default as Rat} from './Rat'
export { SOME_CONSTANT } from './constants'
export { utilA, utilB } from './utils'

export function isThatCatFluffy() {
  return "yes"
}

does not break fast refresh rules. The only issue is that when doing changes to utilAs, instead of refreshing component that need utilA, it will refresh all components that requires at least one of Cat, Bat, Rat, SOME_CONSTANT, utilA, utilB, isThatCatFluffy (which is why it can slow down HMR). The split in the SO answer is not needed

Note: Using default export for React component is really not needed and makes refacotr and re-export just harder for no benefits, I highly advice using export function Cat() {. This patterns also tends to force people to have only one exported component per file, and there is no reason to enforce this (sometimes it can avoid having a directory with 3 files of 20 lines)

Let me know if something is not clear

@githorse
Copy link
Author

githorse commented Jan 20, 2025

Thank you @ArnaudBarre! This is extremely helpful. It sounds like there are some good reasons I should not use barrel files, but that they will not break HMR when used like this. In other words, as long as React component X is defined in a file that only exports React components, HMR will work, even if X is re-exported from a barrel file with mixed exports.

One question, though -- let's say that I change the extension of this barrel file to .tsx. (Maybe just by mistake, or maybe it's actually exporting TSX in a helper function, not a React component, like in #75.) Now the file does trigger the rule -- to be clear: you're saying that's a false positive, right?

@ArnaudBarre
Copy link
Owner

as long as React component X is defined in a file that only exports React components, HMR will work, even if X is re-exported from a barrel file with mixed exports.

Yep correct

Now the file does trigger the rule -- to be clear: you're saying that's a false positive, right?

Yep if the file does not export anything the match a potential React component, any warning is a false positive and should can be reported to improve the rule. The last release should reduce the number of false positive, but if you have another one feel free to paste a code sample here or in another issue so I can look at it

(Note: is you have a PascalCase function Foo that return a string, it will be considered a react component, even if for you it's not, so in that case the warning will be legit)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants