Next.js 实战笔记 1.0:架构重构与 App Router 核心机制详解

上一次写 Next 相关的东西都是 3 年前的事情了,这 3 年里 Next 也经历了 2-3 次的大版本变化。当时写的时候 Next 是 12 还是 13 的,现在已经是 15 了,从 build 到实现都有一些重大变化,所以就想着重新过一下关键点

这部分内容没啥特别好的归纳,基本上学/写到哪里记到哪里

更多内容可以在官方文档里面看到,我觉得一个比较有用的部分是这个:**Project structure and organization,**里面讲了 Next 推荐的文件夹管理方式,以及路由、metadata、SEO 之类的关键信息

构造

早起的版本中 Next 还是使用 webpack 做 bundle 的,从 Next 12 之后慢慢引入了 Rust 编写的 SWC(Speedy Web Compiler),到现在的 15 版本,已经开始引入 turbopack 去渐渐代替 webpack

找到的资料说,dev 模式自动开启 turbo,不过我看了下,好像还是要手动开启:

yarn dev --turbo
yarn run v1.22.22
$ next dev --turbo▲ Next.js 14.0.3 (turbo)- Local:        http://localhost:3000✓ Ready in 2.4s❯ yarn dev
yarn run v1.22.22
$ next dev▲ Next.js 14.0.3- Local:        http://localhost:3000✓ Ready in 2.7s

可以看到有 --turbo flag 的才会开启 turbopack……

目前体感来说,使用 turbopack 会快不少,大概提速 30%-50%,不过我的练手项目都比较小,差别就在这几秒或者是几百毫秒的差别,不足以大到让我有明显的体感上的差别

❗ 看了一下,大概是 next 的 config 文件里面没有配置,所以默认 dev 没有开启 turbo

app router vs page router

新版的项目结构也有了一些的变化,比如说之前的 directory 叫 page,现在改成了 app 。Next 还有一个选项是把所有的代码包在 src 下面,我没选那个,这里提一句

这种转变,实际上是 Next 内部中实现的转变,即从 page router 转成了 app router,现在推荐使用的是 app router,因为 Next 基于 app router 实现了很多新的功能,同样也是未来的转变方向

二者核心对比:

功能Page Router (pages/)App Router (app/)
路由机制文件系统自动生成路由文件系统自动生成嵌套路由
支持 Layout❌ 仅支持 _app.js 全局包装✅ 支持嵌套 layout.tsx
支持 Server Components❌ 仅客户端组件(可用 SSR)✅ 默认是 Server Component
支持 Streaming❌ 不支持✅ 支持分块传输 / loading UI
Data fetchinggetServerSideProps, getStaticProps, getInitialPropsfetch() in Server Component
Middleware 支持
动态路由[id].js[id]/page.tsx
API Routespages/api/*✅ 仍使用 pages/api/*
文件结构限制只有一个页面文件允许多个文件组合构成页面(如 loading.tsx, error.tsx
状态成熟度✅ 成熟稳定🚧 仍在改进(尤其是缓存行为)

server component

这应该是 page router 和 app router 最大的区别了,旧版的 page router 中,默认的还是 client side rendering,在 build 的阶段将数据写入 HTML 中。新版的 app router 则是 app 文件夹下默认所有的组件都在服务端生成,其中的一些状态和日志不会在 client 端显示,只会在服务端显示,如下面这个 log:

page.js should render as page, and is server component, which will be rendered at server

前面的 server 标记了是 server 端的内容,在正式打包后就会被去除

另一个需要注意的是,server component 不能用 hooks,这是 client component 专用的。如果要使用 hooks 的话,需要在文件头标注 use client;,这样这个组件下所有的内容都会在 client 端生成,否则就会报错:

如果想要利用好 Next 的 server side rendering,那么就尽可能的抽象组件,尽可能的在末端使用 use client

路由

基础的路由比较简单,新加一个文件夹,并且创建对应的 page.js 文件即可:

动态路由

根据官方文档显示,显示的 directory 的名称应该如下:

[folder]Dynamic route segment
[...folder]Catch-all route segment
[[...folder]]Optional catch-all route segment

并且在对应的文件夹下创建 page.js 文件即可

路由组与私有路由

根据官方文档,实现如下:

(folder)Group routes without affecting routing
_folderOpt folder and all child segments out of routing

layout

这个也是 Next 提升了很多的地方,这是目前 template 中的 layout:

import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";const geistSans = Geist({variable: "--font-geist-sans",subsets: ["latin"],
});const geistMono = Geist_Mono({variable: "--font-geist-mono",subsets: ["latin"],
});export const metadata: Metadata = {title: "Create Next App",description: "Generated by create next app",
};export default function RootLayout({children,
}: Readonly<{children: React.ReactNode,
}>) {return (<html lang="en"><bodyclassName={`${geistSans.variable} ${geistMono.variable} antialiased`}>{children}</body></html>);
}

其中, metadata 就是当前页面绑定的关键词,这也是个保留词。使用当前 layout 的所有页面,都会共享这里面的布局和 metadata

除此之外,Next 做的改进就是,每个文件夹下面都可以有它独立的 layout,这是不影响外层布局的。如果有这个需求的话,这个用途/设定挺好的

Image

Next15 也对其做了不少的改进,之前主要用的是 lazy loading 的特性,这次发现了一个 priority,即与 lazy loading 相反的特性,很适合加在 logo/banner 等地方

加载数据

现在 Next 所有的组件默认都是 server component 了,因此也不太需要使用 useEffect 去渲染数据,而是可以直接创建新的 async 组件,如:

const Meals = async () => {const meals = await getMeals();return <MealsGrid meals={meals} />;
};

加载状态

这里我主要新创建了一个 loading.js 文件,然后搭配了 Suspense 使用:

import React from "react";
import classes from "./loading.module.css";const MealsLoadingPage = () => {return <div className={classes.loading}>Fetching meals...</div>;
};export default MealsLoadingPage;
const MealsPage = () => {return (<><header className={classes.header}><h1>Delicious meals, created{" "}<span className={classes.highlight}>by you</span></h1><p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Magnamvoluptatibus fuga voluptas temporibus porro consequatur totam nihilquae omnis eos blanditiis asperiores, repudiandae itaque officiaoptio? Repudiandae recusandae sit sequi?</p><p className={classes.cta}><Link href={"/meals/share"}>Share Your Favorite Recipe</Link></p></header><main className={classes.main}><Suspense fallback={<MealsLoadingPage />}><Meals /></Suspense></main></>);
};

效果如下:

如果不使用 Suspense 的话,那么整个页面都会被 loading.js 所接管

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90053.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90053.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/90053.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pillow 安装使用教程

一、Pillow 简介 Pillow 是 Python 图像处理库 PIL&#xff08;Python Imaging Library&#xff09;的友好分支&#xff0c;是图像处理的事实标准。它支持打开、编辑、转换、保存多种图像格式&#xff0c;常用于图像批量处理、验证码识别、缩略图生成等应用场景。 二、安装 Pi…

SQL Server从入门到项目实践(超值版)读书笔记 20

9.4 数据的嵌套查询所谓嵌套查询&#xff0c;就是在一个查询语句中&#xff0c;嵌套进另一个查询语句&#xff0c;即&#xff0c;查询语句中可以使用另一个查询语句中得到的查询结果&#xff0c;子查询可以基于一张表或者多张表。子查询中常用的操作符有ANY、SOME、ALL、IN、EX…

【MySQL\Oracle\PostgreSQL】迁移到openGauss数据出现的问题解决方案

【MySQL\Oracle\PostgreSQL】迁移到openGauss数据出现的问题解决方案 问题1&#xff1a;序列值不自动刷新问题 下面SQL只针对单库操作以及每个序列只绑定一张表的情况 -- 自动生成的序列&#xff0c;设置序列值 with sequences as (select *from (select table_schema,table_…

【Maven】Maven命令大全手册:28个核心指令使用场景

Maven命令大全手册&#xff1a;28个核心指令使用场景 Maven命令大全手册&#xff1a;28个核心指令深度解析一、构建生命周期核心命令1. mvn clean2. mvn compile3. mvn test4. mvn package5. mvn install6. mvn deploy二、依赖管理命令7. mvn dependency:tree8. mvn dependency…

大语言模型(LLM)按架构分类

大语言模型&#xff08;LLM&#xff09;按架构分类的深度解析 1. 仅编码器架构&#xff08;Encoder-Only&#xff09; 原理 双向注意力机制&#xff1a;通过Transformer编码器同时捕捉上下文所有位置的依赖关系# 伪代码示例&#xff1a;BERT的MLM任务 masked_input "Th…

MySQL(120)如何进行数据脱敏?

数据脱敏&#xff08;Data Masking&#xff09;是指通过某种方式对敏感数据进行变形&#xff0c;使其在使用过程中无法识别原始数据&#xff0c;从而保护数据隐私。数据脱敏通常应用在开发、测试和数据分析等场景中。下面我们详细介绍如何在Java应用程序中进行数据脱敏&#xf…

使用 Dockerfile 构建基于 .NET9 的跨平台基础镜像

官方基础镜像准备 微软官方 dotnet sdk 基础镜像&#xff1a; docker pull mcr.microsoft.com/dotnet/sdk:9.0拉取 ubuntu 镜像&#xff1a; docker pull ubuntu:24.04更多资源请参考&#xff1a; dotnet sdk images&#xff0c;https://mcr.microsoft.com/en-us/artifact/mar/…

C++ : 线程库

C : 线程库一、线程thread1.1 thread类1.1.1 thread对象构造函数1.1.2 thread类的成员函数1.1.3 线程函数的参数问题1.2 this_thread 命名空间域1.2.1 chrono二、mutex互斥量库2.1 mutex的四种类型2.1.1 mutex 互斥锁2.2.2 timed_mutex 时间锁2.2.3 recursive_muetx 递归锁2.2.…

idea的使用小技巧,个人向

idea的使用小技巧&#xff0c;个人向 一、前言二、过程1、显示内存的使用情况2、去掉xml文件中的黄色背景3、显示所有打开文件4、显示工具栏到菜单下面5、使用JDK8 一、前言 每次重装idea都需要重新设置一下&#xff0c;这里做个记录。 这些技巧只是个人感觉的好用 演示用的…

debian及衍生发行版apt包管理常见操作

好的&#xff0c;这是 Debian 及其衍生版&#xff08;如 Ubuntu&#xff09;使用的 apt 包管理器的常用命令速查表。 一点说明&#xff1a;apt 是新一代的命令行工具&#xff0c;整合了 apt-get 和 apt-cache 的常用功能&#xff0c;并提供了更友好的交互体验。本表主要使用现…

vue调用函数

好的&#xff0c;我们来讲解如何在 Vue 模板中调用函数。您提供的代码是一个非常棒的、很实用的例子。 在 Vue 模板中&#xff0c;你可以在两个主要地方调用函数&#xff1a; 文本插值中&#xff1a;像 {{ formatDate(date) }} 这样&#xff0c;函数的返回值会作为文本被渲染到…

前端常用构建工具介绍及对比

打包构建工具是现代软件开发中必不可少的,它们帮助开发者自动化构建、打包、部署等流程,提升开发效率。不过,不同时期构建工具略有差异。 每个构建工具都有其擅长的领域,我们需要知道其优势,才能在我们实际开发中选择合适的构建工具进行构建处理。 1. Gulp Gulp 是一个…

Web后端开发-SpringBootWeb入门、Http协议、Tomcat

文章目录Web后端开发简介SpringBootWeb入门HTTP协议HTTP-概述HTTP-请求协议HTTP-响应协议HTTP-协议解析Web服务器-Tomcat简介基本使用SpringBootWeb入门程序解析Web后端开发简介 SpringBootWeb入门 package com.wuxuan.javaweb_wushuang.controller;import org.springframework…

物联网通信技术全景剖析:从LoRa到5G的深度对比与选型指南

物联网通信技术全景剖析&#xff1a;从LoRa到5G的深度对比与选型指南在万物互联时代&#xff0c;选择合适的通信技术如同为设备构建“神经网络”。本文将深入解析七大主流物联网通信技术&#xff0c;助您在技术选型中精准决策。一、低功耗广域网&#xff08;LPWAN&#xff09;技…

俄罗斯方块AI深度解析:从算法原理到实现细节

俄罗斯方块AI深度解析:从算法原理到实现细节 前言 俄罗斯方块,这个诞生于1984年的经典游戏,至今仍然是人工智能研究领域的热门课题。当简单的几何形状在网格中不断下落时,看似简单的规则背后却隐藏着复杂的策略决策问题。本文将深入剖析一个基于Python实现的俄罗斯方块AI…

Spring Boot 框架创建一个简单的后端接口,并介绍如何使用 Apifox 连接该接口

目录 一、配置 二、使用 IntelliJ IDEA 创建 Spring Boot 项目 1.打开 IntelliJ IDEA&#xff0c;选择 File > New > Project 2.在左侧面板选择 Spring Initializr&#xff0c;项目名称设置为HelloWorldAPI 3.点击 Create 完成项目创建 三、创建控制器类 四、运行项…

CICD[导航]、docker+gitlab+harbor+jenkins从安装到部署

一、安装 CICD[软件安装]&#xff1a;docker安装gitlab-CSDN博客 CICD[软件安装]&#xff1a;ubuntu安装jenkins-CSDN博客 CICD[软件安装]&#xff1a;ubuntu安装私有镜像仓库-Harbor-CSDN博客 CICD[软件安装]&#xff1a;ubuntu24安装Docker-CSDN博客 二、镜像执行 CICD[…

深度学习图像分类数据集—蘑菇识别分类

该数据集为图像分类数据集&#xff0c;适用于ResNet、VGG等卷积神经网络&#xff0c;SENet、CBAM等注意力机制相关算法&#xff0c;Vision Transformer等Transformer相关算法。 数据集信息介绍&#xff1a;蘑菇识别分类&#xff1a;[Agaricus, Amanita, Boletus, Cortinarius, …

iOS 多线程导致接口乱序?抓包还原 + 请求调度优化实战

在一次性能优化过程中&#xff0c;我们将 iOS App 内多处请求改为并行处理&#xff0c;以提高页面加载速度。但上线后却收到部分用户反馈&#xff1a;进入页面后数据加载错乱&#xff0c;有时展示前一次页面内容&#xff0c;有时同一个接口请求重复返回不同内容。 日志仅显示正…

PDFBox 在 Linux 报 “No glyph for U+535A (博)” —— 一次子集化踩坑与完整排查清单

PDFBox 在 Linux 报 “No glyph for U535A (博)” —— 一次子集化踩坑与完整排查清单关键词&#xff1a;PDFBox、PDType0Font、子集嵌入&#xff08;subset embedding&#xff09;、SimHei、思源黑体、字体回退1. 背景业务场景 后端使用 Apache PDFBox 填充含 AcroForm 的中文…