开源推荐:基于Next.js 的评论组件Saas

嗨,大家好,我是徐小夕,今天和大家分享一款非常有意思的开源项目——Chirpy, 一个主打保护隐私、支持主题定制的评论组件 SaaS。(采用Next.js开发 )

6a564e17596e0dfbcd5c8d4055a56f81.png

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

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

预览

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

  • Chirpy 评论组件

da75004fc6a3bfc565a9f3aeed89754b.png
  • Chirpy 主题定制功能

5dc12de50f7e282a2ac02be6c4654093.png
  • 组件使用分析面板(Analytics)

e63f3934593db3ff5ecb92c460872065.png

初心 ❤️

作者在构建自己的博客的时候想要一个类似 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 VS Gatsby

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


GatsbyNext.js
SSR
SSG
ISR
BUILD SPEED
HMR SPEED

(知乎 emoji 支持有限,部分说明用文字代替,下同)

npm 趋势图:

7c34fceed9ab0befb42aa1f7fc554193.png

Gatsby 和 Next.js 的 NPM 下载量对比

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

288ef5cba6cf68f4f2d25b4f0f1ffcae.png

ISR 示意

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

Prisma ➡️ Hasura

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


PrismaHasura
语⾔TypeScripthaskell
TypeORMGraphQL Server
GraphQL API❌ ⼿动✅ 由数据库 Schema ⽣成
⾼并发❌ 受限于 Node.js 性能和应⽤架构✅ (50M内存⽀持1000 q/sec)
Subscription❌不支持
灵活性✅高❌一般

Hasura 应用的架构

616fa7092c053f547cbe322df939720e.png

passportjs ➡️ next-auth

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


passportjsnext-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>

// 输出 html & CSS  
<p class="w-1 h-1">...</p>

.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。


slatetiptap
基于ReactProseMirror
稳定性❌ 相关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。

373a0764290a333f8969ce9fdc840adb.png

Chirpy 的 Next.js bundle size 输出:


apollo-clienturql
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 工具来用 。

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 三部分:

  • Next.js 自然选择部署到开发它的公司 → Vercel 是最佳选择,相比同类服务(比如 netlify)构建性能、图片之类的优化效果更好,部署体验也属一流。

  • Hasura 前置了一个 Caddy HTTP Server 可以自动给 HTTPS 域名签名,同时也为未来支持弹性负载均衡作准备。

  • Plausible 实例单独部署避免影响业务数据,同时也加上了 Caddy HTTP Server。

  • Hasura 和 Plausible 各自部署到了一个 DigitalOcean 虚拟机,主要看中高性价比,使用方便。

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

长期规划

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

b58947514fc4b26ffd92ca61626b801e.png

intercom 的聊天组件

社区/community

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

7e2ba7e3a32d4927eb926041706deb61.png

2021技术复盘汇总

d0f6ab893ce74f738afbd442e42e0e0e.png

dd7698a0371d734707e1c618b8e21b4e.png

503bf158fc6b3b20c92dc29a4002e85b.png

好啦, 今天的分享就到这啦, 如果文章对你有帮助, 欢迎 「点赞」 + 「在看」, 鼓励作者创造更优质的内容~

ac3e8e34d1331d193356905725e6055f.png

点个在看你最好看

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Three.js开源项目有许多,其中一个知名的项目是Gio.js。Gio.js是一个基于Three.js的web 3D地球数据可视化的开源组件库。使用Gio.js,开发者可以快速地创建自定义的Web3D数据可视化模型,并将其作为一个组件整合到自己的应用中。通过在HTML页面中添加Three.js和Gio.js的依赖,可以开始基于Gio.js开发应用。您可以创建一个具有基础样式的Gio地球,具体代码如下所示: ``` <!DOCTYPE HTML> <html> <head> <!-- 引入 three.js --> <script src="three.min.js"></script> <!-- 引入 Gio.js --> <script src="gio.min.js"></script> </head> <body> <!-- 创建一个 div 作为 Gio 的绘制容器 --> <div id="globalArea"></div> </body> </html> ``` 除了Gio.js,还有其他基于Three.js开源项目,如harp.gl。harp.gl是一个用TypeScript编写的3D网络地图渲染引擎,使用了Three.js。您可以在harp.gl的GitHub地址中找到更多相关信息。 github.com/syt123450/gio.js giojs.org/index_zh.html GitHub - heremaps/harp.gl: 3D web map rendering engine written in TypeScript using three.js<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [[开源] Gio.js -- 一个基于 Three.js 的 Web3D 地球数据可视化库](https://blog.csdn.net/weixin_34129696/article/details/87961256)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [基于ThreeJs的一些开源地图项目](https://blog.csdn.net/lg8883573/article/details/122596587)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值