最近在学习NextJS Version14的一些东西
学习资料来源于:《Next.js开发指南》——冴羽
拜读了第一节的内容,将个人比较在意的东西记录一下:
Next.JS CLI
next
命令就是来自于 Next.js CLI。Next.js CLI 可以帮助你启动、构建和导出项目。
完整的CLI命令,我们可以使用
npx next -h
来查看一些命令,我会挑出来讲解:
next build
运行之后的内容:
从上面这张图可以看出来,构建时会输出每一条路由的信息。
其中:
- first load JS:加载路由一共需要的JS大小也是加载该页面时下载的资源大小。总共有三种颜色,绿色,黄色,红色,绿色表示高性能,黄色或者红色就说明你的页面性能需要优化。
- Size:目标路由单独依赖的JS大小,导航到该路由时下载的资源大小,每个路由的大小只包括它自己的依赖项。
- First Load JS shared by all: 每个路由都需要依赖的JS大小,所有路由共享的 JS 大小会被单独列出来
解释:正常我们开发的 Next.js 项目,其页面表现类似于单页应用,即路由跳转(我们称之为“导航”)的时候,页面不会刷新,而会加载目标路由所需的资源然后展示,所以:
加载目标路由一共所需的 JS 大小 = 每个路由都需要依赖的 JS 大小 + 目标路由单独依赖的 JS 大小
也就是说!
First Load JS = Size + First load JS shared by all
build --profile
该命令参数用于开启 React 的生产性能分析(需要 Next.js v9.5 以上)。
有了这个功能之后呢,你就可以在生产环境里像开发环境那样使用Profiler了
小提一嘴:Profiler是什么?React.Profiler
允许你测量应用中一部分 UI 的渲染时间,这对于识别和优化性能瓶颈非常有用。
比如说我们这么做,写一个简单的Profiler client组件:
// Profiler.client.tsx
"use client";
import React, { ReactNode } from "react";
interface ProfilerProps {
children: ReactNode;
}
const Profiler: React.FC<ProfilerProps> = ({ children }) => {
return (
<React.Profiler
id="hello"
onRender={(id, phase, actualDuration) => {
console.log({ id, phase, actualDuration });
}}
>
{children}
</React.Profiler>
);
};
export default Profiler;
有什么用呢?我们在浏览器里安装react插件,在网站是react制作的时候,插件可以帮我调试程序。
一般来说,在npx next dev
的开发环境中,我们可以直接查看React Developer Tools的Profiler内容来获取信息
如果我们使用的一般的build的话
显而易见的,无法使用Profiler,在生产环境中不支持性能测量。
但如果你执行 npx next build --profile
再执行 npx next start
,尽管 React 插件会显示当前在生产环境,但 Profiler 是可以使用的:
这个功能可以帮助我们排查线上的性能问题。(!)
为了活用Profiler,我们完全可以使用React.Profiler
来包裹根组件或任何其他组件。这样做可以帮助我们监控整个应用的渲染性能,从根组件开始,包括所有子组件的渲染情况。这种方法非常适合于获得整体应用性能的概览,特别是在调试性能问题或者进行应用级性能优化的时候。
next build --debug
该命令参数用于开启更详细的构建输出
开启后,将输出额外的构建输出信息如 rewrites
、redirects
、headers
。
举个例子,我们修改下 next.config.js
文件:
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
async redirects() {
return [
{
source: "/index",
destination: "/",
permanent: true,
},
];
},
async rewrites() {
return [
{
source: "/about",
destination: "/",
},
];
},
};
module.exports = nextConfig;
输出内容:
多了rewrites和redirects的内容,这二者有啥作用,后续的文章会详细说明。
next dev
没啥好说的,就是运行程序,并且环境是开发环境。会自动具有热加载、错误报告等功能。默认的3000端口,如果要指定其他端口:
npx next dev -p 4000
如果你想更改主机名(hostname):(以便其他主机访问)
npx next dev -H 192.168.1.2
但是这个功能,请先参考自己的IP地址,修改为自己的IP才可以,并且访问的设备主机需要处于一个网络环境下。
题外话:因为本人之前在公司写项目的时候,项目负责人写了一个脚本,可以在运行代码的时候,终端打印出来本地和外部主机可以访问的两个地址,这边我很好奇,所以试着复刻了一下:
const { spawn } = require("child_process"); // 用于创建子进程
const os = require("os"); // 用于获取操作系统信息
// startDev.js
// 引入所需模块
// 获取本地 IP 地址
function getLocalIP() {
const interfaces = os.networkInterfaces(); // 获取所有网络接口信息
for (const name of Object.keys(interfaces)) {
// 遍历接口名称
for (const iface of interfaces[name]) {
// 遍历接口信息
if ("IPv4" === iface.family && !iface.internal) {
// 判断是否为 IPv4 地址且非内部地址
return iface.address; // 返回 IP 地址
}
}
}
return "localhost"; // 如果没有找到合适的 IP 地址,则返回 localhost
}
// 获取本地 IP 地址
const ip = getLocalIP();
// 设置端口号
const port = 3003;
// 设置启动参数
const args = ["dev", "--hostname", "0.0.0.0", "--port", port];
// 创建子进程并启动 Next.js 开发服务器
const nextDevProcess = spawn("next", args, {
stdio: ["inherit", "pipe", "pipe"], // 设置子进程的标准输入、输出和错误输出
});
// 监听子进程的标准输出
nextDevProcess.stdout.on("data", (data) => {
const output = data.toString(); // 将输出数据转换为字符串
// 重写 Next.js 默认的网络地址输出
const modifiedOutput = output.replace("http://0.0.0.0", `http://${ip}`);
process.stdout.write(modifiedOutput); // 将修改后的输出写入标准输出
});
// 监听子进程的错误输出
nextDevProcess.stderr.on("data", (data) => {
process.stderr.write(data); // 将错误输出写入标准错误输出
});
在package.json的scripts里面进行修改:
"dev": "node startDev.js",
唯一缺点:输出的信息的颜色消失了,不过应该不成大问题。各有所好吧
next start
生产模式下,使用 next start
运行程序。不过要先执行 next build
构建出生产代码。运行的时候,跟开发模式相同,程序默认开启在:
http://localhost:3000。
如果你想更改端口号:
npx next start -p 4000
next lint
执行 next lint
会为 pages/
、app/
、components/
、lib/
、src/
目录下的所有文件执行 ESLint 语法检查。如果你没有安装 ESLint,该命令会提供一个安装指导。如果你想要指定检查的目录:
npx next lint --dir utils
这样他就会专门去检查utils工具类文件夹下面的语法错误
next info
执行之后会把当前系统的相关信息打印出来,可以用于报告NextJS的程序bug。在项目的根目录执行
打印的结果如下:
这些信息可以贴到 GitHub Issues 中方便 Next.js 官方人员排查问题。