18-前端栈学习-Serverless_with_Next.js
什么是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 的主要区别
- 用途和功能
- React:React 是一个 JavaScript 库,专注于构建用户界面,特别是单页面应用(SPA)。它主要关注组件的声明式构建和 UI 的更新,而对于页面路由、数据获取、服务器端渲染等功能则没有直接的支持。
- Next.js:Next.js 是一个基于 React 的框架,提供了更多的功能和开箱即用的解决方案,特别是服务端渲染(SSR)、静态页面生成(SSG)、API 路由等。Next.js 旨在简化 React 应用的构建过程,使开发者能够更方便地构建 SEO 友好、性能优化、可扩展的应用。
- 服务器端渲染 (SSR) 和静态生成 (SSG)
- React:React 默认是客户端渲染(CSR)。当应用加载时,浏览器会下载 JavaScript 并在客户端渲染页面。这对于单页面应用(SPA)很有效,但不适合需要 SEO 或首次加载性能优化的场景。
- Next.js:Next.js 支持 服务器端渲染 (SSR) 和 **静态生成 (SSG)**,这意味着页面可以在服务器端预渲染并发送到客户端,或者在构建时就生成静态页面,这对 SEO 和性能非常有利。
- 文件路由系统
- React:React 本身不提供路由功能,通常需要与其他路由库(如
react-router
)一起使用来管理页面间的导航。 - Next.js:Next.js 自带一个基于文件系统的路由系统。你只需在
pages
目录下创建.js
文件,Next.js 就会自动为你生成对应的路由。例如,pages/index.js
就是根路由/
,pages/about.js
对应/about
。
- React:React 本身不提供路由功能,通常需要与其他路由库(如
- API 路由
- React:React 只专注于前端,不提供后端 API 的支持。如果你需要在 React 应用中使用后端 API,你通常需要自己设置一个后端服务器。
- Next.js:Next.js 内建支持 API 路由,你可以在
pages/api
目录下创建服务器端的 API 路由文件,这些文件会被自动处理为 API 接口。例如,pages/api/hello.js
就可以定义一个 API 路由。
- 构建和优化
- React:React 本身并不提供构建和优化工具,但你可以结合工具如 Webpack、Babel、Parcel 等来构建应用。
- Next.js:Next.js 提供了内置的构建工具(如 Webpack 和 Babel 配置),并且它会自动优化你的应用。比如,自动拆分代码、懒加载页面、支持代码分割等功能。
- 增量静态生成(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)
SSR
为什么这很有优势?
- 让服务器负责打包和构建我们的文档 → 服务器更接近数据,且更加一致可靠。
- 客户端的性能因用户而异 → 不可预测,可能会变慢。
- 当构建涉及敏感数据的复杂应用时,我们不能信任客户端。
我们在 Next.js 中会使用什么?
Next.js 提供了一种结合了 CSR 和 SSR 的“混合”方法,我们称之为 “React Server Components”(RSC)。
具体是如何工作的?
我们将代码分为 客户端组件 和 服务器端组件。
与 CSR 或 SSR 有何不同?
- RSC 允许客户端首先渲染客户端组件,同时等待服务器渲染服务器端组件。
- 而不是等待服务器渲染所有内容,我们只在服务器上渲染必要部分,其余部分交由客户端处理。
React Server Components
客户端组件会发送到客户端,而服务器端组件会在服务器上渲染后再发送到客户端。
- 这种混合方法提供了更好的用户体验 → 逐步呈现(piece-by-piece)而不是一次性呈现(all-in)。
Next.js和serverless的关系
- 无服务器架构(Serverless)与 Next.js 的结合:
- Next.js 本身支持服务器端渲染(SSR)和静态生成(SSG),而 无服务器架构(如 AWS Lambda 或 Vercel)可以用来托管和运行这些 Next.js 应用的功能。
- 通过将 Next.js 与无服务器架构结合,可以让你在没有管理传统服务器的情况下,自动根据需求扩展和处理请求。
- Next.js 在无服务器环境中的部署:
- 在无服务器架构下,Next.js 可以将页面或 API 路由部署为无状态的函数。这意味着,当用户访问页面时,Next.js 会根据请求动态生成页面并返回,同时可以自动扩展来处理流量的波动。
- Next.js 的 API 路由(API Routes)非常适合与无服务器平台结合使用,可以通过简单的 HTTP 请求触发服务器端函数,而无需传统的服务器配置。
- 无服务器函数与 Next.js:
- 无服务器函数(如 AWS Lambda、Vercel 或 Netlify)可以用来处理 Next.js 中的某些动态功能。例如,当用户请求需要数据库查询或其他复杂处理的页面时,Next.js 会将这些请求委托给无服务器函数处理。
- 这种方式减少了服务器维护的需求,简化了基础设施的管理。
总结
Next.js 和无服务器架构的结合让开发者能够构建高效、可扩展的应用,而无需担心传统服务器的维护。无服务器架构为 Next.js 提供了自动扩展、按需执行和高效的成本控制,使得全栈开发更简便且高效。
如何构建一个Next.js应用
使用终端创建骨架
1 | npx create-next-app@latest |
项目结构
只需要关注src
文件夹和package.json
或package-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 时,目的是确保某个组件在客户端渲染。
影响:
- 客户端渲染:
use client
告诉 Next.js 这个组件必须在客户端渲染,而不是在服务器上渲染。如果你没有明确声明use client
,Next.js 可能会默认将其视为服务器端渲染组件,尤其是在混合使用 SSR 和 CSR 的项目中。对于包含useState
、useEffect
等客户端特定代码的组件,必须显式地声明"use client"
,否则会导致渲染错误或不按预期工作。 - React Hooks 使用:
由于组件中使用了useState
和其他 React Hooks,use client
是必需的,因为这些 Hooks 只能在客户端执行。React Hooks 本质上是在客户端处理状态和副作用的,因此在这种情况下,use client
确保该组件在客户端运行。
总结:
"use client"
确保 StatementItem
组件在客户端渲染并能够正常使用 React 的客户端功能(如 useState
),而不是在服务器端进行预渲染。没有这个声明,该组件可能会在服务器端引发错误,特别是因为它依赖于客户端状态和交互。