LinMinheng

独立开发者 · 摄影师 · 学生

这里是我的一方天地,互联网冲浪累了就回来歇歇脚。随手记下想法、晒晒在做的东西,也欢迎你停下来看看。

黄昏书房 · 一方天地

我是 LinMinheng。白天写代码,有光的时候按快门,剩下的时间在读书和发呆之间反复横跳。做这个网站不是为了什么 KPI,只是想在喧闹的互联网里,留一块安静的、完全属于自己的角落

比起追逐热点,我更在意把一件小事做到细腻——一段干净的代码、一张恰到好处的光影、一句想了很久才写下的话。如果你恰好路过,泡杯茶,慢慢看就好。

这里会慢慢长出更多东西——写到一半的想法、刚拍的照片、新折腾的小项目。不着急,反正这块地是我自己的。

在 GitHub 上看全部 →

事情的起点很简单:我有一套跑在 Cloudflare 上的临时邮箱,但每次想看邮件都得打开电脑、登后台。我想要的只是一个能揣在兜里、随手一划就能看的东西。

第一版:两小时的"成功"

周五晚上九点,我新建了个 React Native 项目,用 WebView 直接套了个壳。十一点上线,能用。

丑是真的丑——就是一个全屏浏览器,连侧滑返回都没有。但我告诉自己"先跑起来",改天再优化。结果第二天一打开,自己都不想用。那种感觉就像穿着睡衣去见朋友,虽然没人拦着你,但你自己不好意思。

第二版:卡在 HTML 邮件上

我不服气,花了整整一个周末重写 UI。邮件列表改成原生组件,滑动丝滑了,视觉也正常了。结果测试的时候,收到一封营销邮件,直接把我整个界面撑爆了——对方的 CSS 把我的按钮全盖住了,底部导航栏飞到屏幕外面去了。

我尝试了三种方案:

  1. iframe 沙箱 → React Native 没有真正的 iframe
  2. CSS reset + 命名空间隔离 → 对方用了 !important,我的规则全被覆盖
  3. 纯文本模式 → 那我为什么不直接用命令行收邮件?

卡了整整一周。我开始怀疑自己是不是选错方向了,也许这就该是个网页,别做 App 了。

第三版:想通"信任边界"

转折点在一篇无意间看到的博客——讲浏览器渲染引擎如何隔离不可信内容。我突然意识到:我一直在把邮件当"自己的数据"对待,但它本质上是"外部输入",是不可信的。

那一刻思路打开了:

  • 邮件正文不该和我的 UI 共享一个渲染上下文
  • 应该用 WebView 渲染邮件,但把它当成"显示外部内容的沙箱",不是"偷懒的全屏浏览器"
  • 列表用原生组件,详情用受限的 WebView,两者通过 postMessage 通信

重构花了两天,但这次代码写得很踏实。我知道哪里是边界,知道哪些数据可以信任,哪些必须清洗。现在它能干净地列出收件箱、按需加载正文、附件直接下载,即使对方发来一个带恶意脚本的邮件,也只是在沙箱里转转,出不来。

一些碎碎念

这个项目让我意识到一件事:做对比做快难太多了。

做快只需要你懂 API 怎么调,库怎么用。做对需要你理解问题的本质是什么,边界在哪里,哪些坑以后会踩。前者可能三天就能糊一个能 demo 的东西,但后者需要你推倒重来、踩坑、骂娘、凌晨四点躺床上突然想通。

现在我每天都会打开这个 App 看几次邮件。不是因为它功能多牛逼,是因为我知道它每一行代码为什么在那里。这种"知道自己在干嘛"的踏实感,是我做独立项目最上瘾的部分。

窗外雨停了。写完这篇,去睡。

写于一个改完最后一个 bug 的深夜,窗外在下雨。

太阳落山前后那十几分钟,光是斜的、软的、带着温度的。摄影师管它叫 golden hour。它来得很慢,走得很快,你没法催,只能等。

那个下午

去年夏天,我在江边蹲了整整一个下午。

计划是拍日落时江面的倒影——看了好几天天气预报,那天云量 30%,风力二级,理论上是完美的。结果到了现场,云层厚得像一床被子,太阳完全躲在后面,江面灰蒙蒙的,什么都看不出来。

我坐在堤坝上,看着相机包,开始怀疑人生。要不要走?再等等?可能就这样了吧。旁边钓鱼的大爷看我坐了两小时一张没拍,还好心劝我:"小伙子,今天没戏了,回吧。"

就在我收拾三脚架的时候——真的就是那一瞬间——云层裂开了一条缝。

光像水一样倾泻下来,先是照亮远处的桥,然后慢慢铺满整条江面。江水从灰色变成金色,波纹一圈一圈地反光,整个世界突然活了。我手忙脚乱地把三脚架重新架起来,调焦距、设参数、按快门,心跳快得要爆炸。

那束光只持续了大概四十秒。

然后云层又合上了,江面重新变灰。我呆呆地站在那里,看着相机屏幕上刚拍下的那张照片,有种不真实的感觉——就像做了一个太短暂的梦。

关于等待这件事

回家之后,我把那张照片放大到显示器上,盯着看了很久。光的颜色是一种很暖的琥珀金,带一点橙,又不完全是橙。我用取色器吸了那束光最亮的地方:#E3A857

后来做这个网站的时候,我把主色定成了这个颜色。不是因为它"设计上好看"(虽然确实还行),是因为它能提醒我一件事:好东西值得等,而且往往在你快放弃的时候才来。

摄影教会我的第一件事,不是构图,不是曝光,是等待。等一个瞬间,等光、等云、等那个"对了"的时刻。你可以学会所有技术参数,但你没法加速时间。有些东西,必须耐着性子等它自己发生。

这大概也是为什么我喜欢摄影——在这个什么都能"马上"的时代,它强迫你慢下来。你架好机位,调好参数,然后就是等。等的过程里,你会开始注意到风怎么吹、云怎么动、远处有人在遛狗、江面上有船经过。那些你平时根本不会看第二眼的东西,突然都变得有意思起来。

那个钓鱼的大爷后来也看到那束光了。他回头冲我竖了个大拇指,笑着说:"等到了吧?"

嗯,等到了。

每个程序员都被劝过:"别重复造轮子。"这话当然对,尤其在公司里、在 deadline 面前。但在我自己的一方天地里,我想为它辩护几句。

一个具体的例子

上个月我需要一个简单的图床——存图、生成外链、管理文件。逻辑很简单,开源方案一大把,随便挑一个改改配置就能用。

但我还是花了整整一周,自己从头写了一个。

用的是 Cloudflare R2(对象存储)+ Pages Functions(无服务器函数)+ Workers(边缘计算)。写完之后代码不到 500 行,功能够用,但确实没什么特别的——现成的那些方案该有的它都有,人家有的高级功能它反而没有。

朋友看到了问我:"为什么不直接用 xxx?功能更全,还有 Web UI,你这不是浪费时间吗?"

我想了想,说:"可能是为了知道它为什么是这样的。"

造轮子最大的收益从来不是那个轮子

写这个图床的过程里,我搞懂了几件事:

1. Cloudflare 的三件套(R2 / Pages / Workers)是怎么配合的

之前我只是"会用",知道 R2 能存文件、Workers 能跑代码、Pages 能部署前端。但具体怎么让 Workers 读取 R2 的文件、怎么设置 CORS、怎么生成带签名的上传 URL、怎么在 Pages Functions 里调用 R2 绑定——这些细节,看文档和自己动手完全是两回事。

2. 对象存储的权限模型是个什么逻辑

一开始我设置的权限太开放,任何人都能上传。后来改成"需要 token 才能上传,但所有人都能下载"。再后来发现有人在滥用外链,又加了防盗链。每踩一个坑,我对"权限"这件事的理解就深一层。

3. 边界情况比我想象的多

文件名带特殊字符怎么办?上传到一半断网了怎么办?同一个文件重复上传要不要去重?文件太大要不要限制?这些问题,用别人的库的时候你根本不会想,因为库已经帮你处理了。但当你自己写,你会被迫把每一个"如果"都想一遍。

**造轮子的过程,就是把一个"黑盒"拆开,看清里面每个零件为什么在那里的过程。**等你写完,你对那个领域的理解会从"会用"变成"懂"。

什么时候该造,什么时候不该造

我的标准很简单:

**工作上,能用库就用库。**deadline 是真实的,客户不会因为你"想学习"就多给你两周时间。这时候效率第一,别膨胀。

**但凡是我真心想搞懂的东西,我允许自己慢下来,亲手造一次。**不为了上线,不为了给别人用,就为了自己能说一句"我知道它是怎么工作的"。

有些人会说这是浪费时间。也许吧。但我觉得,如果学习本身是目的,那"浪费"这个词就不成立了。

一个意外的收获

那个图床我现在每天都在用。不是因为它功能多强,是因为我知道它每一行代码在干什么。

有一次半夜传图的时候发现上传失败,我打开浏览器控制台看了一眼报错,立刻就知道是 CORS 配置有问题。改了两行代码,重新部署,三分钟解决。

如果用的是别人的方案,我大概会先去翻文档、搜 issue、发帖问人,然后等半天才搞定(或者干脆放弃,换一个服务)。

这种"完全掌控"的感觉,是造轮子的隐藏回报。

最后

所以下次你看到我又在造轮子的时候,别劝我了。

我知道有现成的,我也知道我的不一定更好。但有些东西,不是为了"更好",是为了"搞懂"。

效率不是唯一的尺子,好奇心也是。

那一周我做了个实验:关掉手机上所有 App 的推送,只留电话和短信。起初的两天极其难受,手会无意识地去摸手机,解锁,然后发现没什么可看,又锁上。像戒断反应。

前 48 小时

第一天最难熬。

早上起来的时候,习惯性地看手机——以前一打开就是几十条通知,微信群消息、邮件、GitHub 的 PR、知乎推荐、淘宝优惠券。现在屏幕干干净净,只有时间和日期。

我愣了几秒,有种不知道该干什么的感觉。

上午写代码的时候,每隔十几分钟就会想:"有人回消息了吗?那个 issue 有人回复吗?群里是不是在聊什么重要的?"然后拿起手机,解锁,看一眼——什么都没有,锁上,放下。过一会儿又拿起来。

我开始意识到,**通知不是在提醒我"有重要的事",而是在训练我"随时检查手机"。**那个"叮"的一声,就像巴甫洛夫的铃铛,响一次,我的注意力就被打断一次。即使没有铃铛,我也会主动去找。

第二天稍微好一点,但还是难受。中午吃饭的时候,我打开微信,发现群里聊了两百多条——一个技术群在讨论某个框架好不好用,大家吵得很激烈。我往前翻了翻,发现跟我没什么关系,甚至跟技术本身关系也不大,就是在吵"立场"。

以前我一定会参与进去,因为看到红点我就会点开,点开就忍不住说两句。现在没有红点了,我看了一眼,关掉了。没有任何损失。

第三天开始的安静

到了第三天,某种东西安静下来了。

早上起来不再第一时间看手机,而是先去刷牙、做早饭。写代码的时候能连续两三个小时不碰手机,因为没有东西在"叫"我。中午想起来看一眼,回几条消息,然后放下,继续做自己的事。

我开始能连续读完一整章书,能完整地看完一次日落而不想着拍下来发出去。

有一天傍晚,我在江边坐着,看天慢慢暗下来。以前我一定会拿出手机拍照、修图、发朋友圈,然后每隔几分钟就看一次有没有人点赞。现在我就坐着,看着,什么都不做。

那天我看到了一只白鹭从江面飞过,翅膀划出一道弧线。以前我可能根本注意不到,因为我在看手机。

一周后

实验结束的时候,我打开了所有 App,看它们这一周积累的通知:

  • 微信群消息 1847 条
  • 邮件 93 封(大部分是广告)
  • GitHub 通知 31 条(只有 3 条跟我相关)
  • 其他乱七八糟的 200+ 条

我花了半小时快速过了一遍,发现:真正重要的不超过十条,而且都有人通过其他方式联系到我了。

其他那些,全是噪音。别人的争论、算法推荐的内容、商家的促销、我根本不关心的群聊。它们以前每天在"叮叮叮"地响,把我的注意力切成碎片,但其实它们对我的生活没有任何影响。

那一刻我意识到:过去那些"叮"的一声,偷走的不是几秒钟,是我把一件事做深的能力。

现在

实验结束之后,我没有完全恢复通知。

微信还是静音的,只有收藏的联系人可以响;GitHub 只开了 mention 和 review request 的通知;邮件保留了,但过滤器设置得很严格,只有"发给我"并且"不是广告"的才会推送。

这个网站某种程度上就是那次实验的延续——我想要一个没有红点、没有点赞数、没有人催我更新、没有推送打扰我的地方。一个可以慢下来、写一半就停下、随时回来继续的角落。

它不会"叮"我。我想起来的时候,它就在这里。

这种感觉很舒服。像回到了互联网刚开始的时候,你打开一个网站,是因为你想看,而不是因为它在催你。

逛了很多人的个人站,我慢慢分清了两类:一类是"门面",精致、克制、为了给别人看;一类是"自留地",随性、生长、首先为了自己。我想要的是后者。

"门面"和"自留地"

门面型的站点很好认:导航栏四个链接(About / Work / Blog / Contact),首页一张巨大的头像或者作品集封面,每篇博客都像精修过的论文,排版一丝不苟,甚至连 footer 的字体大小都精确到 0.1rem。

这没什么不好。但我发现这类站点有个共同特征:它们更新很慢,或者根本不更新。

不是作者懒,是门槛太高了。当你把自己的站点当成一个"展示窗口",你写每一篇博客都会先问自己:"这东西够格放上去吗?会不会显得我很业余?"然后你就不写了。

自留地型的站点完全相反。可能首页就是一个时间线,随手扔点东西进去——今天是一个项目,明天是一张照片,后天可能就是一句话。排版不一定精致(但也不丑),整体感觉就像一个人的工作台,有点乱,但每样东西都在它该在的地方。

**这种站点的特点是:你能感觉到作者经常回来。**不是为了维护,是为了用。

我想要什么

我花了两周时间想清楚了几件事:

1. 它应该足够好看,好看到我自己愿意常回来

这不矛盾。好看不等于精致到不敢动。我希望它有一套舒服的配色、合适的留白、读起来不累的字号行高,但又不要设计过度到每次加点东西都要纠结"会不会破坏整体风格"。

这也是为什么我给它做了 11 套配色——不是为了炫技,是为了给自己留余地。今天想要暖一点,切到琥珀金;明天想要冷一点,切到靛蓝。心情变了,站点跟着变。

2. 它不能精致到让我不敢往里随便扔东西

我见过太多"完美"的网站最后变成了摆设。作者不敢更新,因为怕新内容不够好、怕风格不统一、怕破坏了"完整性"。

所以我给自己定了个规矩:博客可以写半成品的想法,可以写一句话,可以写到一半就发出去,以后再补。项目也不用等"做完了"才能放上来——做到哪算哪,能用就行。

3. 它该有展示项目的地方,也该有写一句废话的地方

这个站上既有正经的开源项目、部署在 Cloudflare 上的服务,也有"今天拍到一束很好看的光"这种没什么营养的碎碎念。

我不觉得这很割裂。人本来就是多面的,我写代码,也拍照,也会为了一个配色纠结半天,也会在凌晨四点想通一个问题然后爬起来改代码。这些都是我,为什么要藏起来?

说到底

说到底,它是一个会随我一起慢慢变的容器

今天它是这个样子——五篇博客、四个项目、十一套配色。明年回来看,希望它已经长出了我现在没预料到的形状:可能多了一个相册页,可能博客写到了三十篇,可能我又折腾了一套完全不同的设计。

不着急。这个站没有 deadline,没有 KPI,不需要对任何人交代。它唯一的用户是我自己,唯一的目标是:让我想回来。

这篇就当是它的第一块地基吧。下次再来,希望这里已经有了更多故事。