Next.js 实战
0x1 CSR,SSR,SSG
CSR
客户端渲染(Client-Side Rendering)。常见 B 端 Web 应用开发模式,前后端分离,服务器压力相对更轻,渲染工作在客户端进行,服务器直接返回不加工的 HTML 用户在后续访问操作
缺点:首屏时间长
SSR
服务端渲染(Server-Side Rendering)。JSP/PHP 已经体现了服务器端渲染,其代码耦合度高,且模板语言中混杂编程语言对于一些复杂的功能,维护起来很麻烦。在这种模式下,Java 和 PHP 负责渲染的逻辑,前端只负责 UI 和交互
同构 SSR
BFF:Backend For Frontend,服务于前端应用的后端
前后端一体化,一套 React 代码在服务器上运行一遍,到达浏览器又运行一遍。前后端都要参与渲染,而且首次渲染出的 HTML 要相同
SSG
静态站点生成(Server-Side Generation),在构建时直接把结果页面输出 HTML 到磁盘,每次访问直接把 HTML 返回给客户端,相当于一个静态资源。相比 SSR,因为不需要每次请求都由服务器端处理,所以可以大幅减轻服务器端的压力
缺点:只能用于偏静态的页面,无法生成与用户相关的内容(如,产品展示页面,与用户操作无关)
CDN:建立并覆盖在 Internet 之上,由分布在不同区域边缘节点服务器群组成的分布式网络
SSR / SSG 的共同优势
利于 SEO
浏览器的推广程度,取决于搜索引擎对站点检索的排名。搜索引擎可以理解是一种爬虫,他会爬取指定页面的 HTML,并根据用户输入的关键词对页面内容进行排序检索,最后形成结果并展现出来
更短的首屏时间
SSR / SSG 只需要请求一个 HTML 文件就能展现出一个页面,虽然在服务器上会调取端口,但服务器之间的通信比客户端快得多。同时不再请求大量 JS 文件
0x2 Next.js
Next.js 是一个构建于 Node.js 之上的开源 Web 开发框架,支持基于 React 的 Web 应用程序功能。具有上手速度快、能力集中全面以及覆盖足够多的性能优化和生态的特点,对前后端一体化的开发模式十分友好
SSR 的实现
SSR 核心重要概念之一:同构
./client
:客户端./pages
:页面./server
:服务端在服务器端返回 HTML 模板页面时,会将一些初始化数据脱出来(脱水),如
<!-- ./server/index.tsx -->
<script>
window.context = {
state: ${JSON.stringify(serverStore.getState())}
}
</script>
当页面进入客户端进行渲染时,会将脱出的初始化数据重新注入(注水),如
// ./pages/Demo/store/demoReducer.ts
typeof window !== 'undefined' ?
(window as any)?.context?.state?.demo : {
content: '初始默认数据'
}
使浏览器端与服务器端达到同步的效果
0x3 Next.js 客户端开发
Demo 仓库
Next.js 项目初始化:
npx create-next-app@latest --typescript
next-env.d.ts:确保 TypeScript 编译器选择 Next.js 类型,可以放到
./.gitignore
中,无需变更next.config.js:Next.js 的配置,可以补充 webpack 的一些配置
数据注入
getInitialProps
在服务器端执行,只在页面层进行绑定,采用同构,首次渲染服务器端渲染,路由跳转使用客户端路由
XXX.getInitialProps = async (context) => {
const { XXXId } = context.query;
const { data } = await axios.get(`${LOCALDOMAIN}/api/xxxInfo`, {
params: {
XXXId,
}
});
return data;
};
getServerSideProps
SSR,与
getInitialProps
不同是即使使用 router 跳转当前页,也只会在服务端执行这部分逻辑export const getServerSideProps = async (context) => {
const { XXXId } = context.query;
const { data } = await axios.get(`${LOCALDOMAIN}/api/xxxInfo`, {
params: {
XXXId,
}
});
return {
props: data, // 需要使用 props 包裹
}
}
getStaticProps
SSG,在服务器端构建执行,若涉及动态带参路由,则需使用
getStaticPaths
配置所有可能的参数情况export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [{ params: { XXXId: "001" } }],
fallback: false,
};
};
export const getStaticProps: GetStaticProps = async (context) => {
const { XXXId } = context.query;
const { data } = await axios.get(`${LOCALDOMAIN}/api/xxxInfo`, {
params: {
XXXId,
}
});
return {
props: data,
}
}
CSS Modules
Next.js 支持使用文件名约定的 CSS 模块,
[name].module.css
,具体操作如下:- 创建相关模块文件,如:
style.moudle.scss
- 在
.tsx
文件中引入,如:import styles from './style.module.scss'
- 在需要的地方引用,如:
<div className={styles.divOne}><h1 className={styles.title}></h1></div>
- 创建相关模块文件,如:
Layout
通过在入口文件导入 Layout,可以实现每个页面公共的页眉页尾
return (
// ...
<Layout navbarData = { navbarData } footerData = { footerData }>
// ...
</Layout>
)
文件式路由
Next.js 有一个基于页面概念的基于文件系统的路由器。当一个文件被添加到 pages 目录中时,他会自动作为一个路径可用
BFF 层的文件式路由
BFF 作为服务器构建包,不影响客户端构建 bundle 体积。相同的 router 生成方式,不过是作为 API 层访问,而不是 page
路由跳转
next / link 跳转
import Link from "next/link";
// ...
return (
<Link href = { item.link } key = { index }>
</Link>
)
useRouter 跳转
import { useRouter } from "next/router"
// ...
const router = userRouter()
原生方法跳转
缺点:不会进行 diff 比对渲染,性能上 Next.js 提供的路由跳转更好
header 的修改
可用于修改 TDK(Title,Description,Keywords)
return(
<Head>
<title></title>
<meta />
</Head>
)
多媒体适配
对于不同分辨率的屏幕进行适配
- CSS 适配
- JS 适配
大图优化——webp
0x4 Next.js 服务端开发
BFF 层开发
和 Express 等开发类似,区别在于并没有参数可以直接区别请求类型
调试方式
VSCode
在需要调试的位置添加
debugger;
,启动 JavaScript Debug Terminal,执行命令npm run dev
即可浏览器
npm run debugger
Strapi —— headless CMS
仓库:https://github.com/strapi/strapi
初始化:
npx create-strapi-app my-project --quickstart
一个接口的生成过程如下:
content-type builder
编辑结构体content manager
配置数据源并发布setting roles
里选择对应角色并勾选要发布的接口类型- 若涉及嵌套,则在接口后添加
populate=deep
参数(npm i strapi-plugin-populate-deep --save
),没安装加参数populate=*
,但只能嵌套一层
0x5 核心功能讲解
首页功能实现
- 页面、动画、多媒体适配、BFF、Strapi
文章页实现
页面、动画、多媒体适配、BFF
Strapi分页(/api/articles?pagination[page]=1&pagination[pageSize]=10 // 1/10页)
多媒体格式转换
- markdown 转 html:
npm i showdown -s
- html 转 dom:
dangerouslySetInnerHTML
- 公共样式的定义
- markdown 转 html:
主题化功能实现
- 基础样式和背景的抽离
- 主题化 context 全局注入
- 从注入数据中取出 theme 和 setTheme
- 多进程间的主题同步
-End-
Next.js 实战的更多相关文章
- 《Node.js实战(双色)》作者之一——吴中骅访谈录
- Webfrom 生成流水号 组合查询 Repeater中单选与复选控件的使用 JS实战应用
Default.aspx 网页界面 <%@ Page Language="C#" AutoE ...
- Webfrom 生成流水号 组合查询 Repeater中单选与复选控件的使用 JS实战应用
Default.aspx 网页界面 <%@ Page Language="C#" AutoE ...
- iKcamp团队制作|基于Koa2搭建Node.js实战项目教学(含视频)☞ 环境准备
安装搭建项目的开发环境 视频地址:https://www.cctalk.com/v/15114357764004 文章 Koa 起手 - 环境准备 由于 koa2 已经开始使用 async/await ...
- vue.js实战——购物车练习(包含全选功能)
vue.js实战第5章 54页的练习1 直接放代码好了,全选的部分搞了好久,代码好像有点啰嗦,好在实现功能了(*^▽^*) HTML: <!DOCTYPE html> <html l ...
- 【Vue.js实战案例】- Vue.js递归组件实现组织架构树和选人功能
大家好!先上图看看本次案例的整体效果. 浪奔,浪流,万里涛涛江水永不休.如果在jq时代来实这个功能简直有些噩梦了,但是自从前端思想发展到现在的以MVVM为主流的大背景下,来实现一个这样繁杂的功能简直不 ...
- Node.js实战(二)之HelloWorld示例
经过前面的Node.js实战(一)之概述 想必你应该对Node.js的概念.应用场景.优缺点等有个大致的了解,同时你本地Windows或者Linux上已经准备好了Node.js环境. 下面我们来进入每 ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 错误处理
沪江CCtalk视频地址:https://www.cctalk.com/v/15114923887518 处理错误请求 爱能遮掩一切过错. 当我们在访问一个站点的时候,如果访问的地址不存在(404), ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 记录日志
沪江CCtalk视频地址:https://www.cctalk.com/v/15114923883523 log 日志中间件 最困难的事情就是认识自己. 在一个真实的项目中,开发只是整个投入的一小部分 ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 解析JSON
视频地址:https://www.cctalk.com/v/15114923886141 JSON 数据 我颠倒了整个世界,只为摆正你的倒影. 前面的文章中,我们已经完成了项目中常见的问题,比如 路由 ...
随机推荐
- C#/.NET/.NET Core优秀项目和框架2024年2月简报
前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍.功能特点.使用方式以及部分功能截图 ...
- Binlog分析利器-binlog_summary.py
Binlog中,除了具体的SQL,其实,还包含了很多有价值的信息,如, 事务的开始时间. 事务的结束时间. 事务的开始位置点. 事务的结束位置点. 操作的开始时间(一个事务通常会包含多个操作). 表 ...
- Windows NFS 真弱 → 中文乱码导致文件找不到
开心一刻 正睡着觉,然后来了个电话 对方说:你好,方便面是吗 我愣了一下,以为是恶作剧 回了句:我不是,我是火腿肠! 就挂了电话 又躺了好一会,忽然琢磨过来...... 不对呀,她好像说的是:你好,方 ...
- Rust 登上了开源头条「GitHub 热点速览」
抱歉!上周因为出月刊工作量比较大,所以「GitHub 热点速递」暂停了一期,必须要给守着更新的读者道个歉,以后每周二的「热点速递」会按时更新,下不为例. 说回本周的热门开源项目,Rust 语言可谓是出 ...
- Java 小案列 this关键字使用+构造器 +方法+调用
1 package com.bytezero.thistest; 2 3 public class Boy 4 { 5 private String name; 6 private int age; ...
- vagrant 多个box的操作|共享目录失败
本来机器上已经有一个Ubuntu的box了,今天想在安装一个centos的box,结果还折腾了很长时间. 多个机器的命令 添加box的时候需要使用名称,一个的时候可以忽略名称 vagrant box ...
- 让 js 失效 Chrome F12 右上角 settings - Preferences - Debugger - Disable JavaScript
说的可能比较长,实际上,F12 右上角 - 右小角 还是挺好找的.
- SpringBoot 学习记录 2021.05.13 Started
环境搭建 Spring Boot 2.x Java JDK 需要安装 JDK java8 也就是 1.8, 用 jdk-8u271-windows-x64.exe 网上有很多安装java8的教程,很简 ...
- day04-实现SpringBoot底层机制
实现SpringBoot底层机制 Tomcat底层启动分析+Spring容器初始化+Tomcat关联Spring容器 1.任务1-创建Tomcat,并启动 (1)创建一个Maven项目,修改pom.x ...
- python基础五(文件操作)
一 文件操作 一 介绍 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众 ...