Live data from Hacker News

Delightful React file/directory structure

joshwcomeau.com

1–10 of 53 posts

Re: Delightful React file/directory structure

#2
I do something similar, except I directly use index.tsx as the widget in a directory structure, like this:

    components
      Button.tsx
      Menu
        index.tsx 
That way if I want to break out the Button component into multiple sub-components, I don't need to change the imports, but I also don't need to add a re-exporting index.ts in every single folder (it gets annoying once you're up to dozens of folders).

Also, for funsies I have both a components directory for reusable components and a separate "app" directory for the core containers that make up the first-class functionality. index.tsx in that folder is what would normally be the App.tsx, so the JSX nesting structure of the app is mirrored in the directory structure:

    app
      index.tsx 
etc... This also makes SSR easy because then in the root 'src' directory that contains all this I can have a server.tsx with ReactDOM.render and a client.tsx with ReactDOM.hydrate, and each can use their respective isomorphic context providers.

Also I don't know if this is standard nowadays but aliasing "src" to the source root and adding it as a baseDir in tsconfig.json means you can use absolute imports.

Re: Delightful React file/directory structure

#3

I do something similar, except I directly use index.tsx as the widget in a directory structure, like this: components Button.tsx Menu index.tsx That way if I want to break out the Button component into multiple sub-components, I don't need to change the imports, but I also don't need to add a re-exporting index.ts in every single folder (it gets annoying once you're up to dozens of folders). Also, for funsies I have…

I think his criticism of that approach is that you end up with a bunch of index.tsx tabs open in your IDE and it can be hard to tell what is what.

My approach is similar to his, but is simplified to have one index at the top of the components folder for all the components:

  components
     index.tsx 
Then import is easy, and feels less redundant

  import { mywidget, mycomplexwidget } from '@foo/components'

Re: Delightful React file/directory structure

#4
post #3

I do something similar, except I directly use index.tsx as the widget in a directory structure, like this: components Button.tsx Menu index.tsx That way if I want to break out the Button component into multiple sub-components, I don't need to change the imports, but I also don't need to add a re-exporting index.ts in every single folder (it gets annoying once you're up to dozens of folders). Also, for funsies I have…

I think his criticism of that approach is that you end up with a bunch of index.tsx tabs open in your IDE and it can be hard to tell what is what. My approach is similar to his, but is simplified to have one index at the top of the components folder for all the components: components index.tsx Then import is easy, and feels less redundant import { mywidget, mycomplexwidget } from '@foo/components'

That issue with too many index.ts files used to be a major issue but nowadays I use VS Code which disambiguates matching filenames with their parent directory.

I think I just don't really like using re-exporting index files if I can avoid them, because I don't see much of a positive cost/benefit in most cases. In your example I'd be doing something like this instead:

    import { mywidget } from '@foo/components/mywidget';
    import { mycomplexwidget } from '@foo/components/mycomplexwidget';
I could fish for pseudo-objective arguments for this but honestly I think it's mostly just personal preference!

Re: Delightful React file/directory structure

#6
Kinda wish Josh would mention how he structures his tests in his projects. Something I'm currently struggling at work is that within our code repos, the pattern that everyone seems to copy is mimic the src/ directory for the test/ directory, rather than co-locating tests along with components. This means a structure for components:

    src/
      components/
        Button/
          Button.tsx
Is just copied ad-hoc for tests, so we get this:

    test/
      components/
        Button/
          Button.test.tsx
Ideally it would be structured as so:

    src/
      components/
        Button/
          Button.tsx
          Button.test.tsx
This pattern makes it extremely taxing to utilize codemods in the future to transform repos into something else. It also, in my opinion, instills thinking that testing is separate from feature development and is often treated as such. As a result, my org often forgoes proper testing or tacking it on at the very end to just fulfill the motions of the dev cycle.

The oddest part is that some staff and principle engineers are very adamant about this structure. It's just additional boilerplate that doesn't help and makes it hard to understand what components have tests (especially when you get in the weeds of not having a flat component directory, where child components have nested directories often several layers deep). I have no idea where this pattern permeates but it should be discouraged in most frontend projects.

Co-location of files should absolutely be encouraged, the alternative is just a jumble of directories that make it hard to grok what is actually happening.

IDK, just ranting now at this point.

Re: Delightful React file/directory structure

#8
post #6

Kinda wish Josh would mention how he structures his tests in his projects. Something I'm currently struggling at work is that within our code repos, the pattern that everyone seems to copy is mimic the src/ directory for the test/ directory, rather than co-locating tests along with components. This means a structure for components: src/ components/ Button/ Button.tsx Is just copied ad-hoc for tests, so we get this: t…

I think people do the "separate directory for tests" thing because test runners have, in the past, shipped with a default configuration to target a test directory, rather than match test files by suffix.

Colocation of test files is the hands down winner and encourages the writing of tests. When you're making a change to a code file, you probably won't think to scour the codebase for relevant tests. If you see the test file right next to source file in your editor, you probably will.

Post reply on HN