开源了我独立开发的评论组件 SaaS 🔥 🚀

2022-01-14 12:16:25 +08:00
 devrsi0n

👋 大家好,在独立开发一年后,今天开源了我的 Next.js App - Chirpy, 一个主打保护隐私、支持主题定制的评论组件 SaaS 。

太长不看版 🙈

这是 GitHub Repo, 欢迎点亮 🌟 收藏,欢迎参与贡献。对于初、中级工程师这里有所有你需要知道的一个完整的 SaaS 怎么运作的全部知识,非常适合学习。

官网目前正在 beta 测试,欢迎试用。如果想要数据完全由你控制,Chirp 也支持 docker 部署

预览 👀

评论组件,支持富文本编辑和 markdown shortcuts ( markdown 实时预览,类似 typora 的书写体验)

主题定制 🌈(更多定制项开发中)

组件使用情况分析面板(Analytics) 📈

初心 ❤️

我在构建我自己的博客的时候想要一个类似 Disqus 一样的功能丰富、接入快捷的评论组件,但 Disqus 本身这几年因为不经用户同意就私加广告,出卖用户隐私等问题广为诟病。下面是我检索到的一些报道:

Bloomberg LawDisqus Faces $3 Million Sanction Over Alleged GDPR Breachesfor multiple breaches of EU privacy law.

Disqus facing $3M fine in Norway for tracking users without consent

我也用过 gitalk utterances 之类的基于 GitHub API 的免费评论系统,它们有一个显而易见的问题就是只支持 GitHub 登陆,而且受限 GitHub 本身 API ,很多功能并不好做,比如组件的使用情况分析 / Analytics 。

市面的组件基本都缺乏主题定制能力,放在自己的博客、网站有很大概率因为设计不协调导致的违和感,所以主题定制也是必要的。

基于以上种种问题所以我打算做一个完全开源同时也能解决以上痛点的评论组件系统。

技术选择与演进 🕺

Next.js 🆚 Gatsby

时间倒回到 2020 年,当年 React SSR 框架 Next.js 推出了 SSG( Static Site Generation )和 ISR( Incremental Static Regeneration ), 迅速变得炙手可热,相比 2019 年大热的静态网站生成器 Gatsby 优势明显。(如果放在今天重新选择,remix 也是一个非常好的选择。😄)

Gatsby Next.js
SSR 🔴
SSG
ISR 🔴
BUILD SPEED 🐌 ⚡️
HMR SPEED 🐌 ⚡️

npm 趋势图

Next.js 的 ISR(增量静态更新) 特性特别适合评论组件的场景。想象有成千上万个 iframe 评论组件,用 ISR 渲染既有了类似 SSR 的灵活性,也有 CDN 的加速加持(减少并发渲染)。下图是 ISR 示意:

一开始 Chirpy 选择了 egoist 的 Next FullStack Starter 作为始点,主要技术栈是:Next.js + Prisma + GraphQL + TypeGraphQL + Tailwindcss。但深入开发过程中发现 ORM Prisma 并不支持 Subscription/real-time API,这是一个对用户体验比较重要的功能,在慎重考虑之后 backend 迁移到了 Hasura

Prisma ➡️ Hasura

严格来说 PrismaHasura 并不算是同一类东西。Hasura 是一个支持高并发的 GraphQL server ,支持用 GraphQL 增删改查数据库(比如 PostgreSQL),同时也提供一套完整的权限控制。Prisma 是一个 ORM ,为了支持 GraphQL 还是需要手写所对应的 resolver 以及相应的权限控制,开发成本较高,但相应的比 Hasura 更加灵活。

Prisma Hasura
语言 TypeScript haskell
Type ORM GraphQL Server
GraphQL API 🟡 手动 ✅ 由数据库 Schema 生成
高并发 🟡 受限于  Node.js 性能和应用架构 ✅  (50M 内存支持 1000 q/sec)( https://hasura.io/blog/fast-graphql-execution-with-query-caching-prepared-statements/)
Subscription 🔴
灵活性 🟡

Hasura 应用的架构

passportjs ➡️ next-auth

用户登陆系统(第三方登陆 + 传统账号密码)也有 2 个比较成熟的选择,一开始选择的是 passportjs, 在深入开发中遇到很多 OAuth 和安全相关的问题,最后重构换到了 next-auth 。相比之下 next-auth 更加现代化(提供 React Hooks ,库本身也是用 TypeScript 写的),更安全,Next.js 集成方便。

passportjs next-auth
第三方登陆
邮箱密码登陆
无密码登陆
安全性 🟡
React Hooks 🔴
Next.js 集成 🔴

Tailwindcss & twin.macro & radix-colors

Tailwind 是一个原子化 CSS 开发框架,在熟悉它之后 CSS 开发效率能显著的提升 🚀;同时它提供了一套完备且经得住考验的默认主题配置,以及一套丰富的 SaaS UI 库(不完全免费,但学会 tailwind 之后手写类似的 UI 不会太难,更重要的是这里有常用 SaaS 的 UI 设计可供参考,对我这个设计苦手非常有帮助 🥳)。

实际上 Chirpy 是和 twin.macro 一起用,这是一个结合 tailwind 和 CSS-in-JS ( styled-component & emotion ) 的库,tailwind 早期版本在组件化开发中会遇到样式类不能被 overwrite 的情况, 因为 tailwind 本身输出原子类:

<p className="w-1 h-1">...</p>

// 输出 CSS 👇

.w-1	{
  width: 0.25rem;
}

.h-1	{
  height: 0.25rem;
}

twin.macro 版本, 不需要 CSS !important 就能覆盖样式:

<p tw="w-1 h-1">...</p>

// 输出 html & css 👇

<p class="random-name">...</p>

.random-name	{
  width: 0.25rem;
  height: 0.25rem;
}

twin.macro 也支持 build 的时候校验,不合法的样式会报错(比如w-0.1),可以避免写出无用样式。以及自由组合多个 variants ,例如:sm:(bg-black hover:(bg-white w-10))。当然它也并不完美,tailwind 可以复用已有的 CSS 类,而它每个 tw 几乎都会生成新的样式, 最终输出的 bundle size twin 会更大一点。它也不支持一些 tailwind 的一些官方插件,比如:tailwindcss-typography(用于编辑器)。故两者是结合一起使用。

tailwind 的 Dark mode 主要靠用 dark: variant (如下面的🌰), 几乎每个颜色值都要写两遍,我理想中的 dark mode 是自动的。

<div class="bg-white dark:bg-gray-900">...</div>

因此这里需要 light/dark 2 套颜色,radix-colors 正满足要求。但它要怎么和 tailwind 一起用呢?答案是:CSS Variable

首先配置 tailwind 主题:

module.exports = {
  theme: {
    colors: {
      bg: `var(--tw-colors-bg)`
    },
  },
}

然后给应用注入样式:

:root {
  --tw-colors-bg: white;
}
:root.dark {
  --tw-colors-bg: black;
}

配合 next-themes 自动在用户切换 mode 时切换网站 CSS 类:

// next-themes 在用户切换 mode 时自动切换 .dark 有无
<html class="dark">...</html>

这样就能在应用切换 mode 时自动刷新颜色。

这里也顺便解决了组件的主题定制功能,Chirpy 只需要在组件渲染时注入用户自定义的变量值即可。

Slate ➡️ tiptap

评论组件体验最核心的是富文本编辑器,一开始 Chirpy 用的是 slate,因为它和 React 结合比较好,但开发到后期也遇到一些问题,比如 markdown shortcuts 实现并不顺利,后面迁移到了tiptap,功能更加完善,底层也基于更稳定的 ProseMirror

slate tiptap
基于 React ProseMirror
稳定性 🔴 issue( https://github.com/ianstormtaylor/slate/issues/3150)
Markdown shortcuts 🔴
功能丰富度 🔴

apollo-client ➡️ urql

apollo-client 毫无疑问是最流行的 GraphQL client ,最初选择的便是它。就在准备开源之前不久遇到了 2 个很诡异的 bug (某些状态死活不更新)。搜索相关问题也了解到 apollo 把开源当成一种营销手段,加之我一直很头痛它很大的 bundle size ,随后下定决心迁移到 urql 这个小巧的多的库,事实证明这次重构超值,减少了近 45KB bundle size 。

apollo-client urql
bundle size 🟡 33kb ✅ 7.1kb
Next.js 集成 🔴 ✅ next-urql
Document Caching 🔴
Stale while Revalidate

Plausible 📈

一开始 Chirpy 自己实现了一个的数据统计 / Analytics ,但后面发现这里面需要考虑很多东西(聚合数据、性能、图表等),严重拖累了开发进度。最后迁移到了 Plausible,它也是一个主打保护隐私的开源 SaaS 。为了更好地保护用户隐私,Chirpy 用它跑在一个单独的服务器上而不是直接用它的服务。

Chirpy 复用了 Plausible 的前端代码以适配评论组件的场景。同时也把它发数据的脚本直接放到 Chirpy 的 bundle + 重映射发数据的 API 接口,可以很好的解决浏览器广告过滤器过滤掉请求导致数据不准确的问题。因此你可以把 Chirpy 当成一个免费且高精确度的 Analytics 工具来用 😉。

Plausible 的营收也是 Chirpy 努力的目标 💪

CI & CD ♻

项目的 CI/CD 主要依靠 GitHub Action 。 开发流程是基于 PR ,每个 PR check-in 之前会跑 Cypress( 端到端测试),jest (单元测试),以及输出 Next.js bundle size 变化(避免无意引入代码造成 bundle size 问题)。

后面会引入 hasura schema CI/CD,减少人肉升级 schema 出问题。

部署 💿

这里分为 Next.js, Hasura 和 Plausible 几部分:

后续支持图片上传考虑使用 Cloudflare Images, 功能齐全,性价比也不错。

远期规划 🛸

评论组件只是我的第一步,在功能逐渐完善之后 Chirpy 也会考虑做类似 intercom 的聊天组件(如下图),hasura + WebSocket 架构天然适合这种轻量聊天应用。Chirpy 目标是打造一套完整的开源用户沟通的解决方案。

社区 /community 🏘

作为开源项目,社区是我很看重的一块,鼓励大家参与贡献( issue ,discussion ,PR )。计划有了一定收入也会定期给活跃的开发者发放一定的金钱支持,回馈社区。

非常感谢你看到这里,欢迎到 Chirpy 社区玩耍 🙌。

4724 次点击
所在节点    分享创造
38 条回复
codespots
2022-01-14 13:52:03 +08:00
东西挺好的,但你知道为啥多说之类的现在不存在了吗?所以还是面向海外用户吧
ljinkai
2022-01-14 14:37:47 +08:00
好东西,Nuxt.js 的考虑集成下吗
enchilada2020
2022-01-14 16:23:02 +08:00
厉害 大佬 dddd (带带弟弟
wensonsmith
2022-01-14 16:37:16 +08:00
不错呀
yuyue001
2022-01-14 17:04:28 +08:00
star 了
knightdf
2022-01-14 17:09:43 +08:00
@codespots 因为要你少说 手动狗头
devrsi0n
2022-01-14 18:55:44 +08:00
@codespots 只面向海外用户
devrsi0n
2022-01-14 18:57:34 +08:00
@ljinkai 哈哈,短期内不会吧。2 个框架差别蛮大的,欢迎 fork 玩玩
devrsi0n
2022-01-14 19:01:52 +08:00
@yuyue001 感谢🙏
devrsi0n
2022-01-14 19:05:13 +08:00
@enchilada2020 欢迎参与贡献,免费帮带 😜
Jiki
2022-01-14 19:06:16 +08:00
赏心悦目,无论是 UI 还是技术栈
devrsi0n
2022-01-14 19:09:41 +08:00
@Jiki 感谢,这是我收到最暖心的评论 ❤️
lyhiving
2022-01-14 19:25:01 +08:00
弄成 intercom 的样子才能看到钱
devrsi0n
2022-01-14 19:28:50 +08:00
@lyhiving 不一定哈,你看 Plausible (文章里有介绍) 本身功能不多的,但是靠主打隐私牌一样月收入恐怖,这种模式是有成功先例的
Showfom
2022-01-14 19:34:38 +08:00
支持一下,就是感觉字体有点大呀

https://chirpy.dev/blog/open-source
devrsi0n
2022-01-14 19:39:50 +08:00
@Showfom 因为 blog 和 docs 主要突出文本本身,不过后面加 TOC 侧边栏的时候会再斟酌下设计,感谢
lyhiving
2022-01-15 16:45:28 +08:00
@devrsi0n 明白,但整体而言单靠一个功能就流行的在目前确实难
devrsi0n
2022-01-15 17:03:12 +08:00
@lyhiving 要说单一的话 Plausible 因为要保护隐私功能可以说极少,而且就 2 个开发者,但一样不影响它赚钱。国外 Facebook 一系列事件下来让保护隐私的 SaaS 就是一个热门领域,况且 Chirpy 也不止这一个特点。产品也是慢慢摸索出来的,我会不断完善 Chirpy
shadeofgod
2022-01-17 12:39:15 +08:00
br_wang
2022-01-17 16:04:22 +08:00
整体方案和技术栈选择相关的说明好看

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/828200

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX