最近我们组在做项目的重构工作,重构的时候采用了全新的技术方案, 最大的变化就是技术选型的时候server端使用的是 GraphQL + apollo,用GraphQL代替了传统的restful风格的前后端数据处理

GATSBY是一款友好支持gql 的前端页面生成器

看一下对于Gatsby的基本解释:

Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps

可以理解Gatsby 是一个静态页面生成工具,它允许使用React作为渲染引擎来搭建一个静态站点

目前比较知名的使用GatsbyJS 的站点就是 react官网

安装

通过Gatsby-cli 脚手架可以直接生产一个静态站点,

测试的时候发现,必须要求本地node版本号 12+

一个基本的框架生成之后是这个样子

GATSBY 的插件功能

GATSBY 拥有很多的插件

可以帮助我们实现非常丰富的功能,比如之后的demo,编译markdown文件,还有在别人的文章中看到可以在页面中添加离线地图应用等等

这里讲一个op中有使用的插件

gatsby-plugin-page-creator

gatsby中默认将 pages 作为路由映射文件,只要在pages中的文件都可以被映射为一个路由页面

那如果想要变更这个规则,就可以借助这个插件来处理

后面这个参数可以用来规避这种映射规则,如果你的组件不想作为路由展示,那么就可以在这里配置一下

支持请求

Gatsby 自然是支持我们常用的 RESTful API 风格

通过例子可以看到,也可以使用我们常用的这种数据请求,拿到数据做后续处理

const axios = require("axios")

const get = endpoint => axios.get(`https://pokeapi.co/api/v2${endpoint}`)

const getPokemonData = names => Promise.all(names.map(async name => {
  const {data: pokemon} = await get(`/pokemon/${name}`)
  return {
    ...pokemon
  }
}))

但是Gatsby 更推荐我们使用 gql 去处理数据,甚至是静态资源的读取,比如我们看一下关于站点内静态图片的展示 【 gatsby-blog 】
去展示一个图片都是通过gql访问的方式

const Image = () => {
  const data = useStaticQuery(graphql`
    query {
      placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
        childImageSharp {
          fluid(maxWidth: 300) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  `)

  return <Img fluid={data.placeholderImage.childImageSharp.fluid} />
}

这种图片的处理我们也可以按照以往的require方式去实现

src={fixUrl(item.avatar)}

但是gatsby是建议我们去遵循同一套开发风格

这种理念可以说是一种开发规范或者说约定吧,希望可以统一开发者的风格

那这种方案对于团队开发来说比较好,统一的风格有利于之后项目的管理与开发,如果是个人站定的搭建就怎么简单怎么实现了

页面生成

Gatsby支持2种页面生成的方式

  • 1 Gatsby内置自动将src / pages中的React组件生成路由的页面,这个也是我们现在后台重构时候采用的方式
  • 2 gatsby-node.js 中 通过 createPage.函数生成

通过这里例子可以看到我们可以拿到数据后动态生成页面

  createPage({
    path: `/pokemon`,
    component: require.resolve("./src/templates/pokemon.js"),
    context: {
      allPokemon
    }
  })

构建demo

然后我们来写一个demo来感受一下 gatsby 的实际开发

demo的目标可以看做是博客内容展示

Demo :文章列表页面 + 详情页面

基本逻辑:读取markdown 数据,展示页面

过程非常简单:

1 首先我们中配置两个插件

gatsby-source-filesystem

gatsby-transformer-remark

Filesystem 是读取文件资源

remark帮助解析markdown数据

2 template中创建模块文件

3 然后我们在gatsby-node.js 中配置动态页面的渲染

// 生成一个markdown 目录文件
  const markdownData = result.data.allMarkdownRemark.edges
  const articles = markdownData.map(({ node }) => node.frontmatter)

// 首页列表渲染 - 备注由于 GATSBY 首先读取配置 在走默认设置 所以page文件夹需要调整 不然就会读取pages下的文件作为首页了
  createPage({
    path: '/',
    component: path.resolve(`src/templates/index.js`),
    context: {
      articles
    }
  })

  // markdown 遍历生成单独的文章页面
  result
    .data
    .allMarkdownRemark
    .edges
    .forEach(({node}) => {
      createPage({
        path: node.frontmatter.path,
        component: path.resolve(`src/templates/post.js`)
      })
    })

createPage 函数 中path 是指定到页面展示的路由,component 是你使用的模板引擎,context 是需要传递给模板需要渲染的数据

列表页面所需的,头像、时间等参数都是在markdown文件中写入的

---
title: 画个龙
date: 2019-08-10
path: /rainbow
author: mk
cover: https://www.lxybaike.com/uploads/201907/1562575542zU2C2i60.jpg
---
我是mk文件 我是mk文件 我是mk文件 

以上就完成了一个简单的列表展示功能

项目实战

数据请求

按照之前的restful风格。接口分为get与post类型,对应gql中可理解为

get -> Query

post -》 Mutation

const { loading, error, data } = useQuery(GET_TODOS)

const [updateTodo] = useMutation(UPDATE_TODO)

按钮操作后更新页面数据可以通过4种方式实现

1 接口中返回变更的结果,根据id会查询到缓存,会自动更识符,用来作为重新获取对象或者缓存的key —- 所以返回的数据列表中不可以有重复id出现

说到这个想起之前,由于mysql表中使用id + order 作为了联合主键,请求返回的数据有相同的id,导致写入缓存数据出错

2 在 update 中 主动重写 cache ( 这个是目前比较常用的一个, readquery && writequery ) 【 mutation 】

3 使用 refetch 直接重新发起一次请求 【 query 】

4 文档中还有一种, fetchmore 在举例分页操作的时候可以使用,不过尝试了下这种方法,这个要配合 updatequery 函数操作

,不如使用 setxxx 去变更 variables 【 query 】

相关资料


正在加载ing
12 声望3 粉丝

引用和评论

0 条评论