1
0
Fork 0
blog/content/posts/人间世/岁时录/岁时录(十六).md

41 KiB
Raw Blame History

title date slug featuredImage categories tags series summary description wikilinks
岁时录(十六) 2025-02-27 weekly-16 https://img.viento.cc/cover/weekly-16-cover.webp
沉思录
人间世
博客
日常
域名
去中心化
Marxism
岁时录 岁时录其十六 本文是作者周报的第十六期记录了作者近期在技术、教学和开源方面的经历与思考。作者首先分享了担任助教的体验并反思了教学方法。随后为了提升博客在禁用JavaScript时的体验作者对博客进行了多项技术改造如利用Checkbox Hack和Hugo内置功能优化特定模块。此外作者还购买了新域名`foss.moe`并借此探讨了开源文化与萌文化的交融。文章重点讨论了自由前端替代前端的部署与使用作者介绍了多个自建的自由前端项目并分享了相关配置技巧和对特定项目如PixivFE的优化。更进一步作者深入剖析了自由前端背后的深层含义指出了其存在的矛盾性——既是对抗互联网巨头监控的工具又是中心化现实的体现。文章批判了中心化平台的垄断分析了去中心化平台如Fediverse面临的困境强调了“生态”的重要性以及技术社区与大众之间的认知差距。最后作者呼吁技术社区联合起来建立更强大的基础设施积极与大众沟通并做出必要的妥协以推动非中心化互联网的实现。 true

各位老友,晚上好。这里是 Chlorine。

您正在阅读园子的周报——《岁时录》的第十六篇,日期范围为 2025 年 2 月 24 日至 2025 年 3 月 2 日。这是园子的不完全定期刊物,会记录一些小氯和园子在这段时间的经历,以及或有或无的思考。这是从主世界的时间中引出的一条细小的支流,也是这个网络空间中的小岛的编年史。

祝食用愉快。

上小课

这周小氯做了件有趣的事:上小课。

别误会,不是上小课,是上小课。

没错,小氯也是当上牢助教了(骄傲)。

搞笑的是,由于小氯上学期刚刚上完这门课就报名当助教了,因此我的学生们很多都是我的同届甚至同班的同学,还有不少的学长学姐,所以处理和学生的关系的时候,也是要稍微费一点脑子的。所幸我们的总原则很好实践:既然站在助教这个位置上,那么代表的就是教学团队。课下我们怎么亲切都可以,但是一旦涉及任何教学相关的任务,唯一的原则就是公事公办。

回来。其实讲小课的时候小氯也是有点紧张的,因为的确是第一次做这种事,而且准备得也不算充分。而且,同学们也大都不怎么喜欢发言,所以按照常规思路询问「同学们如何如何」时经常冷场。后续还得想想怎么改进好一些。毕竟虽然说按照小氯的打算,同学们应该是课堂的主体,由他们来决定讨论的话题、材料、节奏、评估和最终成果(省省吧你就是不想每次都自己备课),但是小氯还是要负不少的责任的。毕竟在其位者谋其政,既然选择了这个位置,你就不能想着混一学期。

看来大家似乎还没有比较希望讨论的问题啊。没关系的,大家可以随着学习的过程慢慢想。而且剧透一下,就算是诸位现在不去想,这学期的某节小课,可是一定要仔仔细细想一次的哦。放心,亲爱的同学们,你们逃不过去的。——小氯

PS写完这部分后小氯突发奇想地把这段话喂给了 DeepSeek。让我们听听现国脚 DeepSeek 对此的评价。一向并不直性子的 DeepSeek 大将军发言道:

这种语言风格精准捕捉了 Z 世代在权威角色中的身份焦虑,用自我解构消解制度性压力,通过话语狂欢重塑教育现场的人际关系。网络化表达与教育场域规训形成微妙对冲,构建出新媒体时代特有的青年教师叙事范式。

分析得很好,下次不要分析了。

Minimize Our JS

事情是这样的:小氯最近沉迷于 uBlock Origin致力于把每个网站的权限收到最紧由此不惜把许多老友华丽的博客杀得七零八落。

根据己所不欲勿施于人的原则,小氯似乎也应该保证园子在使用 uBlock Origin 的条件下有良好的体验。而众所周知uBlock Origin 最严格的策略,大概就是禁止任何脚本加载了(当然,你也可以禁止任何资源加载,享受纯正的 Web 0.0 体验)。

那么园子能做到 Zero JS 吗?

理论上当然可以,有 ATP 老友的博客珠玉在前,我们可以肯定,即使不使用任何 JS也可以做出一个优雅的 Hugo 主题。

那么让我们来狠狠欺负小氯吧小氯的博客主题吧~

总原则

总原则:不能不用 JS 的地方,就需要用 JS废话)。

或者是说,任何需要实时性的地方,我们都需要 JS因为单凭 HTML 和 CSS 是不可能实现真正意义的动态效果的。例如时间计算,这群呆呆的静态文件哪能知道当前的时间是多少啊。而并没有真正的实时性的地方,我们就可以使用一些 trick 来替代掉 JS。

我用了哪些 JS

知己知彼,百战不殆。让我们先看一下,园子目前用了哪些 JS。

在 VSCode 中使用 <script 作为搜索项,发现了如下脚本:

  • AI 摘要时,点击按钮展开 / 收起摘要
  • 加载动画
  • 桌面端阅读进度条 / 移动端进度球
  • 主题切换
  • 代码一键复制
  • 图片灯箱
  • 公告
  • 运行时间
  • Twikoo外部
  • Algolia Docsearch外部
  • KaTeX外部

很好,我们一个一个来。

AI 摘要

园子原本 AI 摘要的逻辑大概是通过控制内容区域的 height 和 opacity 实现动画,同时在窗口改变时响应式重计算高度。其实我们要的效果,就是一个点击展开或者收起而已。这可以看作是一个二值变元,或者你叫它布尔值也行。

Binary……是吧

首先科普一下小氯刚刚学到的小技巧Checkbox Hack。简单说就是在 HTML 里面藏一个不可见的 checkbox,通过其被选中与否来控制样式的变化。反正你是二值的,我也是二值的,那么正好组个队。

所以我们加一个不可见的 checkbox

<input type="checkbox" id="ai-summary__checkbox" class="ai-summary__checkbox absolute opacity-0">

初始时的内容默认隐藏:

.ai-summary__content {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
}

然后我们通过 CSS 类监听其状态变化:

#ai-summary__checkbox:checked~label {
    .ai-summary__content {
        grid-template-rows: 1fr;
        opacity: 1;
    }

    .ai-summary__icon {
        transform: rotate(180deg);
    }
}

大功告成。甚至比原本的 JS 版本效果还好

KaTeX

小氯老早就看这个客户端 KaTeX 不顺眼了。既然咱们的代码高亮可以用 Shiki 做服务端接管,那 KaTeX 为什么不行呢?

于是小氯开始尝试各种 rehype / remark LaTeX 的手段,结果不能说是硕果累累吧,只能说是一无所获。还试过直接使用 KaTeX CLI 加上 JavaScript结果自然是又重又不好用。

然后,小氯在绝望地进行搜索时,偶然看到了这篇文章。这位作者主张的就是 NoJS然后小氯就在 KaTeX 一节看到了这个东西:

{{ if eq .Type "block" }}
  {{ $opts := dict "displayMode" true }}
  {{ transform.ToMath .Inner $opts }}
{{ else if eq .Type "inline"}}
  {{ transform.ToMath .Inner }}
{{ end }}

嗯哼?

难道伟大的 Hugo 已经支持原生的 KaTeX 编译了吗?去看看文档,果然如此。

好的,我是小丑。

那好吧:

{{- $opts := dict 
  "output" "htmlAndMathml" 
  "displayMode" (eq .Type "block")
  "throwOnError" false
  "errorColor" "#cc0000"
  "trust" true
-}}

{{- with try (transform.ToMath .Inner $opts) -}}
  {{- with .Err -}}
      {{ errorf "KaTeX 渲染错误: %s (位置: %s)" . $.Position }}
  {{- else -}}
      {{- .Value -}}
      {{- $.Page.Store.Set "hasMath" true -}}
  {{- end -}}
{{- end -}}

这样编译出的数学公式配合上 KaTeX 的 CSS显示效果非常出色。

运行时间

秒级的运行时间是不可能离开 JS 实现的,但是天级确实可以。没错,每天一次自动构建。

不过这个更改还在测试阶段,毕竟这属于是有损替换了。

不准备替代掉的

小氯要做的是 Minimize JS而不是 Eliminate JS。如果一个功能使用无 JS 实现会严重损害用户体验的话,小氯宁可不做更改。

阅读进度

几乎没有离开 JS 实现的可能。

Click And Copy

小氯去查了一下,所有的方案都需要和剪贴板 API 交互,所以都得使用 JS。退而求其次的方法大概是使用 input 标签和 user-select: all,使得用户能够使用 Ctrl / Cmd + C 复制,但是这样体验不是很好。

主题切换

小氯是没见过能不使用 JS 询问用户偏好的主题的。大概可行的方法是完全去掉主题切换,只通过 prefers-color-scheme 决定主题。以及,小氯在 You Don't Need JS 找到了一个 Checkbox Hack 的实现,不过由于小氯的变量有点多,实现起来并不容易。

加载动画

小氯的加载动画灵感来自 Innei 老师的动画,应该是整个主题里面 JS 最复杂的部分了。如果去掉的话,可能需要把原本的动效做成 GIF或者干脆去掉这个功能。

灯箱

图片的灯箱一般依赖于灯箱库,如 Fancybox。不过小氯不喜欢第三方依赖因此自己写了个小小的灯箱还是挺丝滑的。

如果要实现无 JS 灯箱,大概需要使用模态框和 :click 以及 :target 伪类吧。不过键盘导航肯定是别想了。

Algolia Docsearch

Algolia Docsearch 当然不可能无 JS 运行。不过我们还可以有一个替代方法,直接依赖搜索引擎的 site: 功能,效果很多时候还不错,只是交互性差一些而已。

Twikoo 评论

严格来说,任何一般意义上的「评论系统」,都不可能不使用 JavaScript——这是一个需要即时反馈的交互。Staticman 可能算是一个例外,其似乎是通过 form 元素提交 HTTP POST 请求,然后触发网站重构建实现的。可以是可以,不过疑似有点太极端了。

小氯能想到的最好的方法,就是 Fediverse或 Bluesky——把文章同时发在 Fedi 上,并在网站里面整合一个可以跳转到相关帖子的按钮。缺点就是依赖外部服务,只是把自己的网站变成不需要 JS实际上对于真正的无 JS 用户还是不友好。并且需要一个 Fedi 账户。

冷知识

园子没有使用任何 cookie (/ω\)

又一个新域名

小氯酱的第不知道多少个域名

这次是突发奇想的,只是感觉这个域名好有趣,而且没有被占用,也没有溢价(这确实很离奇),所以就买下了。

foss-moe-domain|709

是的,foss.moe

要说直接灵感,大抵是来自 tuna.moe。这是清华大学学生网络与开源软件协会TUNA的官方域名一个提供各种镜像站和 DNS 的神秘组织。

小氯不太清楚 TUNA 为什么选用了这个域名。可能是 TUNA is MOE 的意思吧。

那么 foss.moe 似乎就是 FOSS is MOE。

一个项目可能很萌吗?难说。按理说张牙舞爪的代码没什么「萌」可言,但是项目本身的设计却可以带有可爱的色彩。例如著名的 Clash Nyapasu抱歉这里不能放链接。或者是这个项目本身的用途可以有「萌」的色彩例如 nazurin

{{< github repo="y-young/nazurin" >}}

当然,在两不沾的情况下,我们也可以通过各种变换和解读来创造可爱感,例如,把编程语言、代码工具和平台娘化。或者再脱离一层,在项目本身和萌压根不沾边的情况下,通过人的行动「强行」加入这样的元素,例如边写代码边看番。虽然说这种行为大抵除了给自己创造美好回忆以及降低代码质量之外一般没什么其他影响,但是我们试想一下,如果某位二次元开发大佬,看着某部番写了一个碾压 Ubuntu 的 Linux Distro那鉴于开发社区出色的八卦能力难说这个发行版会不会带上这部番乃至更广义的萌文化的印记。

这大概可以看作萌文化和开源文化在某些层面的融合吧。尽管理论上说任何文化都可以和开源开发这一光荣而充满挑战的人类智慧活动融合在一起,但是依小氯的经验(当然只是经验),萌文化似乎显得尤其容易。

为什么呢?

我们可以拿另一种常常和开源文化结合在一起的东西类比一下:咖啡。这种味道奇特的提神饮料几乎伴随了开源的整个历史,从 Java 到 coffee-2-code-converter 再到 Buy Me A Coffee。理由也不难给出程序员们在熬夜写代码时大抵是需要一些东西帮助自己提神的。于是AssemblyBC再到 C++、Java、JavaScript、Python 和 Go、Rust几乎所有的语言都在字里行间沾上了些这样的熨帖而微苦的气息。

对于许多人来说,萌文化似乎就是他们精神上的咖啡。

……很明显,技术和 ACGN 两种爱好完全不矛盾,二者甚至经常共存,「技术宅」这个独特的群体就是最好的例子。其原因比较耐人寻味,大概是时代背景的作用、传播领域的相似性、主题本身的契合性和心理需求的分层满足等,小氯目前说不大清楚。

虽说小氯一方面没有技术,另一方面连泛二次元都只能说勉强算,但是这并不耽误小氯对着好看的插画发出「好可爱」的惊叹并将其拿来当作 VSCodium 的背景板。如果将来能开开心心地写着自己喜欢的代码,看着自己喜欢的作品,这种生活似乎还蛮幸福的。

从某种意义上说,这是一种(好几层的)对于理想世界的向往,尽管这是个小世界。

未来,也难说,会不会有 cosplay 成各种二次元人物的程序员聚在一起打 Hackathon开 FOSDEM甚至用自己手中的代码将这不公正的互联网权力体系敲开一个无法填补的大洞让新世纪的阳光照进网络的每个角落在互联网的历史上留下一场「Moe Revolution」。

……回到域名本身吧。

那这个域名到底可以用来做什么呢?

说实话,小氯也没太弄清。我在买这个域名的时候,考虑的也并不是用它做什么,而是单纯地觉得,看起来还蛮不错的。如同在老城区的旧货店中,从有些拮据的,但是依然保持着某种风度的慈眉善目的老先生手中,买下的一件小小的玻璃镇纸一般。

目前的打算大概是等到 Forgejo 联邦功能实装以后,拿来托管一个自己的公开 Forgejo 实例,把自己的一些个人项目迁移到上面。感觉还蛮适合的,尽管其更适合的用途似乎是收集或者托管一堆很萌的 FOSS。

若干自由前端

自由前端,有时候也叫「替代前端」,1大致意思是第三方开发者创建的非官方界面,用来访问现有网站或服务的内容。动机大体包括原本的前端过于难用,或者是收集过多的用户数据,云云。

关于目前已知的自由前端可以去 Libredirect 看一看,这里小氯列一下几个自己在部署的吧。

名称 地址 后端 语言 需要账号 Cookie Zero JS
Redlib GitHub Reddit Rust
GotHub Codeberg GitHub Go
Neuters GitHub Reuters Rust
Wikiless 已删库 Wikipedia JavaScript 不明
PixivFE Codeberg Pixiv Go 理论上是 几乎
AnonymousOverflow GitHub Stack Overflow Go

即使是其中最占内存的 Wikiless也不过不到 70 MB 的内存占用。而且由于这些项目在技术上大致就是个 proxy因此需要的系统权限极少。即使是拿着 user: nobodyread_only: truesecurity_opt: no-new-privileges:true 或者 cap_drop: ALL 来玩捆绑 play 也可以照常运行,真正的小而美。

由于这些项目大部分时候只需要 docker compose up -d 一把梭,小氯就不挨个讲怎么部署了。

小氯没有自行部署的项目

名称 地址 后端 语言 需要账号 Cookie Zero JS
Invidious GitHub YouTube Crystal 理论上否
Piped GitHub YouTube Vue 理论上否
Nitter GitHub Twitter / X Nim
Wayback Classic GitHub Wayback Machine Ruby

Invidious 这个家伙很有名,常常被和 Nitter 一起拿出来作为自由前端的代表。不过如官方所说这是个「heavy, bandwidth intensive and technically a proxy」的服务。一个个人实例大概需要 20 GB 空间和 512 MB 的内存,虽说小氯也不是拿不出来,但是对于一个看 YouTube 不多的用户来说,性价比不高。

Piped 呢,用的是 Vue不过似乎没办法部署在静态托管平台上因此跳过。

Nitter 不用多介绍了,神级项目。不过随着 X 的 API 收得越来越紧Nitter 活得也愈发艰难了。现在我们需要一个真实账号的 cookie之前好像可以创建大量的临时账号来解决问题小氯没有也不想注册而且看 X 极少,跳过。

Wayback Classic……这玩意真的能且有必要自托管吗

浏览器扩展推荐

这里主要用于把平时浏览的网址自动重定向到我们的自由前端。小氯找到了两个可用的扩展:

  • Libredirect:专门做隐私化重定向,可选项很多,支持自动选择实例。
  • Redirector:最强大,可定制性最高,可以创建各种类型的重定向,不过需要一点折腾。

小氯用的是后一个。写各种规则简直太舒服了,还可以把 jsDelivr 转到国内镜像。

Wikiless 的部署

Wikiless 原本托管在紫柚的 Codeberg 上,但是后来改为私有库了(据说 Codeberg 是在维基官方的要求下这样做的,理由是违反了共享许可证,具体情况小氯不清楚)。小氯这里用的是这个维护中的库:

{{< github repo="Metastem/wikiless" >}}

小氯大概审查了一下代码,没有发现什么问题,应该是可以用的(免责声明:只是大概审查了一下!)。

小氯在想,能不能剥离掉 Redis 的部分,加一个外部图片代理,把项目变成可以在 Cloudflare 部署的呢?

等小氯试试看吧。

小氯温馨提示Wikiless 的默认语言只有 zh没有 zh-CN。你可以在后面加 ?variant=zh-CN 参数来获取简中网页。

Redirector 可以创建两个规则:

# 中文维基 Wildcard
https://zh.wikipedia.org/*/*
-> https://yourdomain.tld/wiki/$2?variant=zh-CN

# 其他语言 正则
^https?://(?!zh\.)([a-z0-9-]+)\.wikipedia\.org/(.*)$
-> https://yourdomain.tld/$2?lang=$1

Wikiless 和 Wikimore

这俩项目听名字就八字不合

Wikimore 来自著名的 PrivateCoffee也是一个 Wikipedia 的替代前端,维护得很勤快。界面上和 Wikipedia、Wikiless 差别比较大,不过也挺好看的。

缺点大概是对 Docker 的支持不太行Dockerfile 是社区维护的,小氯部署的时候甚至根本跑不起来,提了个 issue 官方才修好),而且资源占用很高,上面小氯部署的所有项目加在一起也没它高。很符合我对 Python 的刻板印象(SearXNG、Domain Admin孩子们这并不好笑)。果然,人心的成见是一座大山,而泰山不让土壤,故能成其大。

LiteXiv 与 PixivFE

其实在尝试 PixivFE 之前,小氯还试了另外一个项目,就是 LiteXiv。

{{< codeberg repo="Peaksol/LiteXiv" >}}

这个项目用的是世界上最好的语言突然激动PHP。整体而言属于功能简单但是够用同时界面比较中规中矩的类型。相比 PixivFE 的优点……似乎没什么很大的优点,主要就是明确告诉你大部分的功能可以无 cookie 运行,哦,以及支持简中。

而资源占用嘛,也不高,不过相比于 PixivFE 还是高了亿些的(大概是 PixivFE 的四倍)。很符合我对 PHP 的刻板印象。果然,人心的成见是一座大山,而泰山不让土壤,故能成其大(梅开二度)。

而 LiteXiv 也非常坦率地描述 PixivFE

A modern-looking frontend that provides many more features than LiteXiv.

不过,宝你有没有想到,愿意使用和自托管替代前端的朋友们主要考虑的也不是 modern-looking 呢?

上面说了LiteXiv 相对 PixivFE 的最大优点之一就是明确告诉你大部分的功能可以无 cookie 运行,所以当时小氯还是很纠结了一番的。

……所以,你为什么不行?!

等会,真不行吗?

无论是 Pixiv 不需要登录就能看插画的政策(还算是有点良心),还是 LiteXiv 珠玉在前,似乎都说明,除了 Discovery 等需要登录的功能之外,这个 cookie 并不是必要的。

我试试看。

小氯研究了一下,你不填 cookie或者填一个空的值是不行的容器会直接报错但乱填一个值是没问题的不需要登录的功能完全可以用。只是首页会报 400看起来有点难受而已。大体规律就是需要登录的功能需要登录不需要登录的功能就不需要登录废话连篇)。好在我平时对 Pixiv 的使用基本限于看到一个 artwork 编号然后点进去看一眼画,这样对我也足够了。

PixivFE 的 Deno 图片代理

PixivFE 的一个关键部件是图片代理。不同于 LiteXiv 只能使用内建代理PixivFE 允许用户自行配置图片代理,还给出了一个通过带善人 Cloudflare 的 Cloudflare Workers 的方法。这不可谓不妙啊,毕竟带善人那么多 IP 呢。

虽然说 Cloudflare 确实有规定:

不得使用服务提供虚拟专用网络或其他类似的代理服务。

不过这说的应该主要是研究信息安全,像这样代理一点图片应该是无所谓的。

……等会,单文件的 Cloudflare Workers

你现在是单文件的 JavaScript……对吧

{{< github repo="chlorine3545/pximg-proxy-deno" >}}

只要是单文件的 Cloudflare Workers小氯都要做一个 Deno 的版本(骄傲)。

至于技术细节并不难,就是写一个 handleRequest 函数,转写下主机名,加一个 Referer 和 UA然后用 Deno.serve 启动就好了。其实这个模板可以套到各种需要请求静态资源的地方,比如 Wikimedia、jsDelivr等等。只要有一个边缘计算平台我们就可以为所欲为骄傲

而 Deno 的速度肯定也没得说,可能是冷门服务的原因,至少比 Cloudflare Workers 快。缺点大概就是免费用量比 Cloudflare 少多了,好在也够用。

一点小小的开源贡献

接着上面 PixivFE 的事情说。

在做完 Deno 版本的图片代理之后,小氯的心思开始活络起来:既然做了这个东西,为什么不想个办法让更多有需求的人都用上呢?

于是小氯向官方提了一个 issue ,得到了还算是积极的回复。

What are your thoughts on adding a Deno deployment option?

You'll have to check out the limitations of Deno Playground. Cloudflare Workers allows a proxy server to process up to 100000 requests per day without any other limitations, which is good enough for an image proxy server. (This is why we don't recommend Vercel to host proxy servers since we killed one before)

Where/how should I submit a PR to contribute this code?

This belongs to the "Hosting an image proxy server" documentation page. You can fork the repository, add your section in this file, then create a PR from your fork. Or, if you want, I can do that for you :)

如上文所说Deno 的限制确实比 Cloudflare Workers 紧很多。但是多一个选择,总归不是坏事,只要把限制明明白白地写好就可以了。

于是小氯花了一点时间写了相关的文档然后手忙脚乱地合并了主分支的更改没办法PixivFE 的迭代实在是太快了),最后提了一个 PR。然后就被顺利合并了。所以大家现在看到的文档的这部分,就是小氯的手笔(铸币大头)(骄傲)。

然后第二天小氯又发现PixivFE 的文档似乎没有做 i18n注意不是 PixivFE 没有做 i18n

看看自己将近 700 分的六级和 7.5 的雅思,小氯忍不住了。

当然,由于对 Material for MkDocs 的国际化不太了解(事后证明,这简直是个噩梦,尤其是导航栏的国际化),小氯选择了先做一个 README.md 的中文翻译,这还是比较容易的。

然后也被接受了。所以如果您的 Codeberg 的首选语言是中文,您默认看到的 readme 也是小氯的手笔(铸币大头)(骄傲)。

(话说 Codeberg 的这个功能真的蛮不错的。GitHub 就不行——当然这估计是因为 GitHub 只有英文界面。)

然后小氯问起了对整个文档国际化的问题,不过主理人表示,希望等项目稳定一些之后再考虑这个问题。这也是很合理的,毕竟说实话,小氯在发现自己提完 README.zh-CN.md 的 PR 时,README.md 已经改了许多地方时,也是挺头疼的。

对于小氯酱这条杂鱼来说,目前对于开源社区最现实的贡献方式大概就是做各种翻译了。可惜由于小氯讲话越来越像入机了,因此已经不能直接把文档口译成地道的中文了 qaq

关于自由前端的碎碎念

Warning

下面的部分极端杂乱和情感化,且可能不具备严谨的逻辑结构。这只能代表此时写文章的小氯的当下的混乱思绪的一部分。

自由前端其实是个很矛盾的东西。一方面,它们确实是蛮自由的,可以帮助我们在浏览大量内容的同时尽可能地逃过无处不在的 BIG EXECUTIVE 的监控;另一方面,它们的存在,就是对自由的讽刺。我们总爱给自由前端贴「隐私友好」「零追踪」的赎罪券,却忘了这些标签本身就是对互联网原罪的变相承认。就像中世纪教会贩卖赎罪券时宣称「购买即得救」,我们也在贩卖「自建即自由」的幻觉。说明白点,这意味着一个很冰冷的事实:互联网依然是巨头们的天下,所有的用户——甚至不用加几乎,根本无法离开它们的领域而存在。这像极了 FxZhihu 项目因为破乎收紧 API 而宣告失效时,小氯除了在 Bluesky 上气急败坏地来一句「Shame on you Zhihu」之外什么也做不了就连像 Linus 那样痛痛快快地向自己所愤恨者来一个国际友好手势都受制于自己的家教而无法张口。

是呀,小氯,你这个家伙,你什么也保护不了。你修不好项目的 API你不能让知乎放开对未登录用户的限制你甚至连报复都做不到。你不会想着用自己那几台破 VPS 去把整个知乎的网络干趴下吧?你只能在忍耐的同时发几句牢骚,毕竟,知乎不在乎你这个刺头用户,但是你却离不开知乎上许许多多的好文章。

「内容就在那里,但是它们属于我们。你爱看不看。」

但是这,似乎也并不是小氯技术力低下的锅。想我政府效率部总负责人、保国公、一字并肩王马保国接管 Twitter对各种开源项目大杀四方不过就是分了那么一点点的力道从 Nitter 到 Twitter Monitor 到 RSSHub 的各大开源项目都被打至跪地。开源社区的各方大佬们殚精竭虑,也只找到了大量注册临时账号来绕过限制这一种不是方法的方法——哦,现在好像也不能用了。

最好玩的是Twitter Monitor 的开发大佬表示不愿意再浪费时间的帖子,发在 Twitter 上Gothub 的前任 1337git,源代码托管在 GitHub 上;每天对着 VX 的开发团队祖安输出的群友们,活跃在 VX 上。

太有趣了,真是太有趣了。既要对着中心化巨头的 API 接口点头哈腰,又要在它们的审查铁幕下偷偷绣红旗;一边用着 GitHub Copilot 的免费版本给自己的信用卡还账,一边在社区里抱怨着它拿着用户代码训练模型。既要又要,真好玩啊。

唯物史观早就说过,生产关系不革命,光在浏览器里搞 proxy 算哪门子进步?当中心化平台垄断着数据石油和算力核电站,我们这些「自由前端」不过一群赛博堂吉诃德,骑着树莓派对着 AWS 风车挥剑。可悲的是,连自诩的革命武器,都要依赖巨头施舍的 API 接口活着。哪天对方改个响应头,整个生态就得通宵改代码。

这当然并非我们所愿,但这是我们的悲剧。

这时候,熟谙此道的诸位估计也要大声疾呼了:非中心化平台何在小氯没经历过那个时代但是据史料记载FediverseBlueskyMatrixNostr出来的时候都是光芒万丈的被寄予厚望的甚至是被吹捧和神化的大有「太好了是新的非中心化社交平台我们有救了」的味道。似乎过不了多久联邦化和去中心化平台就可以占领整个 SNS 甚至互联网的高地。

至于现实情况嘛大家也清楚。被绮丽的幻想蒙蔽双眼的人们当然没能在圣诞节前回家。Mastodon 实例间的信息同步延迟足够让一只树懒写完毕设;某个联邦节点因「包含敏感内容」被拔线时,整个网络的「去中心化」立刻暴露为分布式单点故障的皇帝新衣。普及性嘛:您随便在身边找一个不那么懂计算机的人问一句,能知道 Fediverse 是啥的人估计不会比能默写薛定谔方程的人多;至于某个被老开源正天平旗的开发者们所不屑的 ActivityPub 兼容平台一个多月的时间发展了一亿用户(大概是余下的整个 Fediverse 的三到四倍)……嗯,小氯不评价。小氯只是个可爱的元素娘,不懂那些弯弯绕绕。

更好玩的还在后面:整个联邦的服务器,一半在谷歌云,另一半在 Hetzner哦对了好像还有挺多用着 Cloudflare 的 CDN。这哪是「用魔法打败魔法」分明是「用魔法给魔法交保护费」。当年巴黎公社至少敢烧掉梯也尔的别墅今天的我们却连自建 DNS 都要偷偷用大厂的 Anycast 网络当跳板。倒不是说我们不能沾一点「不纯洁的算力」,但就这个现状,已经足够让葛天氏之民心梗十次了。

所以,为什么呢

最显而易见的,自然是资源。牢软、牢谷随手就能烧掉几十亿美元,而我们连租 VPS 的每月 5 USD 都得含泪舍弃掉几顿外带食品。怎么比?没那个能力知道吗(范大将军音)?这都不是蚍蜉撼树了,是草履虫大战克苏鲁。

但是小氯觉得,最大的问题其实并不在这里。朝鲜战争时,中国的经济和军事实力可连美国的零头都赶不上。

……小氯在写《HelloForgejo》的时候,清扬老友曾经评论说:

但是我认为 github 重在社区,而不是他本身的功能

这话说得太对了。论功能Forgejo 根本不比 GitHub 差多少。GitHub 能够把目前的 Gitea 和 Forgejo 按在地上锤,可不完全是因为牢软的钱包厚度,而是其 issue 模板、Actions 流水线、Pages 托管、Projects 看板、代码搜索构成的协作生态和庞大的开发者群体以及用户构成的社区规模,早已形成技术领域的「拜占庭式行会体系」。

是了,生态

你有心从 VX 迁移到 Matrix却发现你的亲朋好友和同事老板连 Matrix 是什么都不知道;你希望把项目搬到 Forgejo却发现在 GitHub 用了几年的工作流早就成了九层之台起于累土。每个划时代平台的崛起,本质上都是对资源集中度与用户协作成本的暴力优化。既没有资源,又没有生态,你怎么和人家争啊。

而且,生态不仅是技术用户的事,在非技术群体中,这一差距更是判若云泥。当我们在 Matrix 频道讨论「如何用 Rust 重写核心模块」时99.9 % 的用户正在微信群里用「拍一拍」功能互相调情。这种割裂不完全是技术鸿沟,而更像是认知代差的具象化——就像维多利亚时代的博物学家试图向非洲部落讲解进化论。我们幻想中的「全世界用户,联合起来」,在现实中往往演变为技术神父 / 政委与小白用户的永恒割裂。就像试图用《资本论》指导 Tik Tok 网红做直播带货——理论完美,实操荒诞。毕竟,对于我们亲爱的广大用户们,那些在 Reddit 追番、用 Pixiv 存图、靠 Stack Overflow 续命的「数据无产阶级」们,真的在乎 Nitter 实例是否遵循 AGPLv3 吗?当某个自由前端因 API 变更突然暴毙时,他们只会默默切回官方 app顺手给 Play Store 打五星。这不是背叛,而是生存理性对理想主义的血腥处决

至于非中心化替代品,你想依靠「自由、隐私权、去中心化」这些能让技术宅们颅内高潮的卖点去吸引对技术不感兴趣的普通用户?你 Mastodon 算什么东西,你敢说你的平台比 Meta比 X比这些世界顶级的互联网巨头做得好而那些高喊着「用户主权」的 Nostr 协议拥趸,可曾计算过对一个普通用户而言自行保管私钥的代价?当普通人在咖啡馆弄丢存着私钥的 Yubikey 时,他们失去的不仅是社交图谱,更是数字人格的死亡证明。这种「自由」的代价,堪比要求中世纪农民自行铸造货币。

别做梦了,同志们

那怎么办?干等着奇迹降临,全球互联网生态一夜之间离奇消失,留我们一张白纸上书写新时代的创世纪篇?要是您有这种想法的话,这边建议您去查一个叫 Juan Posadas 的人(姑且算人),他的思想或许您会喜欢的。

哲学家们只想着如何解释世界,问题在于改变世界。

我们需要联合。在技术封建主义的铁蹄下,零散的技术宅游击队永远打不赢平台正规军。一台两台 VPS 可以被任何一家企业轻松封杀,那么十万台、一百万台呢?如果我们能通过这种联合建立前端的 CDN 联盟,让自建实例能一键接入抗 DDoS 的分布式盾墙呢?到时候,还有谁敢冒失地对联邦出手?枪杆子里面出政权,你没有足够的实力,谁会施舍你一个眼神?

或许有人会认为,联合本身就违背了去中心化的初心。的确,进行联合存在另一个中心化乃至极权化的风险,但是这就是我们要平衡的地方。小氯说过,开源运动就像是国际共运。那么,如果敌后的抗日根据地没有团结在党的领导之下,东亚地区恐怕就要玩 TNO 了;如果南斯拉夫的游击队没有在南斯拉夫抵抗运动的旗帜下协调行动,贝尔格莱德到现在估计还挂着第三帝国的万字旗。即使是反对先锋队国的卢森堡主义,也并没有否定先锋党的必要性,只是强调不能放弃工人民主的原则。而无政府主义的理想虽然美好,但是还是 Forgejo 那篇所说的,这种方法的实用性极低。无政府公社联邦的社会治理模型,还没能在任何一个稍具规模的社会——咱们都别说现代社会了,就是原始社会也行——成功实践。马克思主义是实证的科学,如果一个理论毫无实践可行性,就算是再精妙的推理、再美好的前景,我们都要忍痛抛弃。剩下的一种理论,尽管这条路荆棘遍地,但是这也是唯一可行的道路。

而且,我们再悲观一点,再现实一点:现在的去中心化生态本身,不就正在孕育新型的中心化吗?某些实例管理员手握封禁大权的样子,活脱脱是数字版《动物庄园》的雪球和拿破仑;某个实例因「政治立场不合」将整个域名拉黑时,所谓的联邦协议瞬间退化为数字巴尔干化的帮凶。就算没办法做到相对好的平衡,像「君主布尔什维克主义」那样用强权要求自由也比看着联邦走向崩坏(有点夸张)强。

当然,从技术实践上,一定程度的中心化也是必要的。就拿 SNS 来说吧。社交媒体本身就具有中心化属性,除非我们能做到近乎实时的实例间互联互通,否则只有一个人的社区广场不叫广场,那叫树洞。我们或许喜欢这种若即若离的社交状态(小氯也是),但是你让一个普通用户来回答,谁会喜欢喊一声之后一个点赞的人都没有呢。

最重要的是,人民群众是历史的主体。如果我们的目的是颠覆整个互联网的权力体系,就不能把这场「非中心化革命」(我们姑且这么叫)仅仅局限于技术用户中。这确实很难,小氯也常常会觉得和大众打交道是个很麻烦甚至很烦心的事。既然我们——诸位(还是别把自己狂妄地纳入这个范畴吧)有这个能力和志向,那么群众工作,就是绕不过去的一环。无论是把 API 文档翻译成短视频脚本,还是教外卖小哥用 curl 检查平台抽成算法。

为了做到这一点,我们有时候——尽管小氯很不愿意说这话——必须要做妥协,无论是用我们精心的设计去吸引用户叛逃,还是在自由前端嵌入可爱的「电子多巴胺注射器」。是的,这样危险,屠龙少年如何才能不成为恶龙;这样卑微,像在摩天大楼的钢架缝隙里播种苔藓;而且经常会很屈辱,像给 Linux 内核套上 Windows 11 的皮肤。但历史早就证明:任何革命想要成功,都必须先学会穿着「敌人」的制服跳舞。当某天非技术用户觉得「哇,这个动漫人物界面的 GitHub 比原版还好用诶」时,我们才算摸到了新世界的门环。

我们也要团结一切可以团结的力量,无论是还愿意在盈利之外考虑一些社会福祉的企业,还是冷眼旁观着这场战斗或者闹剧的基础服务提供者。毕竟,以普遍理性而论,你总不能这样:

fully-open-source-infra|400

……而 FediverseBlueskyMatrixNostr它们不是圣杯但它们确实是先锋。如同巴黎公社、斯巴达克运动和苏维埃联盟是国际共运的先锋一般。它们不完美它们有许许多多的问题。但是它们勇敢地迈出了那一步为我们这些后人留下了宝贵的经验更重要的是它们就像是海明威笔下的那副鱼骨——证明我们曾与鲸鱼搏斗虽败犹荣。

为什么不试试 Fediverse / Bluesky 呢?

所以,小氯依然会在每一个希望找到一个能闲着没事发发短博客的平台的老友的评论区留下这么一句话,歪着头,满脸的清澈和愚蠢,像极了 Pixiv 的画师们画的 Goofy ahh big head铸币大头的神情。

第一,他们确实很可能需要;第二,我们总要反抗。如果我们放弃了,那就真的什么都完了。


  1. 严格来说,这两者不完全一样,替代前端的范围更广。不过由于大量的替代前端都是 FOSS并且专注于用户自由和隐私因此两个词有时候会混用。以下我们统一使用「自由前端」。 ↩︎