part4-m4

  • 本阶段将带你学习前端圈子中口碑极佳的 React 框架以及它的一些高阶用法、组件库封装、数据流方案、服务端渲染(SSR)、静态站点生成(SSG),同时深入 React 框架内部,剖析 React 部分核心源码和实现,最后还会结合 TypeScript 和蚂蚁金服的 Ant Design 库做出实战。

模块四 React 服务端渲染专题(原生实现、Next.js 集成框架、Gatsby)

  • 本模块中重点介绍 React 体系下的服务端渲染方案,其中包括原生 React 实现服务端 SSR,基于 Next.js 的集成式服务端渲染开发;除此之外,我们还会一起学习目前国外社区非常火热的静态站点生成方案(SSG):Gatsby。

任务一:ReactSSR

  1. zl

  2. zl

  3. zl

  4. zl

  5. ReactSSR相关观念回顾

  • 什么是客户端渲染
    • CSR: Client Side Rendering
    • 服务器端仅返回JSON数据,DATA和HTML在客户端进行渲染
  • 什么事服务器端渲染
    • SSR: Server Side Rendering
    • 服务器端返回HTML,DATA 和HTML在服务器端进行渲染
  • 客户端渲染存在的问题
    • 首屏等待时间长,用户体验差
    • 首页结构为空,不利于SEO

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ux1x9syc-1630307463408)(./img/m4/1630022480267.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eLvKJn1W-1630307463410)(./img/m4/1630022619699.jpg)]

  • React SSR同构
    • 同构指的是代码复用,即实现客户端和服务器端最大程度的代码复用
  1. 项目结构初始化
  • 项目结构
  • src 源代码文件夹
    • client 客户端代码
    • server 服务端代码
    • share 同构代码
  • 在资料下找到 package.lock.json package.json 复制过来
  1. 实现ReactSSR雏形

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LHfX8sWV-1630307463412)(./img/m4/1630023517463.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vktUU0NK-1630307463414)(./img/m4/1629887115224.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tm5qMJ4J-1630307463415)(./img/m4/1630024105147.jpg)]

  1. 服务器端程序webpack打包配置
  • webpack 打包配置
  • 问题:Node 环境不支持ESModule 模块系统,不支持JSX语法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ctN2LQI1-1630307463417)(./img/m4/1630024893595.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nal9TFaZ-1630307463418)(./img/m4/1630025122557.jpg)]

  1. 为组件元素附加事件的方式
  • 在客户端对组件进行二次“渲染”,为组件元素附加事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uss5UZpZ-1630307463419)(./img/m4/1630025996061.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qAD6xo5S-1630307463421)(./img/m4/1630025344207.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9TM6zEob-1630307463422)(./img/m4/1630025479994.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvPazplB-1630307463423)(./img/m4/1630025647869.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-14xsWHlr-1630307463424)(./img/m4/1630025816543.jpg)]

  • “web:client-build”: “webpack --config weboack.config.js --watch”
  1. 优化:合并webpack配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8mIB9Fcv-1630307463425)(./img/m4/1630026073825.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UqZbftSg-1630307463426)(./img/m4/1630026221601.jpg)]

  1. 优化:合并项目启动命令
  • 目的:使用一个命令启动项目,解决多个命令启动的繁琐问题,通过npm-run-all工具实现
    "dev": "npm-run-all --parallel dev:*"
  1. 优化:服务器端打包文件体积优化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTbye19N-1630307463427)(./img/m4/1630029395158.jpg)]

  1. 优化:代码拆分
  • 将启动服务器代码和渲染代码进行模块拆分
  • 优化代码组织方式,渲染React组件代码独立功能,所以把它从服务器端入口文件中进行抽离

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UKEoGBEU-1630307463429)(./img/m4/1630030208255.jpg)]

  1. 实现思路分析
  • 在React SSR项目中需要实现两端路由
  • 客户端路由是用于支持用户通过点击链接的形式跳转页面
  • 服务器端路由是用于支持用户直接从浏览器地址栏访问页面
  • 客户端和服务器端公用一套路由规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6QDztY9D-1630307463430)(./img/m4/1630030475437.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQZc1Vp6-1630307463431)(./img/m4/1630030567230.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NCDpUlby-1630307463432)(./img/m4/1630030593209.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rPvHEyQH-1630307463433)(./img/m4/1630030978469.jpg)]

  • 采用数组的方式,而不是组件,是因为在node中更容易解析
  1. 实现客户端路由

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8bcLMUCd-1630307463435)(./img/m4/1630031117644.jpg)]

  1. 实现客户端Redux
  • 实现思路分析
    • 在现实了React SSR的项目中需要实现两端Redux
    • 客户端Redux就是通过客户端JavaScript管理Store中的数据
    • 服务器端Redux就是在服务器端搭建一套Redux代码,用于管理组件中的数据
    • 客户端和服务器端共用一套Reducer代码
    • 创建Store的代码由于参数传递不同所以不可以共用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Krpap72P-1630307463436)(./img/m4/1630041057535.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nmKGANYM-1630307463437)(./img/m4/1630040533548.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyiX3JYo-1630307463439)(./img/m4/1630040789493.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZv4fvxx-1630307463440)(./img/m4/1630040825948.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rMrIJIj4-1630307463441)(./img/m4/1630040895223.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rd3IED1u-1630307463442)(./img/m4/1630040954772.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xxHobCNc-1630307463444)(./img/m4/1630041012819.jpg)]

  • 用到了浏览器不支持的语法,会去填充这个语法
  1. 实现服务器端Redux(一)
  • server/createStore.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9KBpBtJE-1630307463445)(./img/m4/1630041138332.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5KHfgHsQ-1630307463446)(./img/m4/1630041181193.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gl17r8VH-1630307463447)(./img/m4/1630041261982.jpg)]

  1. 实现服务器端Redux(二)
  • 服务器端store数据填充
    • 问题:服务器端创建的store是空的,组件并不能从store中获取任何数据
    • 解决:服务器端在渲染组件之前获取所需要的数据
  • 在组件中添加loadData方法,此方法用于获取组件所需数据,方法被服务器端调用
  • 将loadData方法保存在当前组件的路由信息对象中
  • 服务器端在接收到请求后哦,根据请求地址匹配出要渲染的组件路由信息
  • 从路由信息中获取组件中loadData方法并调用方法获取组件所需数据
  • 当数据获取完成以后在渲染组件并将结果响应到客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zWd0u49X-1630307463449)(./img/m4/1630042098167.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0O9s3REz-1630307463450)(./img/m4/1630042196307.jpg)]

import app from './http';
import renderer from './renderer';
import createStore from './createStore';
import routes from '../share/routes';
import { matchRoutes } from 'react-router-config';

app.get('*', (req, res) => {
  const store = createStore();
  // 1. 请求地址 req.path
  // 2. 获取到路由配置信息 routes
  // 3. 根据请求地址匹配出要渲染的组件的路由对象信息
  const promises = matchRoutes(routes, req.path).map(({route}) => {
    // 如何才能知道数据什么时候获取完成
    if (route.loadData) return route.loadData(store)
  })

  Promise.all(promises).then(() => {
    res.send(renderer(req, store));
  })
  
});
  1. 实现服务器端Redux(三)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ePNFFT5H-1630307463451)(./img/m4/1630042685340.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J2vu652A-1630307463453)(./img/m4/1630042909756.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GIUuktPQ-1630307463454)(./img/m4/1630042969429.jpg)]

  1. 防止XSS攻击

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1G1QjuX-1630307463455)(./img/m4/1630043051860.jpg)]

任务二:Next

  1. Next
  • React 服务端渲染框架
  • Next.js 是React服务端渲染应用框架,用于构建SEO友好的SPA应用
    • 支持两种预报渲染模式,静态生成和服务端渲染
    • 基于页面的路由系统,路由零配置
    • 自动代码拆分,优化页面加载速度
    • 支持静态导出,可将应用导出为静态网站
    • 内置 CSS-IN-JS 库styled-jsx
    • 方案成熟,可用于生产环境,世界许多公司都在使用
    • 应用部署简单,拥有专属部署环境Vercel,也可以部署在其他环境
  1. 创建Next项目
  • 创建:npm init next-app next-guide
  • 运行:npm run dev
  • 访问:localhost:3000
  • 临时安装 create-next-app 用于创建Next.js项目,这样做的好处在于每次都会下载最新的create-next-app,创建的版本也就是最新的
  1. 基于页面的路由系统-创建页面
  • 在Next.js中,页面是被放置在pages文件夹中的React组件
  • 组件想要被默认导出
  • 组件文件中不需要引入React
  • 页面地址与文件地址是对应的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3nwLASUa-1630307463456)(./img/m4/1630049070077.jpg)]

  1. 基于页面的路由系统-页面跳转

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-43zmUavy-1630307463459)(./img/m4/1630049199873.jpg)]

  • 预取:页面加载完成,浏览器空闲,next回主动获取link标记对应的页面内容,当点击a标记的时候,页面已经被加载完成了
  1. Next应用中的静态资源访问
  • 应用程序根目录中的public文件夹用于提供静态资源
  • 通过以下形式进行访问
    • public/images/1.jpg => /images/1.jpg
    • public/css/base.css => /css/base.css
  1. 修改页面中的元数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mQCvZs0s-1630307463460)(./img/m4/1630050525034.jpg)]

  1. Next应用中添加样式的方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFUFe7bS-1630307463461)(./img/m4/1630050682792.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fOvFyKaj-1630307463463)(./img/m4/1630050781219.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aOuQnoyq-1630307463464)(./img/m4/1630050915979.jpg)]

  1. 预渲染介绍
  • 预渲染概述
    • 预渲染是指数据和HTML的拼接在服务器端提前完成
    • 预渲染可以使SEO更加友好
    • 预渲染回带来更好的用户体验,可以无需运行JavaScript即可查看应用程序UI
  • 预渲染的两种形式
    • 在Next.js中支持两种形式的预渲染:静态生成和服务器端渲染
    • 静态生成和服务器端渲染是生成HTML的时机不同
    • 静态生成:静态生成是构建时生成HTML。以后的每个请求都共用构建时生成好的HTML
    • 服务器端渲染:服务器端渲染是在请求时生成HTML,每个请求都会重新生成HTML
  • 两种预渲染方式的选择
    • Next.js允许开发者为每个页面选择不同的预渲染方式,不同的预渲染方式拥有不同的特点,应根据场景进行渲染
    • 但建议大多数页面使用静态生成
    • 静态生成一次构建,反复使用,访问速度快,因为页面都是事先生成好的
    • 适用场景:营销页面、博客文章、电子商务产品列表、帮助和文档
    • 服务器端渲染访问速度不如静态生成快,但是由于每次请求都会重新渲染,所以适用数据频繁更新的页面或页面内容随请求变化而变化的页面
  1. 实现静态生成
  • 无数据和有数据的静态生成
    • 如果组件不需要在其他地方获取数据,直接进行静态生成
    • 如果组件想要在其他地方获取数据,在构建Next.js会预先获取组件需要的数据,然后再对组件进行静态生成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XdzbnKSv-1630307463466)(./img/m4/1630052120737.jpg)]

  1. 实现服务器端渲染

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YOTvzuLB-1630307463467)(./img/m4/1630052529311.jpg)]

  1. 实现基于动态路由的静态生成
  • 基于参数为页面组件生成HTML页面,有多少参数就生成多少HTML页面
  • 在构建应用时,先获取用户可以访问的所有路由参数,再根据路由参数获取具体数据,然后根据数据生成静态HTML

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyAzIA27-1630307463469)(./img/m4/1630052978021.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IUsIdywP-1630307463470)(./img/m4/1630053044779.jpg)]

  1. fallback选项的作用
  • 如果为false表示展示默认404页面,如果为true,表示服务器端接收请求的一瞬间,服务器端要获取不在范围的路由参数,根据这个路由参数获取对应的数据,再把数据传递给组件进行静态页面的生成,最后把生成的页面返回给客户端

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rm1iHKCz-1630307463472)(./img/m4/1630053844814.jpg)]

  1. 自定义404页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SeD2TTkS-1630307463473)(./img/m4/1630053907053.jpg)]

  1. API Routes
  • 什么是API Routes

    • API Routes 可以理解为接口,客户端向服务器端发送请求获取数据的接口
    • Next.js应用允许React开发者编写服务器端代码创建数据接口
  • 访问API Routes:loaclhsot:3000/api/user

    • 不要在getStaticPaths 或 getStaticProps 函数中访问 API Routes,因为这两个函数就是在服务器端运行的,可以直接写服务器端代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DBdPT75L-1630307463475)(./img/m4/1630054119502.jpg)]

  1. 案例代码初始化配置
  • npm init next-app movie
  • npm install @chakra-ui/core@next
  • npx chakra-cli init --theme
  • npm install react-icons @emotion/core @emotion/styled
  • npm install @emotion/babel-preset-css-prop --save-dev

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w1ZUl9Xm-1630307463476)(./img/m4/1630071049363.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lLPO1e30-1630307463477)(./img/m4/1630071103164.jpg)]

  1. 实现头部组件布局
  • components/Header.js
  1. 实现导航组件布局
  • components/Navigation.js
  1. 实现轮播图组件布局
  • react-responsive-carousel
  • components/Swiper.js
  1. 电影列表布局
  • components/Movie.js
  1. 电影详情页面布局
  • components/Layout.js
  • pages/detail/[id].js
  1. 实现首页组件的静态生成:轮播图数据获取与展示

  2. 实现首页组件的静态生成:电影列表数据的获取与展示

  3. 实现详情页基于动态路由的静态生成

  4. 导出静态网站

"export": "next buid && next export

  • npm run export
  1. 自定义Next应用服务器
  • npm install express nodemon
    "dev": "nodemon server/index.js"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmptkMF0-1630307463478)(./img/m4/1630074713678.jpg)]

  1. 部署Next应用到Vercel平台
  • vercel.com

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eGVRUSsx-1630307463480)(./img/m4/1630074891113.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DclTZ611-1630307463481)(./img/m4/1630074926722.jpg)]

任务三:Gatsby

  1. 什么是Gatsby以及静态应用的优势
  • 静态站点生成器 基于React,能把React开发的项目转换为静态站点
  • https://www.gatsbyjs.org 官网
  • 解决单页应用存在的两大问题
    • 首屏加载时间长
    • 对搜索引擎不友好
    • 将React应用转换为静态应用,这两个问题就不存在了
  • 优势
    • 访问速度快
    • 更利于SEO搜索引擎的内容抓取
    • 部署简单
  1. Gatsby工作流程与框架特性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qtVl80Qd-1630307463487)(./img/m4/1630120098200.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4eMfZ1jv-1630307463489)(./img/m4/1630120208512.jpg)]

  1. 创建Gatsby项目

npm install gatsby-cli -g

  • 创建项目
    • 创建: gatsby new project-name https://github.com/gatsbyjs/gatsby-starter-hello-world
    • 启动: gatsby develop 或 npm start
    • 访问: localhost:8000
  1. 基于文件的路由系统
  • Gatsby 框架内置基于文件的路由系统,页面组件被放置在src/pages文件夹中
  1. 以编程的方式创建页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WFIysm3q-1630307463491)(./img/m4/1630121941987.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZhgNm3yN-1630307463493)(./img/m4/1630122720141.jpg)]

  1. Link组件的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xd334j5q-1630307463495)(./img/m4/1630122994798.jpg)]

  1. GraphQL数据层介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUW51dUi-1630307463496)(./img/m4/1630130106038.jpg)]

  1. 在组件中从数据层中查询数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-121vUMzE-1630307463498)(./img/m4/1630130728726.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PpQN2cDz-1630307463500)(./img/m4/1630130794152.jpg)]

  1. Gatsby框架中和插件相关的一些概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0rZW2u7B-1630307463502)(./img/m4/1630131050432.jpg)]

  1. 将本地JSON文件数据添加到数据层中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c3qvdP7G-1630307463503)(./img/m4/1630131355967.jpg)]

  • gatsby-config.js
  1. 图像优化
  • 图像文件和数据文件不在源代码中的同一位置
  • 图像路径基于构建站点的绝对路径,而不是相对于数据的路径,难以分析出图片的真实位置
  • 图像没有经过如何优化操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6nJRWHdQ-1630307463504)(./img/m4/1630131816788.jpg)]

  1. 将本地markdown文件作为数据源构建文章列表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HrQ3Htjj-1630307463506)(./img/m4/1630132258320.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uycfgDca-1630307463507)(./img/m4/1630132305048.jpg)]

  1. 以编程方式为所有md数据节点添加slug属性
  • 构建文章详情
    • 重新构建查询数据,添加slug作为请求标识,slug值为文件名称
    • gatsby.md => /posts/gatsby
    • react.md => /posts/react

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PG0r5Jkb-1630307463508)(./img/m4/1630132852182.jpg)]

  • gatsby-node.js
  1. 根据slug构建文章详情页

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WPgrGGqH-1630307463510)(./img/m4/1630133239158.jpg)]

  1. 解决markdown文件中的图片显示优化问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X3RguqN6-1630307463511)(./img/m4/1630133720457.jpg)]

  1. 将CMS作为Gatsby应用程序的外部数据源

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iPlZgwB8-1630307463513)(./img/m4/1630134148648.jpg)]

  1. 开发数据源插件-获取外部数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-myDqcEvZ-1630307463514)(./img/m4/1630136431787.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MhX06RfO-1630307463515)(./img/m4/1630136561813.jpg)]

  • plugins/gatsby-source-mystrapi/gatsby-node.js
  • npm init -y
  • npm install axios
  • npm i pluralize

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kWb12KTt-1630307463516)(./img/m4/1630136829289.jpg)]

  1. 开发数据源插件-添加数据至数据层
  • npm install gatsby-node-helpers
const axios = require("axios")
const pluralize = require("pluralize")
const createNodeHelper = require("gatsby-node-helpers").default

async function sourceNodes({ actions }, configOptions) {
  const { createNode } = actions
  const { apiUrl, contentTypes } = configOptions
  // Post -> posts  Product -> products
  const types = contentTypes
    .map(type => type.toLowerCase())
    .map(type => pluralize(type))

  // 从外部数据源中获取数据
  let final = await getContents(types, apiUrl)
  for (let [key, value] of Object.entries(final)) {
    // 1. 构建数据节点对象 allPostsContent allProductsContent
    const { createNodeFactory } = createNodeHelper({
      typePrefix: key,
    })
    const createNodeObject = createNodeFactory("content")
    // 2. 根据数据节点对象创建节点
    value.forEach(item => {
      createNode(createNodeObject(item))
    })
  }
}

async function getContents(types, apiUrl) {
  const size = types.length
  let index = 0
  // {posts: [], prodcuts: []}
  const final = {}
  // 初始调用
  await loadContents()
  async function loadContents() {
    if (index === size) return
    console.log(`${apiUrl}/${types[index]}`)
    let { data } = await axios.get(`${apiUrl}/${types[index]}`)
    final[types[index++]] = data
    await loadContents()
  }
  return final
}

module.exports = {
  sourceNodes,
}
  1. 开发数据转换插件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rjLV0p7v-1630307463518)(./img/m4/1630137713185.jpg)]

  • npm i xml2js
  • npm install gatsby-node-helpers
  • plugins/gatsby-transformer-xml
const { parseString } = require("xml2js")
const { promisify } = require("util")
const parse = promisify(parseString)
const createNodeHelpers = require("gatsby-node-helpers").default

async function onCreateNode({ node, loadNodeContent, actions }) {
  const { createNode } = actions
  // 判断node是否是我们需要转换的节点
  if (node.internal.mediaType === "application/xml") {
    let content = await loadNodeContent(node)
    let obj = await parse(content, {
      explicitArray: false,
      explicitRoot: false,
    })
    const { createNodeFactory } = createNodeHelpers({
      typePrefix: "XML",
    })
    const createNodeObject = createNodeFactory("parsedContent")
    createNode(createNodeObject(obj))
  }
}

module.exports = {
  onCreateNode,
}
  1. SEO优化
  • react-helmet 是一个组件,用于控制页面元数据,这对于SEO非常重要
  • 此插件用于页面元数据添加到Gatsby构建的静态HTML页面中
    npm install gatsby-plugin-react-helmet react-helmet
  • 配置 gatsby-config.js
  • “gatsby-plugin-react-helmet”,
  • components/SEO.js
import React from "react"
import { graphql, useStaticQuery } from "gatsby"
import { Helmet } from "react-helmet"

export default function SEO({ title, description, meta, lang }) {
  const { site } = useStaticQuery(graphql`
    query {
      site {
        siteMetadata {
          title
          description
        }
      }
    }
  `)
  const metaDescription = description || site.siteMetadata.description
  return (
    <Helmet
      htmlAttributes={{ lang }}
      title={title}
      titleTemplate={`%s | ${site.siteMetadata.title}`}
      meta={[
        {
          name: "description",
          content: metaDescription,
        },
      ].concat(meta)}
    />
  )
}

SEO.defaultProps = {
  description: "",
  meta: [],
  lang: "en",
}
  1. 让Gatsby应用支持less

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oZHpAt41-1630307463519)(./img/m4/1630139171544.jpg)]

  1. 案例实现方式介绍

  2. 创建realworld项目

  • gatsby new realworld https://github.com/gatsbyjs/gatsby-starter-hello-world
  • npm start 如果报错
    • rm package-lock.json
    • rm -rf node-modules
    • npm install
    • code .
  1. 构建案例所需组件
  • https://github.com/gothinkster/realworld-starter-kit/blob/master/FRONTEND_INSTRUCTIONS.md
  • html to jsx 安装这个vscode插件
  • 把.cache 文件夹下 default-html.js 文件复制到src下改成html.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n4mWE5wF-1630307463521)(./img/m4/1630140997307.jpg)]

  • 动态的给每一个页面组件添加布局组件
  • 在根目录下创建文件.eslintrc 解决警告
  1. 在案例中配置Redux

npm install redux react-redux

  • src/store/createStore.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4U0Rypqa-1630307463522)(./img/m4/1630141505873.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QQllEWub-1630307463523)(./img/m4/1630141584305.jpg)]

  1. 实现登录(一)

  2. 实现登录(二)

  3. 同步用户状态

  4. 实现客户端路由

npm install gatsby-plugin-create-client-paths

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rGAFZHZd-1630307463525)(./img/m4/1630143022360.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SIb8XSkW-1630307463526)(./img/m4/1630143186747.jpg)]

  1. 受保护的客户端路由

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UutZ1BDo-1630307463527)(./img/m4/1630143530559.jpg)]

  1. 文章列表实现思路分析

  2. 通过数据源插件获取外部文章列表数据

  3. 将文章列表数据添加至数据层

  4. 根据文章列表数据创建带分页的文章列表页面

  5. 组件查询数据显示数据-1

  6. 动态获取文章列表数据

  7. 创建文章详情页面

  8. 创建动态文章详情页面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值