为了更好的浏览体验,请不要在本页面禁用 Javascript 🙂

JAMStack 实践:使用 Gatsby & Notion 构建站点

JAMStack
我很讨厌这种概念含糊不清的新生词汇。但是当你想要交流的时候,又必须给它一个名称。本文不打算用过多的篇幅介绍 JAMStack。下面是有用的链接&引用,可以帮助你更好的理解这种理念。
技术雷达 vol 21
许多年前从手机原生开发兴起的后端即服务开发模式,现在在Web开发上变得流行起来。我们将这种集合了静态站点生成和利用第三方API进行客户端渲染的框架被称为JAMstack(JAM代表JavaScript,API 和 Markup),例如Gatsby.js。这种方式之所以能给用户提供丰富的体验,主要依靠的是API和SaaS。因为HTML不管是在网页浏览器中还是在构建时渲染,它的部署模型和全静态生成的网站是一样的,共同的好处是服务端的攻击面很小,而使用很少的资源可以获得极好的性能。事实上,像这种在部署上对内容发布网络(CDN)非常友好的技术,我们开玩笑想把它称为CDN优先应用程序。
定性的来说它是一种开发架构,由 Netlify 的提出并且实现,同样 Netlify 也提供部分对应的服务。
Gatsby
关于 Gatsby 的介绍,上一篇文章中有提到一些,这里不再赘述。
技术雷达 vol 21
Gatsby.js是一个用于编写JAMstack架构风格网络应用的框架。应用的一部分在构建时生成并且以静态站点的形式进行部署。剩余的功能以渐进式网络应用的方式进行实现并运行在浏览器中。这些应用无需服务端代码即可运行。通常来说,渐进式网络应用会通过调用第三方API,或者现成的SaaS解决方案实现内容管理等功能。在Gatsby.js的例子中,所有的客户端和构建代码都是用React编写。框架包含了一些优化来让程序运行得更快。它将代码与数据分离来最大程度地减少加载时间,并且通过在应用内跳转时预先加载资源来提高性能。接口通过GraphQL进行调用并且通过一些插件来简化和现有服务的集成。
广而告之
📢
GatsbyJS 简体中文文档目前正在翻译中,欢迎大家加入翻译小组 🎉 🎉 🎉
Notion
Notion 引入了 block-styled 的编辑模式。万物皆 block 的理念贯穿于整个应用中。当你使用 Notion 时,会有一种玩乐高、我的世界的感觉。这种 block 的模式能激发使用者的创造力。sspai 上一堆 Notion 吹,这里我就不吹了。
喜欢 Notion 的人,大都不会吝啬他的溢美之词。下面是 Jamie(notion-py 作者) 的彩虹🌈屁。
Notion was no longer just a productivity tool. It was now a general-purpose widget-rich responsive UI layer and data store that could serve as a dashboard, control panel, task manager, or a CRM system with mail-merge. It’s the holy grail of API-lovers: a central system, with a great UI and flexible schemas, into which all-the-things can be integrated.
我非常赞同 Jamie 的观点,这也是我喜欢 Notion Database 的原因 ,程序员懂得都懂。
Database 是 Notion 2.0 推出的功能,在此之前 Notion 跟其它的笔记软件比起来并没有太大的优势。
Notion Database 提供了数据存储服务 & API(非官方)。至此为止 JAMStack 的要素齐全了。
Javascript —— gatsby
API —— notion
Markup —— gatsby
让我们看看这些东西混在一起,能起什么样的化学反应。下面是我基于 Notion 的数据服务造的一些轮子。
gine-blog —— 个人博客
基于 Notion 搭建的博客
block-styled 的编辑器写作体验很好。Database 可以结构化地组织数据。公开页面,即可享受图床服务。在 Notion 中我通过 Database 来组织博文,gine-blog 在 build 时,会拉取 Notion Database 中的数据,构建出一个静态站点。博客托管在 Netlify 上,每当我写完文章后,我只需要向 Netlify 发用一个 POST 请求,告诉它重新构建我的站点,既可以完成文章的发布。为此我还写了个 Chrome 的插件,它可以帮助我发送 POST 请求(构建站点),在 Notion 中完成一站式的操作:从写作到发布,我都无需离开 Notion 页面。
phos —— PWA 音乐播放器
网易云灰掉的歌(还有越来越臃肿的 app),让我转投了 Spotify 。但是 Spotify 也没法完全解决版权问题。流媒体服务带来便利的同时,也让我们失去了很多自由。自建仿佛是最好的出路,于是乎便有了这个项目。Notion Database 存储歌曲数据,PWA 提供跨平台的使用体验。其中绝大部分歌曲直接使用网易云的音源,对于网易云没有版权的歌曲,可以使用 youtube 音源替换,都没有的可以去找一些网络资源,然后上传到 notion 的音乐表中。 《跳舞的梵谷》 这张专辑是我在网易云买的,下载 ncm 后转码为 mp3 上传到 Notion 表中。
渐进策略:网易云 > youtube > 购买数字音频 / 下载网络资源上传到 Notion
写 Phos 时,我意识到数据服务+PWA 离线应用的模式非常讨人喜欢,即它没有隐私和版权的问题,并且是跨平台的。就好比多年前的本地播放器,它虽然没有集成云服务,无法多端同步。但是它就是一个纯粹的播放器,做它份内的事情,绝不越界。
=+服务 = 数据 + 应用
我希望未来的服务可以像这样拆分,服务不再跟服务商耦合(现在的服务商即掌握数据又掌握应用的发布),数据是自己的,原始数据是对用户可见的。可以有多个数据服务商,可以有多个应用。我选择我喜欢的,不是非要去吃某一陀屎。
我以为我发现了什么了不得的新趋势,搜索一番。原来我们的李爵士在十年前就提出了这样的观点:
Raw Data Now!
后来发展成了 Solid 项目,感兴趣的可以看一看。Solid 似乎是一种反商业模式的模式,可能很难取得大的进展。不过我喜欢这种愿景。
实践
看了上面这么多,基于 Notion 开发应用是种怎样的体验?为什么不自己试一试一下呢。
下面的实践,会引导读者构建一个展示博文&书单的站点,它可以作为个人博客的基础。
前置技能
掌握基本的 Javascript + HTML + CSS
接触过 React 开发
开发环境
node
npm / yarn
新手包
Notion API 尚未正式推出(已经鸽了好几年了),可以使用非官方的 API(基于 Web 版网络请求的封装)。我为 Notion 的 Database 专门写了API Wrapper —— notabase,它可以让你使用 Javascript 与 Notion Database 中数据交互。然后基于 notabase 构建了数据源插件 —— gatsby-source-notion-database,方便在 Gatsby 中使用。
这里有一个stater 可以帮你快速搭建起开发环境。
通过 gatsby-cli 快速搭建 starter
如果你已经安装了 gatsby-cli ,可以使用下列命令,快速获取 starter。
gatsby new my-gatsby-notion-site https://github.com/mayneyao/gatsby-starter-notion
Shell
或者先获取源码,然后再安装依赖。
git clone https://github.com/mayneyao/gatsby-starter-notion cd gatsby-starter-notion yarn // or npm install
JavaScript
安装完依赖后, yarn develop 会在你本机的 8000 端口,开启一个开发服务器。访问 http://localhost:8000 我们会看到一个类似这样的站点。
至此为止,一个用 Notion 和 Gatsby 搭建的站点就诞生了🎉 。
这篇文章不打算一步一步的教你怎么用 Gatbsy,关于如何使用 gatbsy 你应该去查阅它的官方文档。
下面我会介绍建站过程中几个重要的步骤。
建立数据库
在 Notion 中建立 Database 页面,可以理解为 Notion 中的一个 Database page 映射数据库中的一张表。在此之前你需要构思下 schame 该如何设计,不用太过谨慎,Notion 的 Database 是十分灵活的,后面怎么修改都可以,不必考虑数据之间的约束和完整性,这使得你可以快速地验证想法。
这里有个模板,你可以克隆到自己的 Notion 中。
此页面包含了2张表格
posts —— 文章表
title —— 文章标题
tags —— 文章标签
books —— 文章可能关联了某本图书
status —— 文章状态。一个 idea,或者正在写,或者已经发布。
publish_date —— 发布时间
books —— 书单表
title —— 图书标题
cover —— 图书封面
status —— 状态。在读,已读,未读。
comment —— 如何评价这本书
posts —— 和这本书有关联的文章。
文章表书单表是相互关联的,例如我看了《流畅的 Python》这本书,我有一些感悟,因此我写了一遍赞美 Python 的文章。
在书单表格中个,我们可以看到《Fluent Python》有一篇与之相关的文章。
在文章表格中,我们可以看到 Life is short,use Python 这篇文章关联了 《Fluent Python》 这本书。
连接 Notion & Gatsby
// gatsby-config.js { resolve: `gatsby-source-notion-database`, options: { sourceConfig: [ { name: 'posts', table: 'https://www.notion.so/4b50defc60ce4e89a6539f511d9d946f?v=8e71dde4479040b5a3e6ca0d91d3d8e6', cacheType: 'html' }, { name: 'books', table: 'https://www.notion.so/4ae9328e650945eb9adbd882b3b453d3?v=0966bdbd0645437cbcc62e6a933e241c', cacheType: 'static' } ] } },
JavaScript
gatsby-config.js 的 plugins 中,完成 gatsby-source-notion-database 数据源插件的配置。
cacheType
static
表格数据会转化成 graphql 节点 ,本地开发时可以在 http://localhost:8000/___graphql 中查看调试。
html
在 static 的基础上,将记录对应页面的 html 缓存下来(使用 Puppeteer 抓取页面 HTML )。可通过 html 字段访问。
dynamic
数据不会在 build 时候存储,仅记录表格 meta 信息,方便后续在页面中动态获取数据。
运行 yarn develop 时,gatsby-source-notion-database 会将指定 Notion Database 中的数据全部拉取下来,转化为 GraphQL 的数据节点。
探索 Gatsby 中的 GraphQL 数据
开发服务器开启后,我们可以在本地的 8000 端口,查看数据。访问 http://localhost:8000/___graphql
你不了解 GraphQL 也没有关系。通过与左边的 Explorer 交互,可以快速生成查询语句,查询出我们想要的数据。整个过程非常自然、简单。
下图中,查询出了所有已发布的文章数据,并且文章数据中包含了关联的书籍数据。这些信息适用于在列表页中展示。
我们可以通过 html 字段访问文章的 html 内容,在后面的文章详情页中会使用到它。
query MyQuery { allPosts(filter: {status: {eq: "published"}}) { nodes { title tags status publish_date(fromNow: false) books { title slug cover } } } }
GraphQL
数据 > UI
数据已经有了,接下来在页面中渲染出来。对于 React 用户来说,这一步是应该是轻车熟路了。
//src/pages/index.js import React from "react" import { graphql } from "gatsby" import Layout from "../components/layout" import SEO from "../components/seo" import PostItem from "../components/postItem" const IndexPage = (props) => { const { data: { allPosts } } = props return ( <Layout> <SEO title="My Posts" /> { allPosts.nodes.map(node => <PostItem data={node} />) } </Layout> ) } export default IndexPage export const query = graphql` query { allPosts(filter: {status: {eq: "published"}}) { nodes { title tags status slug publish_date(fromNow: false) books { title slug cover } } } } `
JavaScript
小结
至此为止,我们回顾一下整个过程。
1.
在 Notion 中设计 Database 表格。
2.
使用 gatsby-source-notion-database 数据源插件,将 Notion Database 中的数据转化为 GraphQL 节点数据。
3.
在 GraphQL Explorer 中探索要想要查询的数据。构建出查询语句。
4.
在 UI 构建中,使用查询语句,得到想要的数据,再将数据渲染成页面。
整体的过程就是这样子。如果你恰好是 Notion 用户,又了解前端开发。那么使用 Notion 作为 CMS,使用 Gatsby 构建现代化的站点,整个过程是水到渠成的。
总结
JAMStack 是 Serverless 中一种不错的实践。其最大的优势是降低了开发&运维成本。
如果是以前,我要搭建个人博客,我要先去买服务器,然后配置 LAMP,WordPress。一套折腾下来,人都累死。如果想要服务高可用,我需要掌握服务器/数据库运维、WordPress 配置等等一系列的知识,其中任何一环出现问题,都会让我的站点跑不起来。
而现在,服务器、数据库都不用我操心了,每一个 SaSS 服务都能保证高可用,这是付费的结果。将那些乱七八糟的"脏活"交给专业的人去做。这使得开发可以更加关注应用本身的设计,带来更好的使用体验,也能提高开发效率。这种趋势也十分符合 Unix 哲学和社会分工的理论。
Do One Thing and Do It Well
使用服务远比自建要好,除非服务达不到要求。这就跟造轮子一样,如果有现成的轮子,为什么不用呢?请把专门的事情交给专业的人去做。绝大多数公司都达不到 AWS 的体量,没必要什么都自己整一套,为什么不试试神奇的 AWS(或同类服务) 呢,是认为自己公司能活得比 AWS 更久嘛。
Serverless 的趋势对个人开发者是十分友好的。它降低了运维成本,提高了开发效率,从 idea 到产品,可以快速试错。专注精力投入到产品的设计和交互上,赢取更多用户的青睐。
参见
世上只有一种英雄主义,就是在认清生活真相之后依然热爱生活。 —— 罗曼·罗兰巨人三传
Build with gatsby,react,material-ui and Copyright 2019 Mayne Powered by gine-blog