揭开Next.js文件夹结构 - 综合指南
#javascript #网络开发人员 #编程 #react

介绍

next.js是一个广泛使用的框架,用于制作具有React的现代Web应用程序。它通过包括服务器端渲染,静态站点生成和路由来简化开发。这有助于创建快速且对SEO友好的站点,您可以在服务器端渲染或静态生成之间选择。 Next.js还提供了简单的基于文件的路由和内置CSS支持动态接口。

在Web开发中设置整洁的文件夹是必不可少的。它使事情井井有条,有助于快速找到文件,降低错误机会并使工作更加顺畅。一个有组织的结构可以提高可读性,简化维护并支持团队合作。这就像您项目的地图,为每个参与的每个人都清楚。

本指南旨在帮助您在Next.js项目中完全掌握文件夹设置。它想清楚地组织事物的组织方式和合作。它将解释每个文件夹的作用,文件如何连接以及提供项目中使用Next.js的实用提示。

先决条件

在学习文件夹结构之前,对:

有深入的了解很有帮助。
  • JavaScript:Next.js建立在React顶部,并严重依赖JavaScript,因此对JavaScript基本面的坚实掌握至关重要。
  • react:next.js是一个反应应用的框架,因此对诸如组件,状态,道具和JSX之类的React概念的熟悉是必不可少的。
  • HTML/CSS:在HTML和CSS中拥有良好的基础,将有助于了解Next.js组件和样式的结构。
  • nodejs:next.js是在node.js上构建的,因此对Node.js的工作方式有基本的了解将是有益的。
  • 基本路由:了解Web应用程序如何处理路由和导航将使Next.js的路由系统更容易掌握。
  • apis:Next.js可用于构建服务器端渲染和静态网站,因此对API和数据获取概念的基本了解将是有帮助的。

一旦您在这些领域拥有坚实的基础,您就可以更好地探究Next.js应用程序的特定结构和功能。

了解Next.js文件夹结构


- /app
  - page.js
  - layout.js
  - globals.css
- /public
  - ...
- /styles
  - ...
- /components
  - ...
- package.json
- next.config.js
- ...

这是每个目录(文件夹)和文件的简短说明:

  • /app:我们的NextJS应用程序中最重要的文件夹。包含layout.js,page.js,globals.css(这些是目前最重要的文件)

    • layout.js:在我们的应用程序中,将“ Layout.js”视为关键起点。它像父母一样围绕所有组件,使您可以使用共享布局给您的应用程序页面保持一致的外观和感觉。此外,它还有助于调整语言设置(例如lang =“ en”),更新所有页面的元数据,以及包括脚本标签,链接或字体,以量身定制HTML文档的外观。
    • 页: )。
    • globals.css:“ globals.css”是您可以找到整个应用程序的通用CSS文件。它具有适用于整个应用程序的样式。
  • /public:在“/public”目录中,您可以存储图像,字体和其他资产等文件。这些文件可直接访问用户,而无需通过下一个文件。

  • /样式:在Next.js中,您可以选择保留特定于单个组件的整体设计样式或样式。 Next.js为使用CSS(例如CSS模块,CSS-IN-JS库等)的不同方法提供了支持。另外,globals.css文件可以在样式目录中。

  • /组件:在此目录中,您可以在整个应用程序中放置可以在多个页面中使用的React组件。

  • 软件包。

  • next.config.js:next.config.js文件用作配置中心,您可以在其中量身定制下一个应用程序的不同方面。这包括调整WebPack配置,定义环境变量等任务以适合您的特定需求。

在Next.js项目结构中,您会发现这些基本目录和文件。随着项目的扩展,您可以通过创建子目录或其他文件夹来更多地组织代码,以更好地满足您项目不断发展的要求。

探索每个目录和文件

这是一些关键设计选择背后的简短理由:

应用目录

/应用程序目录保存您的路由文件。该目录中的每个文件都成为您应用程序中的路由。此选择简化了路由和服务器端渲染设置。

要建立“/用户”路由,请先访问应用程序目录。在应用程序目录中,创建一个名为“用户”的新文件夹。在此“用户”文件夹中,生成一个“ page.js”文件。在“ page.js”文件中,您可以构造一个反应功能组件。

const page = () => {
return (
     <div>Hello user</div>
    )
}

export default page

您可以在Localhost:3000/user。

访问它。

现在,让我们解决更复杂的任务。想象一下,您需要构建一个博客应用程序,该应用程序具有各种功能的不同路线。这需要通过“/post”路线展示所有帖子,并通过“/post/new”路线制作新帖子。这个概念称为React中的嵌套路由,它看起来像这样:


import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './pages/Home';
import NewPost from './pages/NewPost';
import Post from './pages/Post';

const App = () => {
    return (
        <Router>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="about" element={<Home />} />
                <Route path="posts" element={<Post />}>
                    <Route path="new" element={<NewPost />} />
                </Route>
            </Routes>
        </Router>
    );
}

export default App;



要在Next.js中实现相同的结构,您只需要在彼此之间嵌套文件夹即可。要建立此路由模式,请首先在“应用程序”文件夹中创建一个名为“帖子”的新文件夹。在“帖子”文件夹中,您将创建一个负责显示所有帖子的页面(例如,Page.js)。


import React from 'react';

const Page = () => {
    return (
        <div>POSTS</div>
    );
}

export default Page;

要创建一个新的嵌套路由,请按照以下步骤:

  1. 在“帖子”文件夹中创建一个名为“新”的文件夹。

  2. 在“新”文件夹中,添加一个“ page.js”文件。

  3. 在“ page.js”中,创建一个用于处理新帖子创建的React组件。


import React from 'react';

const Page = () => {
  return (
    <div>
      NEW POST
    </div>
  );
};

export default Page;

这将在 /post /new中渲染。所有内容都在基于文件的系统上运行,因此您可以创建文件夹,并自动设置路由。

现在,随着我们的邮政应用程序的不断增长,我们不断添加一项新功能,并且需要被称为动态路由的东西。

动态路由涉及根据各种变量或数据创建网站页面,提供灵活的系统。而不是手动编写静态页面,例如“ myDirectory/mypage”,它保持不变,动态路由使网站能够根据用户的偏好在飞行中生成URL。为了说明在博客应用程序中,我们可以实现动态路线以显示特定的博客文章详细信息,例如 /post /:postid,where“:postid”可以动态地表示不同的博客文章,例如:
/posts/:postid i.e
/posts/:blog-post-1
/posts/:blog-post-2
/posts/:blog-post-3

为了实现这些反应,我们将有:


import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './pages/Home';
import NewPost from './pages/NewPost';
import Post from './pages/Post';

const App = () => {
    return (
        <Router>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="about" element={<Home />} />
                <Route path="posts" element={<Post />}>
                    <Route path="new" element={<NewPost />} /> // Nested Route 
                    <Route path=‘:postid element={<Post />} /> // Dynamic Route 
                </Route>
            </Routes>
        </Router>
    );
}

export default App;

在Next.js中,要实现相同的功能,请通过创建文件夹遵循类似的方法。但是,这次将其包裹在方括号[]中,例如“ [Postid]”。这表明它将是“帖子”文件夹中的动态ID。在此文件夹中,您可以创建一个常规的“ page.js”文件并开发功能组件:


import React from 'react';

const Page = ({ postid }) => {
  return (
    <div>{postid}</div>
  );
};

export default Page;

在“帖子”文件夹中,您可以选择创建一个“ layout.js” 文件。

layout.js 文件的目的是使不同路由之间的UI组件共享。例如,您可以使用以下逻辑创建一个新的React功能组件:


import React from 'react';

const Layout = () => {
  return (
    <div>Navigate to top</div>
  );
}

export default Layout;

您可以实现仅在“帖子”文件夹中的页面中重用组件的目标。通过将“ Layout.js”文件放置在“帖子”文件夹中,它将使用[postid],“ newPosts”文件夹以及“帖子”类别中的所有页面(例如“页面)中的所有页面访问。 JS。”

除了为每个子折叠器引入新布局外,您还可以合并 loader “ loading.js” 文件。加载功能将类似于这样:


import React from 'react';
import LoadingSkeleton from './LoadingSkeleton'; // Import your LoadingSkeleton component if needed

const Loading = () => {
  // You can add any UI of your choice, including a skeleton 
  return <LoadingSkeleton />; // Make sure to render your LoadingSkeleton or desired UI component
}

export default Loading;

此代码呈现一个加载骨架,该骨架可作为正在加载页面的视觉表示。它也可以充当通用旋转器。重要的是要注意,“ page.js”正在加载时,将显示“ loading.js”组件。

错误处理:在某些情况下,页面可能无法正确加载。在这种情况下,必须执行错误处理。优雅地处理错误涉及捕获这些错误,然后向客户端呈现有意义的错误消息。

在Next.js中,处理错误很简单,就像创建加载UI文件一样。要建立错误处理约定,您需要做的就是在“帖子”文件夹中创建一个“ error.js”文件。当发生错误时,此文件将自动执行,从而允许向用户出现错误的优雅表示。典型的错误文件可能显示如下:

use client // Error components must be client components

import React, { useEffect } from 'react';

const Error = ({ error, reset }) => {
  useEffect(() => {
    // Log the error to an error reporting service
    console.error(error);
  }, [error]);

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={() => reset()}>Try Again</button>
    </div>
  );
};

export default Error;

使用了这些唯一的文件名,您已经深入研究了Next.js的大多数功能。现在,您对现代Next.js应用程序的架构有全面的了解。

无服务器功能的API路由目录

在Next.js中,您定义了服务器端函数,可以通过http请求访问“ API”目录中的“ API”目录,通常位于您项目的应用程序目录中,以及诸如page.js和layout.js的文件。<<<<<<<<<<<<<<< /p>

Next.js提供了三个用于数据获取的选项。让我们逐一探索他们中的每一个,首先:

当然,这是以适当的降价方式格式化的提供的信息:

服务器端渲染(SSR)

服务器端渲染(SSR)是指动态服务器渲染的数据。它涉及每个请求新鲜获取数据。 SSR确保服务器的每个请求都会启动一个新的渲染周期和数据获取,从而始终保持最新内容。

这是一个快速示例:

async function Page({ params }) {
  const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`, { cache: 'no-store' });
  const data = await res.json();

  return (
    <div className="grid grid-cols-6 gap-x-6 gap-y-3">
      <div className="col-span-full space-y-3 lg:col-span-4">
        <h1 className="truncate text-2xl font-medium capitalize text-gray-200">{data.title}</h1>
        <p className="font-medium text-gray-500">{data.body}</p>
      </div>
    </div>
  );
}
  • 在异步函数“页面”中,我们旨在从JSON占位符API中检索数据。
  • 这是一个动态页面,我们通过页面的“参数”获得“ id”。
  • 使用“ {cache:'no store'}”,我们指示它不要存储数据,而是要获取并显示它。
  • 这种方法可确保它通过每个请求重新获取数据,从而实现服务器端渲染。

静态站点生成(SSG)

要启用静态站点生成(SSG),只需删除“ {cache:'no store'}”选项。

  • 默认情况下,Next.js使用SSG,它不仅从JSON占位符API等来源获取数据,而且还会填充它。
  • 这种方法非常适合保持相对静态的内容,例如博客文章,文档或营销页面。
  • 关于初始请求,它执行提取,存储数据并随后有效地显示。

增量静态生成(ISR)

,您可以使用一个称为“ Revalidate”的替代参数,例如:{next: {revalidate: 10}}。此参数提供了服务器端渲染(SSR)和静态站点生成(SSG)的独特混合物。

随着增量生成,您可以灵活地指定应在构建过程中静态获取哪些数据并建立重新验证时间间隔。这种方法涉及缓存数据,但在指定的时间范围后自动刷新数据,以确保您始终获得最新信息。这使其成为有效管理动态内容的最佳解决方案。

全栈功能

要在下一个应用程序中利用全堆栈功能。我们应该专注于利用无服务器路由处理程序。 Next.js使您可以使用基于文件的路由系统来管理HTTP请求并无缝构建后端功能,从而消除了对外部服务器的需求。

让我们探索使用常规express.js服务器创建简单获取请求路由所需的步骤:

  1. 首先导入所有必要的依赖项,包括Express。
  2. 然后,需要这些依赖性。
  3. 使用“ app.get('/api/users ...')”创建一个新路由。
  4. 确保您在此路线中返回所需的数据。
  5. 最后,让您的应用程序在特定端口上收听,因为服务器需要保持活动状态才能处理传入请求。

此示例说明了如何:

  • 建立一个express.js应用程序。
  • 使用GET请求定义专门针对用户的路由。
  • 当此路由收到GET请求时,它会执行关联的代码,然后返回用户数据。

const express = require('express');
const app = express();

app.get('/api/users', (req, res) => {
  // Handle GET requests for /api/users 

  const users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' },
    { id: 3, name: 'Bob' }
  ];

  // Send the users as a response 
  res.json(users);
});

Next.js包含传统后端服务器中通常存在的所有功能。这些包含:

  • 中间件集成
  • 数据解析功能
  • 身份验证检查
  • 用于简化部署和可扩展API路由管理的无服务器功能。

重要的是要注意,定义路由处理程序有两种不同的方法:

  1. 您可以在“ App Directory”中的“ API”文件夹中建立基于文件的路由处理程序。
  2. 另外,您可以直接在“应用程序目录”本身中创建直接路由处理程序。

但是,第二种方法有一个限制。要创建以“/”开头的路由,类似于常规页面,您必须创建一个特殊的“ route.js”文件以定义后端API路由。如果“ page.js”和“ route.js”都存在并共享相同的路由前缀,例如'/post',则Next.js可能会对它是标准前端页面还是后端API路由遇到歧义。这可能会导致“帖子”作为常规页面和“帖子”作为API路线之间的冲突。

>app
 >users
  >route.js
  >page.js

我建议使用第一种方法,在其中创建与“应用程序”根目录分开的API路由。通过保持与后端相关的逻辑和API文件夹中的API端点之间的清晰分离,这可以使您的代码保持清洁和理解。这样,很明显,您的应用程序的后端与“应用程序目录”中的所有其他内容不同,这增强了清晰度。
创建简单帖子API路由的过程将看起来像:

>api
 >users
  >route.js

现在,这将充当API后端路线。类似于“ error.js”,“ layout.js”,和“ loading.js”在“ page.js”,“ route.js”中也是一个专业的文件名,使您可以创建后端路由。

下面,Next.js为以下HTTP方法提供支持:

  • 获取:从服务器获取数据或资源。
  • 帖子:将数据发送到服务器以创建新资源。
  • put:修改或替换服务器上的现有资源。
  • 补丁:部分更新服务器上的现有资源。
  • 删除:从服务器中删除特定资源。
  • 头:检索资源的标题而不取出其身体。
  • 选项:为资源提供支持的HTTP方法和其他通信选择。

在“ route.js”文件中创建HTTP方法是一个简单的过程。您只需要编写一个“获取函数”并在其中实现您的后端功能:


export async function GET(request) {
  return new Response('Hello, Next.js!');
}

您也可以以类似方式在同一文件中使用HTTP动词:

export async function HEAD(request: Request) {}
export async function POST(request: Request) {}
export async function PUT(request: Request) {}
export async function DELETE(request: Request) {}
export async function PATCH(request: Request) {}

现在,要创建使用NextJS显示的先前端点,您只需要做:


export async function GET(request) {
  // Handle GET request for /api/users
  // Retrieve users from the database or any data source
  const users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Jane' },
    { id: 3, name: 'Bob' },
  ];
  // Send the users as a response
  return new Response(JSON.stringify(users));
}

检索用户并将其返回。您不必设置其他快速配置;专注于从特定端点获取所需数据,考虑业务逻辑,然后让Next.js照顾其余的详细信息。

要在浏览器的API中观察这一点,URL将显示如下:
//http://localhost:3000/api/users

对性能,SEO和UX的影响

搜索引擎将页面速度视为排名因素。加载的网站迅速在搜索结果中排名更高。 Next.js的服务器端渲染和静态站点生成功能可以通过更快地提供内容来提高SEO性能。

服务器端渲染(SSR)和客户端渲染(CSR)

React 18和Next.js 13引入了在两个环境中渲染组件的新方法:客户端和服务器。

默认情况下,在Next.js“ App”文件夹中创建的所有组件都是React Server组件(SSC)。这意味着Next.js使用服务器端渲染(SSR)来提高初始页面加载速度,从而改善了SEO和用户体验。

要将SSC更改为客户端组件(CSC),您可以在页面顶部添加“使用客户端”指令,将其转换为客户端组件。

利用服务器端组件(SSC)和客户端组件(CSC)使您能够享受SSR的优势,同时仍利用React的功能来构建动态和交互式用户界面。

这是服务器端组件(SSC)的典型示例:


import SearchBar from './SearchBar';
import Logo from './Logo';

export default function Counter() {
  return (
    <>
      <nav>
        <Logo />
        <SearchBar />
      </nav>

      <main>
        <p>This component will be rendered on the server side</p>
      </main>
    </>
  );
}

要将上面的代码段转换为客户端组件(CSC),您应该在组件顶部包括“使用客户端”。在使用状态,USESTATE和使用效果或其他客户端管理解决方案时,将组件声明为CSC至关重要。

use client

import SearchBar from './SearchBar';
import Logo from './Logo';

export default function Counter() {
  return (
    <>
      <nav>
        <Logo />
        <SearchBar />
      </nav>

      <main>
        <p>This component will be rendered on the server side</p>
      </main>
    </>
  );
}

在React,状态管理,包括使用钩子,主要发生在客户端,其中组件的状态在用户的浏览器中进行了管理和更新。

何时使用服务器与客户端组件

要简化服务器和客户端组件之间的决策,我们建议以下内容:

  • 首先使用服务器组件,这是“应用”目录中的默认行为,除非您特别需要客户端组件。
  • 有关何时使用客户端组件(CSC)和服务器端组件(SSC)的详细指导,请参阅documentation以获取有用的表。

简单的术语,让Next.js默认处理服务器端渲染。当您需要特定的反应功能(例如Usestate,使用效果或互动性)时,您只需添加“使用客户端”即可为这些特定组件启用客户端渲染。

如何改善NextJS应用程序的SEO:

我们可以通过两种方式定义元数据:

  • 静态
  • 动态

要以静态方式修改元数据,您需要执行以下操作:

export const metadata = {
  title: 'Home'
};

输出:


<head>
  <title>Home</title>
</head>

export default function Page() {
  return (
    <h1>My Next.js page with static metadata</h1>
  );
}

我们还可以利用动态元数据,这将显示出这样的东西:

export async function generateMetadata({params, searchParams}) {
const product = await getProduct(params.id);
return {title: product.title}
}

输出:


<head>
  <title>My Product </title>
</head>

export default function Page() {
  return (
    <h1>My Next.js page with dynamic metadata</h1>
  );
}

generatemetadata 获得动态参数,例如产品ID。

  • 基于产品ID,它称为“ GetProduct”功能。
  • 作为页面标题,它返回一个与特定产品标题相匹配的动态标题。

这种方法显着增强了SEO。

结论

典型的NextJS文件夹结构包括:


- /app
  - /api
    - /users 
      - route.js
  - page.js
  - layout.js
  - error.js
  - globals.css
- /public
  - ...
- /styles
  - ...
- /components
  - ...
- package.json
- next.config.js
- ...

将您的知识应用于Next.js中的现实世界项目是巩固您的技能的关键步骤。实践经验不仅增强了您的理解,还可以帮助您应对挑战,做出明智的决策,并创建有影响力的应用程序,以使用户受益并展示您的专业知识。因此,拥抱机会将您的知识转变为有形的项目,在此过程中,您将获得宝贵的见解并建立强大的工作组合。

归因

学分