看了就会的Next.js SSR/SSG 实战教程

卧梅又闻花

共 6958字,需浏览 14分钟

 · 2022-08-24




Next.js是基于React的服务端渲染工具。在传统的React项目中,例如使用Create-React-App创建的项目,最终build生成的静态文件,是基于浏览器渲染的,即所谓的CSR(Client-side Rendering)。CSR往往都是单页面应用,即一个HTML文件和若干个js、css文件。打开build后的HTML文件,发现代码很简单,页面和组件的元素都是放在了js里,由js动态渲染到HTML中。CSR模式是目前前端开发项目中应用最为广泛的。但有些也场景,特别是需要SEO优化的时候,CSR就不太合适了,所以服务端(Server-side Rendering)渲染应运而生,SSR是由服务器将用户请求的页面DOM组装好后,再返回给浏览器,因此通过“查看网页源代码”,是可以看到完整的页面DOM的。而SSG(Static Site Generation),顾名思义就是静态网站生成,也就是常说的“网页静态化”,除了适合SEO,还很方便CDN加速,比较适合内容相对比较固定的资讯发布类网站。


以下是关于CSR、SSR、SSG的简单对比:


CSR
SSRSSG
运行端浏览器服务器服务器
静态文件单页面由服务器即时生成多个页面
SEO不适合适合适合
静态文件CDN适合不适合适合
适用场景中后台产品信息展示型网站内容较为固定的资讯类网站


本教程基于Next.js技术框架,通过一个简单的实战项目,将工程搭建、开发、部署、自动化等环节完整讲述。如果你正在做类似CMS的项目,并且需要将网页内容静态化。那本教程将非常适合你。SSR与SSG在开发过程中几乎是完全一样的,只是最终部署的环境有所不同。掌握了SSG,那SSR也同样不在话下。


以我的个人经验来讲,从零基础学习一个新的框架,最佳的方法是结合项目边做边学,官方技术文档比较适合做手册来查阅。脱离了实战项目,只看官方技术手册,很难掌握。因此,本教程就是以实战项目的角度,把官网技术文档的主要内容串起来。相信按照本教程操作一遍之后,就能快速掌握Next.js。再回过头去系统地看一遍官方技术手册,那就会更加深入理解。


先睹为快


先看下目录了解本教程都有哪些内容。

1 创建Next.js项目

• 1.1 安装Next.js

• 1.2 设置项目目录

• 1.3 项目入口文件

• 1.4 精简项目

2 配置项目

• 2.1 设置路径别名

• 2.2 配置SourceMap(不建议设置)

• 2.3 设置页面title

• 2.4 设置HTML框架代码

• 2.5 以SSR模式运行项目

• 2.6 设置404/500页面

3 CSS预处理及使用

• 3.1 集成Sass/Scss

• 3.2 集成Less(选读)

• 3.3 集成Stylus(选读)

• 3.4 关于样式命名规范

• 3.5 配置全局样式

• 3.6 配置页面(pages)样式

4 页面路由

• 4.1 优化index页面和样式文件的存放位置

• 4.1.1 方法一:通过next.config.js配置

• 4.1.2 方法二:通过组件引入(推荐)

• 4.2 创建About页面

• 4.3 使用next/router和next/link构建导航组件

5 图片引用

• 5.1 方法一:使用原生<img>标签引入图片

• 5.2 方法二:使用next/image引用图片

6 生成静态化网站(SSG)

• 6.1 设置SSG的export命令

• 6.2 设置静态资源的basePath

• 6.3 设置SSG export输出的目录名称

7 接口请求

• 7.1 CSR/SSR/SSG 三种API请求方式

• 7.2 搭建服务端API服务

• 7.3 构建Profile页面

• 7.4 getServerSideProps和getStaticProps小节

• 7.5 搭建Next.js API Routers服务(选读)

8 动态路由

9 使用CLI命令动态生成目录

10 其他说明

11 项目Git源码


本次分享Demo的主要依赖包版本:

Node.js 16.16.0next 12.2.5react 18.2.0react-dom 18.2.0axios 0.27.2

※注:

代码区域每行开头的:

"+" 表示新增

"-" 表示删除

"M" 表示修改


1 创建Next.js项目


1.1 安装Next.js


找个合适的目录,执行:

npx create-next-app next-ssg

next-ssg是项目名称,可根据需要自行更改。


安装完成后,进入next-ssg,运行:

yarn dev

浏览器打开http://localhost:3000/,项目运行成功。


1.2 设置项目目录


Next.js官方脚手架初始目录结构如下:

├─ /.next              <-- 用于SSR运行的工程,执行yarn dev或yarn build后才会出现├─ /node_modules├─ /pages              <-- Next.js指定的页面目录|  ├─ /api             <-- Next.js指定的API服务目录,可以删除|  |  └─ hello.js      <-- API服务的hello接口|  ├─ _app.js          <-- Next.js指定的项目入口文件|  └─ index.js         <-- 项目首页├─ /public             <-- 静态目录,放在这里的文件可通过"/"直接访问(没有public这一层级)|  ├─ favicon.ico|  └─ vercel.svg├─ /styles             <-- 项目全局样式|  ├─ globals.css|  └─ Home.module.css  <-- Home组件样式├─ .eslintrc.json├─ .gitignore├─ next.config.js      <-- Next.js配置文件├─ package.json├─ README.md└─ yarn.lock


以上目录结构并没有看到src目录,这与日常项目的开发习惯不一致。如果希望保持一致的开发体验,仍然可以使用src做为开发目录。


按照以下步骤重新组织目录结构:

1. 停止项目运行

2. 在项目根目录新建src目录

3. 把pages、styles两个目录放到src目录里

4. 删除pages里的api目录(后续章节讲到API请求时再创建)


再执行yarn dev,项目依然正常运行。


为什么变更了目录结构,项目还可以正常运行?

Next.js的官方脚手架虽然没有src目录,但考虑到src目录是普遍存在于大多数脚手架工程中,所以Next.js也对src目录做了支持。当然,如果新建的不是src目录,把pages、styles放进去是无法被正确识别的。


关于src目录,官方的规则如下:

1. 如果根目录下有pages,则src/pages将被忽略。

2. public目录以及next.config.js、jsconfig.json、tsconfig.json不能放到src目录里。


官方说明:https://nextjs.org/docs/advanced-features/src-directory


1.3 项目入口文件


按以上目录设置后,项目的入口文件变为了src/pages/_app.js。稍后将结合演示项目进行具体讲解。


1.4 精简项目


修改src/pages/index.js,最简化页面:

function Index() {    return (        <h1>This is Index Page.</h1>    )}
export default Index


修改src/pages/_app.js,删除首行的全局样式引用:

-   import '../styles/globals.css'
function MyApp({ Component, pageProps }) { return <Component {...pageProps} /> }
export default MyApp

对src目录及文件进行以下调整:

   /src+  ├─ /common              <-- 公用目录+  |  ├─ /images           <-- 公用图片目录+  |  └─ /styles           <-- 公用样式目录+  ├─ /components      <-- 公用组件目录   ├─ /pages               <-- Next.js指定的页面目录+  |  ├─ /api              <-- Next.js指定的API服务目录(不会生成api页面目录)   |  ├─ _app.js           <-- Next.js指定的项目入口文件(不会生成_app.html)   |  └─ index.js          <-- index页面(会生成index.html)-  └─ /styles        <-- Next.js初始的样式目录(删除)-     └─ globals.css       <-- Next.js初始的公用样式(删除)

现在,src目录结构如下,非常精简了:

/src├─ /common            <-- 公用目录|  ├─ /images         <-- 公用图片目录|  └─ /styles         <-- 公用样式目录├─ /components      <-- 公用组件目录└─ /pages             <-- Next.js指定的页面目录   ├─ /api            <-- Next.js指定的API服务目录(不会生成api页面目录)   ├─ _app.js         <-- Next.js指定的项目入口文件(不会生成_app.html)   └─ index.js        <-- index页面(会生成index.html)


执行yarn dev,效果如下:


2 配置项目


2.1 设置路径别名


为了避免使用相对路径的麻烦,可以设置路径别名。


在项目根目录下创建jsconfig.json,代码如下:

{  "compilerOptions": {    "baseUrl": ".",    "paths": {      "@/*": ["src/*"],    }  }}

路径别名官方说明:https://nextjs.org/docs/advanced-features/module-path-aliases


这样在js代码开头的import路径中,直接使用@表示“src目录”,不用去数有多少个"../"了。


修改jsconfig.json需要重启项目才能生效。


2.2 配置SourceMap(不建议设置)

development环境是开启sourceMap的,production环境默认不开启sourceMap。


如果需要在production环境开启sourceMap,在next.config.js进行以下配置:

module.exports = {  productionBrowserSourceMaps: true,}

为了不暴露项目源码,不建议进行以上设置。


2.3 设置页面title


设置页面的title很简单。


修改src/pages/_app.js:


src/_app.js:

+   import Head from 'next/head'
function MyApp({ Component, pageProps }) {M return (+ <>+ <Head>+ <title>My Next App</title>+ </Head>+ <Component {...pageProps} />+ </>+ ) }
export default MyApp

运行项目,发现页面的title已经修改成功。


2.4 设置HTML框架代码


在Next.js项目里有个public目录,但是里面并没有看到类似Create-React-App项目的index.html。那如何设置HTML的<head>内容呢?


新建src/pages/_document.js,代码如下:

import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() { return ( <Html> <Head> <link rel="icon" href="/favicon.ico" /> <meta name="description" content="Next.js演示项目" /> </Head> <body> <Main /> <NextScript /> </body> </Html> )}


_document.js也是Next.js的指定文件名,且必须在pages目录下才可生效。


你可能会好奇,既然_document.js可以设置<head>的内容,那为什么<title>却在第2.3章节的_app.js中设置呢?


这是因为_document.js只会在初始时进行预渲染。官方不建议把<title>放到_document.js中。如果你在_document.js中的<head>里设置了<title>,在build的时候会收到warning。


title规则官方说明:https://nextjs.org/docs/messages/no-document-title


执行yarn dev,在http://localhost:3000中打开浏览器调试工具,但是并没有看到_document.js设置的内容。


这是因为_document.js设置的内容在build后才会生效。dev模式是看不到刚刚设置的内容的。


2.5 以SSR模式运行项目


执行以下命令,build项目:

yarn build

执行后,在项目根目录下会生成一个.next的目录。这个目录就是用于运行SSR的代码,仅能运行在服务端,不能被浏览器直接运行。


然后再执行以下命令,以SSR模式运行项目:

yarn start


 ※注:每次代码更新,在执行yarn start之前,一定要先执行yarn build。否则运行的并不是最新build的项目。


现在打开http://localhost:3000,看到是SSR模式运行的项目。打开调试工具,看到_document.js设置的代码已生效:


yarn start默认是运行在3000端口,如果想运行在4000端口,可以执行以下命令:

yarn start -p 4000

更多Next.js CLI命令,可参阅官方说明。

Next.js CLI官方说明:https://nextjs.org/docs/api-reference/cli


2.6 设置404/500页面


继续回到dev模式,运行yarn dev


现在打开一个并不存在的页面路径,例如http://localhost:3000/test,页面显示如下:


浏览 90
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报