某天,我看到Dan的一篇文章说准备从medium迁移到个人博客,个人博客是用React+Gatsby。我一直想要建立一个自己的博客,看过hexo or jekll,最终决定学习下Gatsby。理解Gatsby文档感觉挺难也充实,提了很多没有接触过的、建立优秀网站所必需的概念,最终整理输出此篇文档。时间相对长,成果相对丰富,学习新技能的时候,每个官网往往会延伸新的知识,不断挖掘才能形成自己的知识拓扑图:
Getting Started
要跑起来一个gatsby网站很简单,仅需两步,且能延伸出css-modules:
CSS-Modules
CSS规则都是全局的,在不同文件中书写,最终也会汇聚到一个html页面中,如果我们不对CSS name进行处理,则很容易出现命名冲突,这时CSS-Modules应运而生,使用局部作用域。比如:
// index.css
.title {
color: red;
}
// test.css
.title {
color: blue;
}
当在最终生成的html中,两个CSS文件都被引入了,那么test.css.bg和index.css.bg会相互覆盖,但是在CSS-Modules的作用下,形如styles.title般引入index.css,会生成唯一的hash值,伪公式:hash = fileName + classname
// index.js
import React from 'react';
import styles from './index.css';
export default () => {
return <h1 className={styles.title}>hello css-modules</h1>;
}
// 生成的结果html
<h1 class="_28rC3cQIILY_UAwlDiO3Xj">hello css-modules</h1>
// 生成的结果css
._28rC3cQIILY_UAwlDiO3Xj {
title: red;
}
关于CSS-Modules的其他特性,可查看官方文档和css-modules-demos。
进阶——使用插件
在Gatsby中,可以使用插件去解析文件、获取结构化数据资源、自动建站。数据源如下,这些资源独立于React Components,可应用于React Components,整个数据层是这样:
所以建站过程进阶如下:
示例——数据层
代码见示例库gatsby-blog。在示例库中,配置gatsby-config.js,我使用了插件gatsby-source-filesystemsourcing assets文件和pages文件这两个文件系统,在GraphiQL中可以看到输出allFiles和files,基于sourcing插件生成的raw content,再使用gatsby-plugin-mdxtransformation 文件的内容,最终输出allMdx和mdx。
示例——自动化开发react page
自动生成的page有生命周期,在示例中使用到的生命周期有onCreateNode createPage。onCreateNode发生于数据transformation的过程之初,createPage发生于数据层已准备好,开始创建页面。自动化创建页面就发生于此时,根据数据层查询到的数据的不同,插入页面的内容也不同,当然你可以选择在内容之外包裹一层Layout。这个过程值得我们思考的是:自动化的创建能否应用于业务中?
延伸——GraphQL
想要将数据应用于React Components,Gatsby使用了GraphQL。在客户端,使用GraphQL查询语言,筛选客户端需要的数据;在服务端,使用GraphQL schema语言描述客户端可从此服务查询到的数据,若客户端查询一个未被schema定义的字段,则会报错。查询可带参数。query和mutation类型作为查询或修改的入口。见示例库了解更多语法:基于 Express webserver 服务器的一个 GraphQL API 服务端
完善网站
作为程序员,我们往往更注重实现功能的技术,少有从用户的角度考虑一个完善的网站应该具有哪些属性。Gatsby提出了四个要求:RSS/SEO/PWA/离线支持。四个要求可使用Lighthouse插件检测评分。
RSS
RSS中文名:信息聚合。要使得网站支持RSS,整个过程如下,所以作为开发者需要支持的只有一步,就是网站上存放着根据html生成的xml,让RSS聚合器在每次检查更新的时候,都能获取到最新的信息。使用FEED Validator检测网站是否是有效的RSS源。
SEO
帮助搜索引擎理解网站内容,利于曝光。
结构化数据
编写结构化数据。格式类似这样:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"url": "http://www.example.com",
"name": "Unlimited Ball Bearings Corp.",
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+1-401-555-1212",
"contactType": "Customer service"
}
}
</script>
页面元数据
编写页面元数据。开发期间使用结构化数据测试工具验证是否编写正确或完整,部署后“富媒体搜索结果状态”报告监控网页的运行状况。页面元数据的类似这样:
// author描述作者
<meta name="author" content={siteMetadata.author} />
// facebook open graph protocol
<meta name="og:url" content={url} />
<meta name="og:title" content={title || defaultTitle} />
<meta name="og:description" content={description || defaultDescription} />
name和content是一对键值对。og:url中的og代表facebook的open graph协议,使用了这个协议,当用户把内容分享到社交平台上时,社交平台更能读懂你的网页内容。
PWA
PWA,渐进式增强Web Apps,本质是Web Apps,无需添加外壳,也可以在端上如Native Apps般使用。但PWA的能力 = Native apps + Web Apps。
相较于客户端,PWA的优势:
- 无需安装即可使用,就像浏览器版小程序(这里的安装是指Native apps从App Store下载安装)
- 利用浏览器的超大缓存能力,甚至超过Native apps,支持数据库操作的缓存,更快速。
- 强大缓存能力使得在弱网络环境下也能正常使用,更可靠。
- SEO,可在网络上被搜索
相较于Web Apps,PWA的优势:
- 调用原生API,实现消息推送、地理位置等功能。
- 安装到端,像使用原生app一样可搜索、可切换、可作为默认应用程序。
当然,PWA还在发展期,还需要各端对它的支持、缓存策略还需完善、发版麻烦的问题需要解决。但这样的发展方向令人看到了Web前端的另一种可能。所以一个优秀的PWA应该具备的特质:
- 可安装
- 安全可靠,使用https,所有的权限均经过用户同意
- 适配浏览器与端
- 响应式设计
- 在用户体验设计上,多使用类app设计
- 编写SEO
- 持续保留浏览点
- 离线缓存支持
- 后台同步
- 消息推送
“可安装”特质需要添加一个manifest.webmanifest,告诉浏览器你的应用程序在PC或端上安装时的行为。类似这样,键值对释义参考Google's
{
"name": `Irismmr`,
"short_name": `Irismmr`,
"start_url": `/`,
"background_color": `#ffffff`,
"theme_color": `#ffa7c4`,
"display": `standalone`,
"icons": [
{
"src": "/assets/icon-192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/assets/icons-512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"theme_color_in_head": false,
}
“离线缓存支持”特质需要的Web技术是Service Worker。Service Worker是Web应用程序与浏览器之间的代理服务器,当网络可用时,可拦截网络请求缓存资源。正因为此,从安全角度考量,Service Workers必须承载于https协议。Service Worker也可访问推送通知、后台同步API。具体使用可参考通过 Service workers 让 PWA 离线工作
可工作的PWA应用,打开网页Progressive Web Apps安装体验。
(再会)