👋 大家好,在独立开发一年后,明天开源了我的 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
严格来说 Prisma 和 Hasura 并不算是同一类货色。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) |
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 | ✅ |
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 工具来用 😉。
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 指标是打造一套残缺的开源用户沟通的解决方案。
社区/community 🏘
作为开源我的项目,社区是我很看重的一块,激励大家参加奉献(issue,discussion,PR)。打算有了肯定支出也会定期给沉闷的开发者发放肯定的金钱反对,回馈社区。
非常感谢你看到这里,欢送到 Chirpy 社区游玩 🙌。
发表回复