自以为是的 React:文件夹结构和文件命名

2025-05-24

自以为是的 React:文件夹结构和文件命名

简介

我使用 React 已经超过 4 年了。在此期间,我对应用程序应该是什么样子形成了自己的看法。这是这些看法合集的第一部分。

文件夹结构和文件命名

我在开发过的应用程序的文件夹结构上经历了多次迭代。我发现最好的扩展方案是使用扁平文件夹和长文件名。因为我用的是 VSCode,所以文件搜索起来很方便,所以文件名越长越好。以下是我大部分 React 应用程序的布局方式。

文件夹结构

/react-app
  /build
  /node_modules
  /public
  /src
    /assets
    /components
    /contexts
    /lib
    /pages
    /services
    /styles
    AppRoutes.tsx
    index.tsx
    react-app-env.d.ts

  package.json
  README.md
  tsconfig.json
  yarn.lock
Enter fullscreen mode Exit fullscreen mode

以下是这些文件夹中内容的简要概述。

  • /assets – 图像、徽标。
  • /components - 多个页面之间共享的组件。
  • /contexts - 我将所有 context 组件放在一个单独的文件夹中,以免与普通的 React 组件混淆。我喜欢实现的一个常见 context 是 UserAuthContext.tsx。
  • /lib - 使用第三方库(例如 Firebase)时,我喜欢将所有初始化内容放在名为 lib 的文件夹中。然后,我会导出该初始化库的实例。
import firebase from "firebase/app";
firebase.initializeApp({
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  appId: process.env.REACT_APP_FIREBASE_APP_ID
});
export default firebase;
Enter fullscreen mode Exit fullscreen mode
  • /pages - 页面也是 React 组件,但它们代表应用程序的页面或屏幕。它们与 AppRoutes.tsx 文件中的路由 1:1 映射。

  • /services - 我所有的 API 方法都放在一个名为 services 的文件夹中。我喜欢这样做,这样我就不用把 API 调用的业务逻辑直接放在组件中,而且任何组件都可以轻松地引用它所需的服务。

  • /styles - 我很少编写自定义 CSS,而是选择使用像 tailwindcss 这样的框架。这个 style 文件夹存放了我生成的样式和所有自定义 CSS。

  • AppRoutes - 此文件包含我应用程序的所有路由。我使用 React-router 已经有一段时间了,我喜欢将所有路由放在一个文件中,这样就能一目了然地查看所有路由。

import React from "react";
import { Switch, BrowserRouter, Route } from "react-router-dom";
import { useAuthContext } from "./contexts/AuthContext";
import { Navbar } from "./components/Navbar";
import { LandingPage } from "./pages/LandingPage";
import { DashboardPage } from "./pages/DashboardPage";

export const AppRoutes: React.FC = () => {
  const authAccount = useAuthContext();

  return (
    <BrowserRouter>
      <div className="mt-8 w-4/5 max-w-6xl m-auto">
        <Navbar />
      </div>
      <Switch>
        {authAccount ? (
          <AuthenticatedAppRoutes />
        ) : (
          <UnauthenticatedAppRoutes />
        )}
      </Switch>
    </BrowserRouter>
  );
};

const UnauthenticatedAppRoutes: React.FC = () => {
  return (
    <React.Fragment>
      <Route exact path="/" component={LandingPage} />
    </React.Fragment>
  );
};

const AuthenticatedAppRoutes: React.FC = () => {
  return (
    <React.Fragment>
      <Route exact path="/" component={DashboardPage} />
    </React.Fragment>
  );
};
Enter fullscreen mode Exit fullscreen mode
  • index.tsx - 这是典型的索引文件,您可以在其中将 React 应用程序渲染到文档中。

文件命名

我的经验法则是文件名越长、描述性越强越好。导出 React 组件的文件我使用 PascalCase 命名法,其他文件我使用破折号命名法。

# PascalCase
/components/NavBar.tsx
/contexts/UserAuthContext.tsx
/pages/DashboardPage.tsx
# dash-case
/services/auth-service.ts
/lib/apollo-client.ts
Enter fullscreen mode Exit fullscreen mode

我总是更喜欢使用命名导出而不是默认导出。这样更容易在编辑器中搜索所需内容。

更新

我收到了一些关于这篇文章的问题,以下是我的回答:

看看 /components 里面的结构会很有趣。里面有嵌套吗?每个组件都有一个文件夹,里面除了组件文件本身之外还有一个 style/test/... 文件夹?

我没有在任何文件夹中使用任何嵌套。由于我使用 tailwind 或 bootstrap 之类的框架,因此我通常没有单独的样式文件。我的组件文件夹结构如下:

/components
  /__tests__
    Button.test.tsx
Button.tsx
Enter fullscreen mode Exit fullscreen mode

你如何处理一次性组件?例如,Contacts.jsx 页面有一个 ContactList 组件?

我将把页面拆分为子组件,所有子组件都与页面放在同一个文件中。

import * as React from 'react'

export const ContactsPage: React.FC = () => {
  return (
    <div>
      <h1>Contacts</h1>
      <ContactsList />
    </div>
  )
}

const ContactsList: React.FC = () => { ... }
Enter fullscreen mode Exit fullscreen mode

总结

这是我即将发布的系列文章的第一篇。如果你喜欢这篇文章,请点赞并在下方留言。你还有什么想说的吗?

与往常一样,我愿意接受建议。

谢谢阅读。

文章来源:https://dev.to/farazamiruddin/an-opinionated-guide-to-react-folder-struct-file-naming-1l7i
PREV
拖延者的荣耀指南:将浪费的时间转化为职业黄金的开源项目⭐️
NEXT
函数式编程之美