link: NextJSReact

可参考:

默认 next 命令 build、start、dev

next build

构建你的 Next.js 应用以供生产环境使用。

  • 生成静态 HTML 和 JSON 文件(针对静态生成的页面)。
  • 创建服务器端的 JavaScript 文件(针对服务器端渲染的页面和 API 路由)。
  • 执行代码分割,为每个页面生成单独的 JavaScript 包。
  • 优化性能,包括最小化代码和生成资源映射。
  • 准备好所有需要在生产环境下运行的文件和结构。

next start

在生产模式下启动一个 Next.js 应用

  • 启动一个 Node.js 服务器来服务你的 Next.js 应用。
  • 使用 next build 命令创建的优化过的构建文件来服务应用。
  • 处理生产环境下的请求,包括页面渲染、API 路由等。

next dev

在开发模式下启动一个 Next.js 应用。

  • 启动一个热重载的开发服务器,可以自动响应代码的更改并刷新页面。
  • 提供源代码映射和易读的错误消息,帮助开发和调试。
  • 不进行代码分割、最小化或任何生产优化。

根节点 Context

// layout.tsx
 
import ThemeProvider from './theme-provider'
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  )
}

"use client"声明的组件,会画一条分界线,把这个组件及其子组件都变成客户端组件,而这里ThemeProvider包裹了所有children,那不就变成所有页面都是客户端组件了吗? 其实不是,ThemeProvider在这里其实只是提供了一个插槽,只能决定子元素的位置,而不能决定子元素的渲染方式。

非全栈项目中 Api Router 的作用

  1. 作为Node BFF,封装需要在服务端处理的业务逻辑,减少Client打包体积
  2. 作为网关代理,隐藏真实的后端 API 接口地址
  3. 解决接口跨域请求问题

服务器组件的优势

  • 数据获取方便(可直接从数据库或者其他数据源获取
  • 安全,服务器组件是在服务器中渲染的,所以可以安全的使用 API 令牌、密钥等而不用担心泄露
  • 缓存,服务端渲染的结果、接口等可以被缓存,对于经常被访问的页面,可以存储已经生成的 HTML,加快加载速度
  • 打包体积,一些库或框架可能非常大,如果全部发送到客户端,会增加首次加载时间。通过在服务器上使用这些库,你可以避免增加客户端的包大小。
  • 首屏加载:服务端渲染的页面可以立即为用户提供可见的内容,而不必等待客户端JavaScript加载和执行。
  • SEO搜索引擎优化
  • 流式传输

服务器组件和客户端组件使用场景

NextJS 区分客户端组件与服务端组件

token 存储

SSRSPA 最大的区别就是 SSR 会区分客户端 client 和 服务端 server,并且 SSR 之间只能通过 cookie 才能在 ClientServer 之间通信,例如 token 信息,以前写 SPA 项目的时候一般存储在 localStorage 中,但是在 SSRServer 端是拿不到的,因为 localStorage 只存在浏览器中。想要在 客户端和服务端都可以获取到 token ,只能存储到 cookie 中。

尽量将查询请求放在服务端组件

为什么?首先 Nextjs 是一个 SSR 框架,它存在的意义就是提供了服务端直出 html 的能力,如果使用 Nexjs 框架却不使用服务器组件,那就完全失去了使用 Nextjs的意义,不如直接用 SPA实现。

服务端生成页面信息,直接返回 HTML,利好 SEO;
减少客户端和服务端之间的来回通信,加快响应时间
减少发送到客户端的 JavaScript代码,加快页面渲染速度,减少因网络原因导致的页面渲染慢
安全性 ,防止敏感信息泄漏
巴拉巴拉……

NextJs 配合 TailwindCSS 实现自定义字体加载和使用

// TODO

Image

TODO:为什么不要用 img 而要使用 Image
TODO: local image 与 src image 的区别
TODO:如何将大图上传到 CDN

部署

TODO: pm2 配置与环境变量

TODO:静态资源目录上传 CDN

TODO: tailwindcss bg-[] 的使用导致的打包问题

打包到 css 文件会变成 bg-[url(/image/xxx/xxx.png)]

TODO: standalone 独立模式 多台机器部署

TODO: healthz 探针 API 路由

TODO: 关于独立打包和public文件夹处理
next.config.js Options: output | Next.js
All static assets (js/css/media) in Standalone mode become 404 · Issue #49283 · vercel/next.js · GitHub
NextJS with Standalone Mode

NextJS 在服务器组件中获取当前URL

在 NextJS 服务器组件中想要获取到当前用户请求的 URL,一般会选择将组件转换为客户端组件,然后使用 usePathname 来获取URL。如果不想将服务器组件装换为客户端组件,可以配合 middleware 中间件来实现

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
 
export function middleware(request: NextRequest) {
  // 添加一个新的头部 x-current-path,将路径传递给下游组件。
  const headers = new Headers(request.headers);
  headers.set("x-current-path", request.nextUrl.pathname);
  return NextResponse.next({ headers });
}
 
export const config = {
  matcher: [
    // match all routes except static files and APIs
    "/((?!api|_next/static|_next/image|favicon.ico).*)",
  ],
};

在服务器组件中获取当前URL

import { headers } from "next/headers";
 
export default async function Sidebar() {
  const headerList = headers();
  const pathname = headerList.get("x-current-path");
 
  // ...etc
}

来源:Getting the Current URL in Next.js Server Components | PropelAuth Blog

NextJS 常规性能优化

NextJS 性能优化

安全

Server Action 安全

Should I always validate if the user is logged in before running a server action? : r/nextjs
How to Think About Security in Next.js | Next.js

注意 server action 本质上是一个公共的API,你需要在 server action 中进行身份验证