前不久研究了一阵子 vuepress,搜索资料的时候意外发现了 Netlify CMS + vuepress 等一个项目。于是大致了解了一下,最终效果是给 vuepress 这类静态页面生成器添加了一个后台。 之前也有见过 HexoPlusPlus 这类的辅助工具,但是很明显 Netlify CMS 这种给出了很有意思的答卷,集成到平台本身、利用 Github 等 API 都是很有意思的点。顺便引起了我对 JAMStack 的第二次了解。

从静态到动态再到静态

纵观 Web 技术的发展,从最开始的纯静态到 JavaScript 的出现,然后是借助 CGI 等技术实现的动态性,再后来就是 ASP、PHP、JSP 等动态网页技术的出现,总体而言都是向动态性进发的。

对于一个人页面,内容不一定有太多,甚至只有单个页面的信息展示。 尽管 Wordpress 一类的建站程序的搭建基本是一站式的,但是很多功能对于一些人是冗余的。 这种情况下我们再动用数据库、哪怕是单纯的动态页面,似乎也是十分不值得的。

在这种对比下,静态网页的优势愈来愈明显。但是编写静态页面的维护成本是很高的,我们很多重复性工作:比如复制一份博文的模板,然后再修改主页的链接,于是早期有许多基于模板概念的静态网站生成器(SSG, Static Site Generator)适时出现,但是在维护性、拓展性、生产效率上都并不易用。不过,随着其发展以及在前端技术的大大进步的趋势下,SSG 已然发展到我们现在所见的程度了:Gatsby、Hugo、Hexo、Vuepress。

静态页面也带来了灵活性大大降低、缺失动态性,无法进行 CRUD(信息发布、用户系统等)的缺点。不过,看看近些年前后端分离已经大势所趋了,你很容易想到将服务做成 API 之类的东西,然后前端获取渲染就好了呗。比如 Hexo 一类博客常用的评论组件 Waline/Valine 就是这样的。

无头 CMS:我全部都要

SSG 的出现也带走了我们喜闻乐见的 Web 后台,尽管有些提供了桌面下的 GUI 界面。但是主流来看我们的工作流大部分都是基于命令行的,要么你在本地编写文章、生成后部署,要么使用 Git 和自动部署网站(Github Action、Netlify、Vercel)自动生成。不可否认的是使用 VSCode 或 Vim 打开 md 文件对于大部分人来说并不是有难度的事情。但是对比于 Wordpress 精美的后台而言,似乎还是显得有些粗旷。

在前面的工作流中架出一个管理软件来帮助我们图形化的管理这一切似乎并不是一件难事。许多提到 SSG 的人总会以 CMS 系统的繁杂来表达其精简。但是对于许多场景下,我们又对 CMS 对便捷工作流产生了渴望。我们需要的是一个看起来像 CMS,但是他是配合于 SSG 的工具,这样一个东西它并不负责具体的页面生成,而是只负责于具体的内容与文件的处理。 这样一个东西被我们称之为 无头 CMS (Headless CMS),顾名思义。

当然这并不是无头 CMS 产生的唯一背景与功能。许多无头 CMS 主要提供我们前面所说的具体的 API,从而便于在多端调用(适用于 移动端 + 前后端分离的趋势),而同时兼容控制 SSG 工作流的功能(例如 Ghost)。也有专门为这类工作流产生的 Netlify CMS 。

到底啥是 JAMStack

说了这么多,什么是 JAMStack,答案已经很清晰了:我们使用 Javascript, 从 API 请求信息, 使用 Markup 等标记语言(Markdown、Vue、JSX)作为源文件生成静态资源。 这就是 JAMStack 最开始的概念。 但是他现在的意思已经更加宽泛,基本上可以概括为:

  1. 使用静态页面生成器生成静态资源
  2. 使用无头 CMS (headless cms) 管理内容、自动化部署
  3. 使用 API 或 服务(Micro-Service、BaaS)增强能力。

当然对于博客来说,其实最简单的静态生成器已经基本上符合我们的需求了,顶多需要一个 Waline 之类的评论组件。 但是一个无头 CMS 很明显能更好增加我们的体验。 你可以获得近似于 Worldpress 等动态网站在线编辑,一键部署(当然部署需要一定时间)的体验的同时,又可以享受静态页面生成器的种种优点。

Netlify CMS + X

JAMStack 就是 Netlify 最初提出来的。 Netlify 很多朋友应该都有接触过。没的话,大概上他就是一个自动部署 Git 工作流的开发平台。我们可以把 Hexo 一类 SSG 部署到上面,Vercel 也是和他差不多的东西。当我们提交对应 Markdown 文件的时候他就会检测到变化后自动重新生成并部署。 我们也可以封装一些 Node.js 函数部署到上面来作为 API 服务。 而 Netlify CMS 则是由其发起的社区驱动的开源项目。

Netlify CMS 和其他无头 CMS 是有很多不同的,我们前面也提到过。他的官网自称也是 Git 工作流的内容管理(content management for your Git workflow)。首先,他是一个 React 单页应用,同时也是一个 NPM 包,更是一个可以运行在网页的脚本。他的原理是通过 Github 等 Git 平台提供的 API 通过 Pull Request、Merge 等操作来将修改提交上去,再加上我们前面提到的自动部署,一个完整的流程就这样清晰了出来。

并且 Netlify CMS 的设计是通用化的,理论上你可以用它配合任何 SSG。 许多 SSG 都利用 front-matter 来提供信息增强,因此你就需要编写一系列配置文件告诉 Netlify CMS 这些东西分别的类型。从而就可以实现,新建一个帖子:填写标题、选择日期、选择分类、撰写正文(带有富文本编辑器,不过还是 makrdown 大法好)、点击发布。 这样一个十分舒适的流程。

将 Netlify CMS 配置到你的网站也是十分简单的。你只需要创建一个 admin 文件夹,创建 index.htmlconfig.yml 两个文件。其中 index.html 是基本固定的,也就是你只需要对 config.yml 进行配置。

config.yml 的内容大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 这里配置你的博客所在的 repo
backend:
name: github
repo: MaxChang3/philo-vuepress
# 上传媒体文件的目录
media_folder: 'media'
# 发布模式
publish_mode: editorial_workflow
# 一系列文章类型的集合
collections:
- name: 'Post' # 名称,用于后台路由
label: 'Post' # UI 标签
folder: '/' # 储存这类文章文件的所在文件夹
create: true # 允许创建
slug: '{{slug}}' # 文件名称模板
fields: # front matter 对应的表单
- {label: 'Title', name: 'title', widget: 'string'}
- {label: 'Publish Date', name: 'date', widget: 'datetime'}
- {label: 'Body', name: 'body', widget: 'markdown'}

你会发现,确实,你很容易将它配合其他 SSG 使用。当然由于我这里只是想展示他思路的清晰和简易,这里就不讲述具体的搭建流程了。但是具体而言也仅仅在这个步骤了。其他无非是权限配置、OAtuh 配置之类的,有需求我会在写一期。

展望

我不会展望。 也不是每一篇文章都要有一个看似颇有意味的结尾,就像大多数人的人生一样。