NextJS是Vercel维护并开源的一个基于React的全栈Web开发框架,同时也是React官方推荐使用的框架之一。NextJS框架集成了前端工程中常用的路由、样式加载、代码打包、JSX转译等各种组件,此外还包含了很多高级特性,包括混合渲染模式、增量静态生成、基于文件系统的路由、后端开发功能等。
目前NextJS最新版本为13.4
,这个版本引入了AppRouter的概念,相比之前的PageRouter使用方式变化较大。后续章节都会以最新版为例进行介绍。
官方网站:https://nextjs.org/
客观的来说,NextJS的优点是功能全面且集成度高,它包含了一套最现代化的Web开发解决方案,不过相对应这也是它的缺点,集成度高意味着学习曲线陡峭,使用不灵活、兼容性差。NextJS上手难度较高,需要开发人员同时掌握前后端开发知识,虽然NextJS官方文档更新及时而且非常详细,但坏消息是没有中文文档。
此外还要说明的是,当前新版本NextJS13引入的AppRouter导致近期NextJS的API变化极大,这给NextJS生态造成了巨大的撕裂,开发人员在使用上和检索相关问题时都有一定困难,AppRouter在细节上相比旧版反而还丢失了一些重要的特性,虽然基本可用,但还是有待官方后续补充完善。
如果开发博客、新闻网站、门户网站等,对于这类网站使用NextJS开发是非常合适的,这类网站能够充分利用NextJS的混合渲染,对页面响应速度和SEO都有帮助。然而对于管理后台的前端工程、Electron工程等,虽然使用NextJS也能开发纯客户端渲染(CSR)的Web应用,但这样就失去了使用NextJS的优势,还可能遭遇组件库兼容问题,纯CSR工程有很多更好、更灵活的选择,例如CRA、UmiJS等。
NextJS13.4需要Node16.8及以上版本,准备好NodeJS环境后执行以下命令创建NextJS工程:
npx create-next-app@latest
该命令是交互式的,需要我们选择一些配置,我们根据实际情况选择即可。默认创建的工程目录结构如下:
|_node_modules
|_public
|_app // 页面根目录,包含一个示例页面
|_page.js // 页面JSX
|_layout.js // 布局JSX
|_page.module.css // 可以通过CSS Module引入的样式
|_global.css // 全局样式
|_favicon.ico // 图片
|_next.config.js // NextJS框架配置
|_jsconfig.json
|_package.json
|_README.md
创建工程过程中,我们可以选择将所有源码放在src
文件夹下或者不创建src
文件夹,我这里没有创建src
文件夹。默认创建的文件中包含了一个例子页面,我们可以参考这个例子页面学习如何在NextJS中使用页面、布局、CSS Module等功能。
默认创建的NextJS工程中包含3个npm script配置:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
dev:以开发模式启动工程,修改源代码会触发重新构建和自动刷新浏览器
build:构建工程
start:以生产模式启动工程
我们可以尝试执行npm run dev
启动工程并用浏览器访问http://localhost:3000
查看演示页面。
NextJS工程推荐使用VSCode进行开发,不需要安装额外插件,直接打开工程即可(如果使用TailwindCSS则需要安装TailwindCSS的提示插件)。我们这里根据官方文档创建.vscode/launch.json
配置文件,其中Next.js: debug server-side
用于调试服务端组件,Next.js: debug client-side
用于Chrome浏览器调试客户端组件。实际开发时,我们可以同时启动这两个调试配置。
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node-terminal",
"request": "launch",
"command": "npm run dev"
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
}
]
}
服务端组件我们直接在VSCode内设置断点即可。
客户端组件则可以在Chrome浏览器中断点调试。
在开发过程中,NextJS默认在3000
端口启动启动调试服务器,如果我们在同一台电脑上运行其它服务端程序就要另选端口,服务端程序也可能位于测试环境的服务器上,此时调用服务端接口可能有跨域问题。一般来说解决这个问题需要配置前端工程调试服务器的反向代理。NextJS中,我们可以如下配置。
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: "/api/:path*",
destination: "http://127.0.0.1:8000/api/:path*",
},
{
source: "/media/:path*",
destination: "http://127.0.0.1:8000/media/:path*",
},
];
},
};
module.exports = nextConfig;
上面例子代码中,我们配置了两条反向代理,rewrites
即是重写(和Nginx中的概念一样),我们将/api/
和/media/
开头的请求都代理到了本机8000
端口的后端服务上。
前面我们提到过,NextJS比较适合门户、新闻、博客等类型网站的开发(也就是C端),而不适合管理后台的开发,管理后台也完全没必要使用SSR、SSG、混合渲染这些高级特性,这些功能都是为了保证C端用户体验而设计的,这也是为什么很多国内流行的大型组件库没有对NextJS较好兼容的原因,C端网页通常没必要使用AntDesign这类组件库,管理后台又用不上NextJS。(当然,也不是说NextJS不能使用AntDesign等组件库,它可能需要一些额外配置,以及要踩一些坑)。
使用NextJS进行开发时,我们可能不需要组件库,也可能会使用NextUI这类设计比较轻量级,针对NextJS兼容的组件库(它有一些bug,但也算基本可用)。总而言之,我们要根据使用场景,合理选择一个适合当前项目的框架。