什么是serverless

  • “无服务器计算”(Serverless computing)
  • “无服务器函数”(Serverless functions)
  • “无服务器架构”(Serverless architecture)

通常在服务器上运行的代码被写成函数 → 这些函数会被打包,并由特定的动作“触发”。

传统上需要运行在服务器上的代码,通过无服务器架构被简化成一个个独立的函数。这些函数被部署到无服务器平台(如 AWS Lambda、Vercel 等),并且不需要开发者手动管理服务器。这些函数在特定的事件或操作(如 API 请求、文件上传、数据库更改)发生时自动触发并执行。

简单来说:

  • 写成函数:将服务器上的任务抽象成小的函数。
  • 打包和触发:这些函数被托管在云端,在需要时按需运行,而不是一直运行,节省资源和管理成本。

例如,当有人访问你的网站时,可以触发一个无服务器函数来生成页面内容并返回给用户。

什么是Next.js

Next.js 是一个基于 React 的现代前端框架,旨在简化 React 应用的开发,特别是针对服务端渲染(SSR)、静态生成(SSG)和 API 路由等功能的实现。它在 React 的基础上提供了一些开箱即用的功能,帮助开发者更高效地构建现代 Web 应用。

Next.js 与 React 的主要区别

  1. 用途和功能
    • React:React 是一个 JavaScript 库,专注于构建用户界面,特别是单页面应用(SPA)。它主要关注组件的声明式构建和 UI 的更新,而对于页面路由、数据获取、服务器端渲染等功能则没有直接的支持。
    • Next.js:Next.js 是一个基于 React 的框架,提供了更多的功能和开箱即用的解决方案,特别是服务端渲染(SSR)、静态页面生成(SSG)、API 路由等。Next.js 旨在简化 React 应用的构建过程,使开发者能够更方便地构建 SEO 友好、性能优化、可扩展的应用。
  2. 服务器端渲染 (SSR) 和静态生成 (SSG)
    • React:React 默认是客户端渲染(CSR)。当应用加载时,浏览器会下载 JavaScript 并在客户端渲染页面。这对于单页面应用(SPA)很有效,但不适合需要 SEO 或首次加载性能优化的场景。
    • Next.js:Next.js 支持 服务器端渲染 (SSR) 和 **静态生成 (SSG)**,这意味着页面可以在服务器端预渲染并发送到客户端,或者在构建时就生成静态页面,这对 SEO 和性能非常有利。
  3. 文件路由系统
    • React:React 本身不提供路由功能,通常需要与其他路由库(如 react-router)一起使用来管理页面间的导航。
    • Next.js:Next.js 自带一个基于文件系统的路由系统。你只需在 pages 目录下创建 .js 文件,Next.js 就会自动为你生成对应的路由。例如,pages/index.js 就是根路由 /pages/about.js 对应 /about
  4. API 路由
    • React:React 只专注于前端,不提供后端 API 的支持。如果你需要在 React 应用中使用后端 API,你通常需要自己设置一个后端服务器。
    • Next.js:Next.js 内建支持 API 路由,你可以在 pages/api 目录下创建服务器端的 API 路由文件,这些文件会被自动处理为 API 接口。例如,pages/api/hello.js 就可以定义一个 API 路由。
  5. 构建和优化
    • React:React 本身并不提供构建和优化工具,但你可以结合工具如 Webpack、Babel、Parcel 等来构建应用。
    • Next.js:Next.js 提供了内置的构建工具(如 Webpack 和 Babel 配置),并且它会自动优化你的应用。比如,自动拆分代码、懒加载页面、支持代码分割等功能。
  6. 增量静态生成(ISR)
    • React:React 没有直接的支持增量静态生成(ISR)。
    • Next.js:Next.js 提供 增量静态生成(ISR),它允许你在运行时更新静态页面,而无需重新构建整个站点。这样可以高效地更新内容并保证性能。

总结

  • React 只是一个构建 UI 的库,专注于前端开发,主要用于构建客户端应用。
  • Next.js 是基于 React 的框架,扩展了 React 的功能,提供了 SSR、SSG、API 路由、文件路由等特性,使得开发更加便捷,尤其是构建 SEO 友好、性能优化的网站和应用。

如果你需要构建一个具备复杂功能、优化性能和 SEO 的 React 应用,Next.js 是一个非常好的选择。

什么时候用Next.js

Next.js 是一个非常适合各种全栈应用的选择。以下是一些例子:

  • 与数据库进行交互
  • 使用某种认证机制
  • 拥有动态数据(根据需求变化)
  • 拥有 API 层(对内或对外)

渲染

Next.js 支持客户端渲染(CSR),并引入了 React 本身不具备的一种渲染形式——服务器端渲染(SSR)。目前,我们正在使用 React 和 Express 服务构建 Catbook,这是一种客户端渲染(CSR)的方法。那么,为什么要考虑使用 Next.js,而不是继续使用 React 和 Express 服务呢?

  • Next.js 抽象了构建服务器的过程 → 只需要编写函数即可。
  • 无需自行编写 Express 服务!
  • 敏感数据通过服务器层得到保护。
  • Next.js 会在服务器上预渲染 HTML 文档。
  • 确保客户端之间的一致性和正确性。

CSR(React and Express)

image-20241225053048786

image-20241225053059959

image-20241225053127300

SSR

image-20241225053149108

image-20241225053201227

为什么这很有优势?

  • 让服务器负责打包和构建我们的文档 → 服务器更接近数据,且更加一致可靠。
  • 客户端的性能因用户而异 → 不可预测,可能会变慢。
  • 当构建涉及敏感数据的复杂应用时,我们不能信任客户端。

我们在 Next.js 中会使用什么?

Next.js 提供了一种结合了 CSR 和 SSR 的“混合”方法,我们称之为 “React Server Components”(RSC)

具体是如何工作的?

我们将代码分为 客户端组件服务器端组件

与 CSR 或 SSR 有何不同?

  • RSC 允许客户端首先渲染客户端组件,同时等待服务器渲染服务器端组件。
  • 而不是等待服务器渲染所有内容,我们只在服务器上渲染必要部分,其余部分交由客户端处理。

React Server Components

客户端组件会发送到客户端,而服务器端组件会在服务器上渲染后再发送到客户端。

  • 这种混合方法提供了更好的用户体验 → 逐步呈现(piece-by-piece)而不是一次性呈现(all-in)。

image-20241225053502894

image-20241225053514010

image-20241225053534795

Next.js和serverless的关系

  1. 无服务器架构(Serverless)与 Next.js 的结合
    • Next.js 本身支持服务器端渲染(SSR)和静态生成(SSG),而 无服务器架构(如 AWS Lambda 或 Vercel)可以用来托管和运行这些 Next.js 应用的功能。
    • 通过将 Next.js 与无服务器架构结合,可以让你在没有管理传统服务器的情况下,自动根据需求扩展和处理请求。
  2. Next.js 在无服务器环境中的部署
    • 在无服务器架构下,Next.js 可以将页面或 API 路由部署为无状态的函数。这意味着,当用户访问页面时,Next.js 会根据请求动态生成页面并返回,同时可以自动扩展来处理流量的波动。
    • Next.js 的 API 路由(API Routes)非常适合与无服务器平台结合使用,可以通过简单的 HTTP 请求触发服务器端函数,而无需传统的服务器配置。
  3. 无服务器函数与 Next.js
    • 无服务器函数(如 AWS Lambda、Vercel 或 Netlify)可以用来处理 Next.js 中的某些动态功能。例如,当用户请求需要数据库查询或其他复杂处理的页面时,Next.js 会将这些请求委托给无服务器函数处理。
    • 这种方式减少了服务器维护的需求,简化了基础设施的管理。

总结

Next.js 和无服务器架构的结合让开发者能够构建高效、可扩展的应用,而无需担心传统服务器的维护。无服务器架构为 Next.js 提供了自动扩展、按需执行和高效的成本控制,使得全栈开发更简便且高效。

如何构建一个Next.js应用

使用终端创建骨架

1
npx create-next-app@latest

image-20241225061324864

项目结构

image-20241225061420702

只需要关注src文件夹和package.jsonpackage-lock.json即可

实时更改

1
npm run dev

Enter http://localhost:3000/ in your browser to view the Next.js boilerplate

简单应用

  • page.js

    • import StatementTable from "@/components/StatementTable";
      
      export default function Home() {
        return (
          <main className="flex min-h-screen flex-col items-center justify-between p-24">
            <section>
              <h1 className="font-bold text-4xl">Bank Statement Viewer</h1>
              <StatementTable />
            </section>
          </main>
        );
      }
      
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22

      - `StatementTable.js`

      - ```js
      import StatementItem from "./StatementItem";
      async function getStatementHistory() {
      const response = await fetch("https://api.sampleapis.com/fakebank/accounts");
      const data = await response.json();
      return data;
      }

      export default async function StatementTable() {
      const statementHistory = await getStatementHistory();
      return (
      <section className="w-full mt-4 p-4 bg-gray-900">
      {statementHistory.map((item, key) => (
      <StatementItem data={item} key={key} />
      ))}
      </section>
      );
      }

  • StatementItem

    • "use client";
      import { useState } from "react";
      export default function StatementItem({ data }) {
        console.log(data);
        const [category, setCategory] = useState(data.category);
        const desc = data.description;
        const date = data.transactionDate;
        return (
          <div className="p-2 bg-black">
            <input
              type="text"
              value={category}
              onChange={(e) => setCategory(e.target.value)}
              className="text-xl font-bold bg-transparent"
            />
            <p>{desc}</p>
            <span>{date}</span>
          </div>
        );
      }
      

use client

"use client" 在这个代码中有影响,它是 Next.js 中的一个特性,用于指示该组件应该在客户端(而不是服务器端)执行。这个声明通常用在 Next.js 13 和之后的版本,特别是在使用 React Server Components 时,目的是确保某个组件在客户端渲染。

影响:

  1. 客户端渲染
    use client 告诉 Next.js 这个组件必须在客户端渲染,而不是在服务器上渲染。如果你没有明确声明 use client,Next.js 可能会默认将其视为服务器端渲染组件,尤其是在混合使用 SSR 和 CSR 的项目中。对于包含 useStateuseEffect 等客户端特定代码的组件,必须显式地声明 "use client",否则会导致渲染错误或不按预期工作。
  2. React Hooks 使用
    由于组件中使用了 useState 和其他 React Hooks,use client 是必需的,因为这些 Hooks 只能在客户端执行。React Hooks 本质上是在客户端处理状态和副作用的,因此在这种情况下,use client 确保该组件在客户端运行。

总结:

"use client" 确保 StatementItem 组件在客户端渲染并能够正常使用 React 的客户端功能(如 useState),而不是在服务器端进行预渲染。没有这个声明,该组件可能会在服务器端引发错误,特别是因为它依赖于客户端状态和交互。