Next.js实战项目|青训营笔记

136 阅读6分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 12 天

课程目标

具备C端Web应用开发的基本能力 拓展了解:

  • B端应用:挂载到内网,内部使用,business
  • C端应用:面向整个互联网的所有用户

CSR, SSR, SSG

CSR

客户端渲染,B端常见的Web应用开发模式。书写模板代码,在模板应用中请求,前后端分离。渲染在客户端进行,后端与此无关。页面元素在请求之后获取,首屏时间(开始加载到看到所有元素的时间)更长。

SSR

服务端渲染,从服务器返回的直接就是网页元素。旧式SSR在JSP/PHP就已有体现。不过代码耦合度很高,逻辑和交互混杂,维护比较痛苦。Java和PHP负责渲染逻辑,前端只负责UI交互。现在使用的SSR是同构SSR,前后端一体化(模板页面和接口放在一个项目下,但不会混杂到一个文件中),前后端都参与渲染过程。

BFF

服务于前端应用的后端,是一个服务,通常不会直接操作数据库,对下游的请求拼接汇总再交给前端用来渲染。可以提高大型项目的可维护性和复用性。

SSG

静态站点生成,它做的事和SSR一样,但方式不一样。构建的时候完成对路由HTML的生成,输出到硬盘,相当于静态资源。可以减轻服务器压力,但是不能提供很多的个性化内容。适合用于展示性质的网页。

SSR&SSG的优势

  • 利于SEO:搜索引擎可以获得网页上需要曝光的信息。因为服务器返回的内容包括页面元素,搜索引擎可以获得页面的关键词。
  • 首屏时间更短:不用请求大量的js文件,只需请求一个HTML文件。保证用户体验的舒适感。

什么是Next.js

帮助我们更快更好地开发SSR&SSG项目

SSR的实现

核心概念:同构,客户端做的事情服务端也做一遍,来确保生成的代码相同


举个例子 例子分析 路由:只要两端都有就好 绑定事件:事件在JS处理,服务端如果没有处理,就相当于绑定了空的事件 脱水/注水:在server/index.tsx的line75~79,在服务器端返回页面的过程中,将部分初始化数据脱掉,页面进入客户端渲染时,初始化数据会被重新注入


关于Next.js

实际上,上面的这些内容每个项目都有,都需要,属于重复工作,Next.js就解决了这个问题。 创建一个新项目

npx create-next-app@latest --typescript

Next.js客户端开发

CMS仓库 Demo仓库

Nexi.js初始化

目录结构分析 next-env.d.ts:确保ts编译器选择Next.js类型,可以gitignore因为不需要变更 next.config.js:nextjs的配置文件,可以补充一些webpack的配置

数据注入

实际上是脱水/注水 客户端的内容等服务端注入就可以 一般不用钩子请求(也就是客户端注入

getInitialProps

  • 模板页面可以带参数,参数来源是getInitialProps
  • 数据从服务端来,getInitialProps函数也在服务端运行
  • 这个api是旧式的,页面跳转过程走的是客户端路由(而不是服务端),getInitialProps在客户端运行

getServerSideProps

  • 和getInitialProps非常相似
  • 这个方法只会在服务端运行
  • 写法上,return的内容需要用props包一层

getStaticProps

  • 其实是SSG,服务器端构建时运行
  • 写法上,和getServerSideProps相同
  • 为了适合多种情况,还需要结合getStaticPaths方法使用,比较麻烦
  • 不推荐在数据量大的情况下使用

CSS Modules

  • 在类名基础上加上哈希值,避免重复类名(样式互串)
  • 写一个结尾是.module.css的文件

Layout

  • 在其中写好布局方式
  • 使用的时候,用它包裹其它组件
  • 布局中定义好的其他组件将按照相应方式摆放在被包裹组件的周围

路由

文件式路由

  • 在pages文件夹,排除api文件夹,其它文件夹和文件都会生成路由
  • 中括号包裹文件名,生成可变路由
  • 固定路由的优先级高于可变路由

BFF层的文件路由

  • 在pages/api文件夹
  • 不生产数据,数据从后端获取
  • 拼接数据,传给页面渲染
  • 不会影响客户端构建体积

路由跳转

  • next/link跳转,使用Link标签包裹
  • useRouter钩子,用push方法
  • 相比于原生跳转性能更好

header修改

  • 可修改TDK(title, description, keywords)
  • 用Head标签包裹所需属性即可

多媒体适配

  • rem是灵活换算单位,因为移动端和PC端的font-size通常不同
  • css适配,先写好屏幕分类,再补充其它样式
  • 针对需要更改组件交互的情况,可以用useContext取得注入器获取的UA,监听resize事件实现动态修改

大图优化

  • webp数据格式,体积更小但是解析时间长
  • 慢速网络下,体积是关键;快速网络下,解析是关键
  • webp不是所有浏览器都支持,需要判断是否支持

8.5 Next.js服务端开发

数据从哪里来?

关于BFF层开发

  • 没有中间件,不区分GET和POST写法
  • 如果需要限制请求类型,取出req.method判断
  • 直接写deugger在客户端没法触发
  • 运行JS控制台(服务器端调试),VSCode调试
  • 或者运行Node.js控制台,在浏览器控制台打开,用npm run debug

关于CMS

  • 后台管理平台
  • 维护网站的所有数据
  • 数据库偏研发,数据管理平台更加易于使用

Strapi

仓库地址 初始化

npx create-strapi-app my-project --quickstart

可以快速生成CMS

  • content-type builder:创建/修改结构体,有很多类型可选(relation可将一种类型嵌套在另一种类型之中,如涉及嵌套可装依赖strapi-plugin-populate-deep)
  • content manager:配置数据
  • 配置操作接口,生成速度很快

核心功能讲解

首页功能实现

  • 页面&动画&多媒体适配
  • BFF
  • Strapi

文章页实现

  • 页面&动画&多媒体适配
  • BFF
  • Strapi分页,有现成接口
  • markdown:用showdown.Converter转成HTML,再用dangerouslySetInnerHTML,css设置对应标签样式

主题化

  • 存储主题,在HTML中加上theme属性
  • 通过css为不同的theme定义不同的全局属性变量
  • 使用时,直接用变量作为属性值即可
  • 多进程间的主题同步:监听storage的变化
  • loaclhost:3000127.0.0.1:3000主题不会共享,因为域名不一样,用的localStorage不一样