TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Delightful React file/directory structure

97 点作者 joshwcomeau大约 3 年前

14 条评论

azemetre大约 3 年前
Kinda wish Josh would mention how he structures his tests in his projects. Something I&#x27;m currently struggling at work is that within our code repos, the pattern that everyone seems to copy is mimic the src&#x2F; directory for the test&#x2F; directory, rather than co-locating tests along with components. This means a structure for components:<p><pre><code> src&#x2F; components&#x2F; Button&#x2F; Button.tsx </code></pre> Is just copied ad-hoc for tests, so we get this:<p><pre><code> test&#x2F; components&#x2F; Button&#x2F; Button.test.tsx </code></pre> Ideally it would be structured as so:<p><pre><code> src&#x2F; components&#x2F; Button&#x2F; Button.tsx Button.test.tsx </code></pre> 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.<p>The oddest part is that some staff and principle engineers are very adamant about this structure. It&#x27;s just additional boilerplate that doesn&#x27;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.<p>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.<p>IDK, just ranting now at this point.
评论 #30686610 未加载
评论 #30692923 未加载
评论 #30689917 未加载
评论 #30690972 未加载
评论 #30695468 未加载
评论 #30687328 未加载
评论 #30687959 未加载
notapenny大约 3 年前
Keep it as flat as possible until you really, really need to structure it.<p>A folder for components and a maybe separate one for pages or containers is probably all you need (and even those you could probably stick in components until some structure arises). Have seen quite a lot of code-bases that suffered from people trying to structure their folders around a certain model too early on, change their mind, change it again, result: a mess.
评论 #30696350 未加载
zheksoon大约 3 年前
I prefer using fractal-style component structure, avoiding folders like `components` for single-use components. It looks like this:<p><pre><code> src&#x2F; App&#x2F; screens&#x2F; Login&#x2F; component.tsx index.tsx model.tsx styles.scss Dashboard&#x2F; SomeDashboardPart&#x2F; component.tsx index.tsx SomeOtherDashboardPart&#x2F; component.tsx index.tsx helpers&#x2F; someHelper.tsx component.tsx index.tsx model.tsx components&#x2F; Button&#x2F; component.tsx index.tsx </code></pre> `model.tsx` files here are MobX data models used for this specific component
评论 #30687462 未加载
评论 #30694985 未加载
mind-blight大约 3 年前
There are some things I really like about this, and some things that can shoot you in the foot.<p>Like:<p>- Having more than one component in a file. A lot of complex components can be made simpler by breaking then into many smaller, temper components. A lot of these helper components are too specific to warrant generalized use. Adding a new file for each one (especially if they&#x27;re only 3-5 lines of code) clutters the code base, so keeping them in the same time where they&#x27;re used makes sense. You can always pull them into a separate file later.<p>- Not making everything &quot;index.js&quot;. That really makes it more difficult to keep track of what&#x27;s what code is where.<p>Dislike:<p>- using indeed.js for experts. This makes it easier to accidentally add circular imports, and much harder to track them down.<p>- putting all components in a components&#x2F; directory. This is fine for smaller apps, but it starts to get unweildy once you add more features, teams, or team members to the repo. This is especially true if you use redux, Apollo, and React-router (or any of their competing libraries). Selectors, reducers, GraphQL queries, get spread across the code base, and it becomes difficult to teach down which component rely on what selectors (for example). This starts to bog down onboarding and cross team collaboration since ownership becomes more difficult to define. You end up with spaghetti code pretty easily.
ldd大约 3 年前
&gt; Finally, in terms of organization, I want things to be organized by function, not by feature.<p>In my experience, writing a game in mostly React, separating things by feature is more intuitive down the line. Mostly because after some time has passed, finding something is pretty easy and I don&#x27;t get completely lost in code. And yes, this means having custom hooks in the same file as the actual component sometimes.<p>I also purposefully let convoluted import statements with lots of &#x27;..&#x2F;..&#x2F;..&#x2F;&#x27; just exist because my IDE (VS Code) takes care of it and if you really think about it, you never really spend too much time on them.<p>Then again, I&#x27;ve come to the realization that different things work for different folks. And different projects. If anything, I just encourage more people to try different structures until something &#x27;clicks&#x27; with you.
beaconstudios大约 3 年前
I do something similar, except I directly use index.tsx as the widget in a directory structure, like this:<p><pre><code> components Button.tsx Menu index.tsx &lt;-- menu component Link.tsx &lt;-- &quot;Link&quot; component only used within Menu </code></pre> That way if I want to break out the Button component into multiple sub-components, I don&#x27;t need to change the imports, but I also don&#x27;t need to add a re-exporting index.ts in every single folder (it gets annoying once you&#x27;re up to dozens of folders).<p>Also, for funsies I have both a components directory for reusable components and a separate &quot;app&quot; 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:<p><pre><code> app index.tsx &lt;-- entrypoint Login.tsx Register.tsx routes index.tsx &lt;-- core router Home.tsx </code></pre> etc... This also makes SSR easy because then in the root &#x27;src&#x27; 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.<p>Also I don&#x27;t know if this is standard nowadays but aliasing &quot;src&quot; to the source root and adding it as a baseDir in tsconfig.json means you can use absolute imports.
评论 #30686078 未加载
neurotrace大约 3 年前
&gt; Finally, in terms of organization, I want things to be organized by function, not by feature.<p>I found this super surprising. I much prefer doing things by feature than by function. Where it goes is a function of which page&#x2F;view&#x2F;route it&#x27;s on. If it&#x27;s a general purpose component that is used on multiple pages (like `Button`) then, sure, it goes in `src&#x2F;components`. Otherwise, it goes in `src&#x2F;routes&#x2F;app-section&#x2F;components`. Truth be told, I&#x27;ve taken to doing a setup like this:<p><pre><code> src&#x2F; - routes&#x2F; - app-section&#x2F; - effects&#x2F; - some-action.effect.ts - ui&#x2F; - app-section.component.tsx - index.ts - some-component.component.tsx - app-section.route.ts - app-section.types.ts - index.ts </code></pre> `effects` basically holds your business logic, `ui` contains section specific components and exports the top-level component via `ui&#x2F;index.ts`, `thing.route` hooks up the route to state management, `index.ts` provides a bundle for hooking up the effects to your effect system and the route component itself. The `name.type.extension` naming scheme clears up the tab name confusion problem. Maybe I should write my own article about this ;)
tomc1985大约 3 年前
Can we please stop describing technical things using feelings-based words? It&#x27;s foppish, it makes tech sound really really disingenuous and fake, and it cheapens the words as well.<p>&quot;Clean,&quot; &quot;well-organized,&quot; &quot;atomic&quot; ... all adjectives, all descriptive, zero emotion
评论 #30688908 未加载
评论 #30688851 未加载
评论 #30689630 未加载
throwaway284534大约 3 年前
When it comes to the index.js issue, I’m partial to “unwrapping” component directories. For example, if a Post component has a few one off sub-components, they’re placed in Post subdirectory:<p><pre><code> src&#x2F; components&#x2F; Post.jsx Post&#x2F; PostHeader.jsx PostActions.jsx </code></pre> Then import as:<p><pre><code> import Post from “components&#x2F;Post.js” </code></pre> And within the component:<p><pre><code> import PostActions from “components&#x2F;Post&#x2F;PostAction.js” </code></pre> I’ve felt this approach eliminates most index.js reexports and aligns closer with a browser’s native import syntax. This all comes at the cost of less encapsulation, but in a private codebase, it’s less of an issue.
评论 #30687416 未加载
bayesian_horse大约 3 年前
In SPAs it&#x27;s pretty easy to tell to which &quot;code feature&quot; a component belongs. For one group of component, it depends on what page they are on. For the rest it basically doesn&#x27;t matter.<p>I prefer the feature based approach because it is easier to navigate.
lazrgatr大约 3 年前
Unrelated to the post, but the site has the creepiest pop-up I&#x27;ve ever seen. It scared me a bit.
shanehoban大约 3 年前
I cannot get over the quality of this site, the subtle sounds, the design, the interactions, just everything. Josh is a damn genious, from one FE dev to another, bravo!
smotched大约 3 年前
How are you adding the slight bounce animation on your file explorer? its pretty neat.
评论 #30691793 未加载
efrafa大约 3 年前
I would avoid default exports at all cost.
评论 #30687091 未加载
评论 #30687071 未加载