NextJS 13文件夹结构最佳实践

58

我正在学习使用NextJS,并且正在使用最新版本的App Router,目前我遇到了路由问题,例如在哪里放置注册和登录页面,以及它们的文件夹结构,我应该把组件放在哪里,如何将其他相关组件分组,您能否为我解决这个问题,并尽可能简单地给出一些示例,因为我还在学习,任何帮助都将不胜感激,谢谢!


请参考以下文章:https://dev59.com/F1QJ5IYBdhLWcg3wdFd4 - Xuân Cường
1
这是个人偏好,但常见的模式是在与 pages/ 相同级别的位置创建一个 components/ 文件夹(pages 用于路由)。该结构在此处被暗示 https://nextjs.org/docs/pages/building-your-application/routing/pages-and-layouts。 - Andy Ray
5个回答

83
我觉得阅读Next文档中的这一部分会帮助你组织项目文件夹。

https://nextjs.org/docs/app/building-your-application/routing/colocation

我尝试了许多不同的结构,最终选择了这个。
所有文件夹和文件都将位于/app目录中,因为/app目录接受共存,与仅用于路由目的的/pages目录不同。这样/app目录可以被视为新的/src目录。
所有非路由文件夹将通过在名称前加下划线来表示为私有文件夹(如上述链接中所述)。这告诉Next路由器该文件夹不是路由的一部分(例如_components,_libs等)。
到目前为止,我们已经确定带有下划线_的每个文件夹都不是路由,而没有下划线的其他文件夹是路由系统的一部分(尽管在文件夹中有page.tsx或page.js文件是成为路由系统的另一个条件)。但我使用了Next 13的另一个功能,即路由组(如上述链接中所述)。它将文件夹名称放在括号中,以显示该文件夹用于组织目的(分组文件夹),不应包含在路由的URL路径中,例如(routes)。
有了这些原则,我把所有需要的文件夹放在了/app目录下,通过路由组将所有路由分组在(routes)文件夹中,通过在非路由文件夹前加下划线来使用私有文件夹,使得一切都得到了隔离。
下面的图片是以上所有要点的总结。

https://istack.dev59.com/wrJoY.webp

希望链接和我组织项目文件的方式能对你有所帮助。

我喜欢这种方法,但我不知道某些具有特定名称的文件的特性是否会使其变得复杂。例如,在(路由)之外的“error.tsx”或“page.tsx”。 - Francisco Ossian
@FranciscoOssian 正如我在第二点中提到的,所有以下划线为前缀的私有文件夹都会被排除在路由系统之外,即使它们包含"error.tsx"或"page.tsx"。唯一可能引起问题的地方是/app目录的根目录,应该避免使用这种类型的文件名。只有一个地方需要注意,很容易避免,我个人认为。 - Mahmoud Taghinia
6
我经常对人们所说的“组件”含义感到困惑。我知道像按钮、模态框等通用可重用的东西是组件,但是特定的东西呢?假设你有一个路由/app/(routes)/login/page.tsx。如果你有一个特定于登录页面的“组件”,把它放在登录路由文件夹中是否合理?还是将其移到组件目录中,并只在(routes)文件夹中保留page.tsx和layout.tsx文件? - Joe
2
只有在不使用src文件夹时,这才有意义。如果你使用了src文件夹,请使用下面@Yilmaz的答案。 - NSjonas
1
@Joe 如果一个组件只在特定页面或其他组件内使用,我会将其添加到名为“components”的文件夹中,该文件夹位于特定页面/组件的文件夹内。如果它在其他地方也被使用,我会将其移动到一个通用的“components”文件夹中。 - fredric
每个页面的自定义样式应该如何结构化的建议是什么? - undefined

51

enter image description here

有些人将组件放在应用程序内部,但我将它们放在外部,以便告诉其他工程师“app”目录仅包含页面组件。如果你在app目录中放置太多文件夹,那么其他工程师将很难理解我们应用程序中实际存在哪些路由。如果你在“app”目录中采用这种结构,将清楚地显示存在哪些路由:

enter image description here

如果您有类似的路由,具有共享的布局,您可以在app目录中使用()语法。例如:

enter image description here

auth文件夹中,您可以有共享布局的loginsignup页面。
在组件文件夹中,您可以为providersuishared组件创建子文件夹。

我想尝试实现这个,但是"pages"文件夹是用来做什么的? 如果我们只在一个页面上创建组件,而不与其他页面共享,应该把它放在哪里? - undefined
在早期版本中,当您创建一个新项目时,也会存在一个pages文件夹。 - undefined

14
在13版本中,Next.js引入了一个基于React Server Components构建的新的App Router。这意味着无论你将什么组件放置在应用程序目录下,它都会默认作为一个服务器组件工作。 如果你想要在服务器端渲染组件,我建议将组件放置在/app目录内。你也可以将组件放置在任何页面的文件夹内。
/app
  /components
  /dashboard
    customComponent.tsx
    page.tsx
  layout.tsx
  page.tsx

如果想了解更多有关文件约定的内容,请阅读本文: https://nextjs.org/docs/app/building-your-application/routing


13
即使组件文件夹在应用程序文件夹之外创建,组件仍将在服务器上呈现。 - Ahmed Basalib
是的,我刚刚看到了,谢谢你添加这个。 - Gilbish Kosma
@GilbishKosma 使用服务器端渲染有什么优势吗?将它们放在客户端上不会更快吗? - undefined
1
@Victor,优势取决于你的优先考虑因素。如果优先考虑SEO和快速初始渲染,我们可以选择SSR。如果网页高度互动,并且内容在不完全重新加载页面的情况下频繁更改,那么CSR会更好。大多数B2B应用程序受益于使用CSR,例如CMS门户、库存管理应用等。基本上,对于不希望数据在谷歌搜索中可用的情况,请使用CSR。还有一点,如果在Next.js中的任何组件中使用事件处理程序,则该组件将需要"use client",因为它将在客户端渲染。 - undefined
2
值得注意的是,可以通过在目录名称前加下划线(例如 app/_components)来忽略路由中的目录。 - undefined

0

在最新的App路由器版本中,您可以使用各种路由甚至自定义路由以使用自己的定制路由。

使用Next.js App路由器的默认路由: 要创建页面,您可以直接创建一个带有页面名称的文件夹 例如关于页面,创建关于文件夹,创建page.jsx(在关于文件夹内,作为关于索引页面,即可通过URL /about访问) 应用程序 /关于 page.jsx

2.) 实现自定义路由

您可以在next-config中添加

async rewrites() {
    return [
      {
        source: '/old-route',
        destination: '/new-route',
      },
      // Add more custom routes as needed
    ];

当我开始研究目录结构时,我已经做了很多研究。为了最佳实践,我直接在App目录中创建页面,例如all/products/page.jsx或app/about/page.jsx。

对于管理界面,我使用app/admin/pagenameofadmin/page.jsx和app/admin/page.tsx(管理员主页)。

对于所有其他组件,请使用components文件夹,并在其中创建子文件夹以便轻松查找组件。

布局 - 用于常见和重复的组件,如标题/页脚/侧边栏 auth - 用于登录注册相关组件 admin - 用于管理界面组件 pagename - 用于特定页面组件

如果您想在下一级保持所有内容有序,还可以为特定内容类型创建文件夹,但我建议仅在复杂项目中使用它。 product - 用于产品相关组件

将API保留在app/utils文件夹中。


请问您能否更详细地描述一下这个?如果您想要保持所有内容有条理,也可以为特定内容类型创建文件夹。对于复杂的项目,我建议只使用它来创建产品相关组件。将API保留在app/utils文件夹中。 - user8577431
1
不必为不同页面上的每种内容制作不同的组件,您可以通过重复使用相同的组件来节省时间和精力以适用于类似的内容类型。例如,如果您的应用程序中有产品、类别和博客,则可以将它们组织在以内容类型命名的文件夹中(如“产品”文件夹),而不是为每个页面创建单独的组件(如一个“productpage”文件夹)。这样,您就可以在不同的页面上使用相同的组件,从而更轻松地管理和更新应用程序。 - Veer Pratap

-16
一个简单的文件夹结构示例,你可以参考:
  1. 在你的Next.js项目根目录下创建一个pages目录。这是你放置与不同路由对应的页面组件的地方。

  2. 在pages目录下创建一个auth目录,将所有与身份验证相关的页面组织在一起。例如:

     pages/
       auth/
         login.js
         register.js
    
  3. 在login.js和register.js文件中,你可以创建登录和注册页面组件。例如:

     // pages/auth/login.js
     const LoginPage = () => {
         return <div>Login page</div>;
     };
    
     export default LoginPage;
    
  4. 接下来创建一个名为register.js的页面:

     // pages/auth/register.js
     const RegisterPage = () => {
         return <div>Register page</div>;
     };
    
     export default RegisterPage;
    
  5. 要设置路由,你可以使用Next.js内置的App组件和next/router模块中的Router。以下是如何配置路由的示例:

         // pages/_app.js
     import { useRouter } from 'next/router';
    
     const MyApp = ({ Component, pageProps }) => {
         const router = useRouter();
    
         // 检查当前路由是否是身份验证路由
         const isAuthRoute = router.pathname.startsWith('/auth');
    
         // 在这里可以执行任何通用布局或逻辑
    
         // 为身份验证页面添加布局或特定于身份验证的逻辑
         if (isAuthRoute) {
             // 在这里添加身份验证布局或逻辑(如果需要)
    
             // 例如,你可以添加一个通用的导航组件
             // 或者应用特定于身份验证页面的样式
    
             return ;
         }
    
         // 对于非身份验证页面,你可以应用不同的布局或逻辑
         // 或者直接返回组件本身
         return ;
     };
    
     export default MyApp;
    
在上面的例子中,我们使用_app.js文件根据路由配置不同页面的布局或逻辑。我们检查当前路由是否是身份验证路由(以/auth开头),并根据此进行特定的布局或逻辑应用。
注意:您可以根据具体要求在MyApp组件中进一步自定义布局和逻辑。
通过这个设置,您可以在/auth/login访问登录页面,在/auth/register访问注册页面。
记住运行npm run dev或yarn dev来启动Next.js开发服务器,并导航到相应的路由以查看页面的实际效果。
这是一个基本示例,帮助您开始使用Next.js的文件结构和路由。您可以根据项目需求进行修改和扩展。

19
这看起来像是ChatGPT。 - undefined
11
这看起来像是ChatGPT。 - DavidW
4
由于它没有涉及到nextjs 13.4中的新路由,所以看起来它确实得到了一些chatGPT的帮助,是的。 - undefined
1
由于它没有涉及到nextjs 13.4中的新路由,所以看起来确实是得到了一些chatGPT的帮助,是的。 - Norfeldt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接