今天是 2026 年 10 月 18 日,星期天。
下午两点五十多,我盯着侧栏看了几秒,才意识到一件有点丢人的事:运行天数还是旧的。
算错倒没有。那个数字是上次构建那天写死在 HTML 里的,压根没重新构建。只要我不改代码、不重新发布,它就会一直假装「今天」还是那一天。
这破事成了今天下午的起点。顺手把这几天攒下的零碎一起理一理,写成这篇。搭站全过程、域名证书、Folia 移植,前面都单独有文章,这里一个字都不再重复。只记 12 号之后到今天真正新发生的事。
---
\1先把名字安下来:「归舸的大窝」
1.1 名字为什么又改
站名改过不止一次。前几轮是:我的博客 → zixuann → zixuann 的记忆终端。
「记忆终端」这四个字是跟风来的。看别人的站用类似的调调,觉得酷,拿过来也用了几天。用着用着就发现不对:这不像我。像某极客项目的代号,像赛博风的网文标题,像产品经理写的 slogan,唯独不像一个十六七岁、平时打打无畏契约、偶尔瞎想的人住的地方。
「大窝」是你说出来的。我一听就觉得对。
窝是什么?窝是住的地方,就是睡觉、打游戏、写点东西的窝。叫「终端」「空间」「宇宙」「元」都不对路。加个「大」字,还有点自嘲的意思:地方不大,口气不小;或者说,把心里那点空间撑得大一点。
1.2 改动范围
你以为改名字就是改两个字,其实牵一发而动全身:
- 构建脚本里的站点标题(
SITE_TITLE)。头图大标题、浏览器标签、分享卡片都吃这个 - 文章开篇那篇的标题。从「你好,欢迎来到记忆终端」改成「归舸的大窝」
- 页脚。从「记忆终端」改成「归舸的大窝」
- 站内还有残留的「记忆终端」字样。要搜干净,一处不漏
另外有个容易混的地方要理清:
- 顶栏 / 资料卡显示的「归舸」是 名
- 头图 / 页脚的「归舸的大窝」是 宅名
一个像门牌,一个像房子本体。这样分着其实挺合适。你要一起叫「归舸的大窝」也行,但现在这种「短名 + 宅名」的组合我更喜欢。
1.3 为什么名字这么重要
写程序的人容易觉得:名字是字符串,改个常量的事。做产品的人会告诉你:名字是别人记住你的第一件事。
个人站尤其如此。技术站可以用域名、用项目名撑着,但「窝」这种站,气质全靠名字。叫「记忆终端」,进来的人会以为这是个工具;叫「归舸的大窝」,进来的人会以为这是个人。
两种第一印象,差很多。
1.4 改名时踩到的小坑
改名本身顺利,但有一个细节差点漏掉。
头图大标题、页脚、文章标题都改完之后,本地预览一看,都对。推上去之后再看 RSS 和分享用的 <title>,还是旧的,因为浏览器标签和 OG 标题吃的是另一个变量。
后来把 SITE_TITLE 这一个源头收干净,所有派生的地方都指向它,才彻底。教训是:文案不要复制多份。 复制三份,就会有两份过期。源头只有一个,让模板去展开。
另外还有一个「记忆」层面的事。构建脚本注释、设计文档里还写着旧名字,不影响线上,但以后自己读代码会迷糊。顺手也改了。工程上的整洁和网页上的整洁,最后会互相影响。
---
\1头像:从假人插画到自己的图
2.1 以前为什么不满意
头像这事前后拉扯了很久。卡住的是「这是不是我」。
第一阶段:矢量小人。 自己用 SVG 画的。圆脸、腮红、两个丸子头、微笑弧。当时觉得可爱,发出去看了两天就开始尴尬。像儿童英语 App 的默认头像,像十年前论坛的预设表情。你说「太土了」的时候,我其实心里同意,只是嘴上想再抢救一下。
第二阶段:渐变字母「z」。 抽象、干净、现代、有点科技公司官网的味道。问题也在这:太像科技公司了。一个打瓦的小孩,顶着一个 SaaS 创业公司的 logo,违和。
第三阶段:无畏契约裁切。 从官方壁纸裁的方图,至少是自己喜欢的东西。但也不是自己。是 Riot 画的,是 Jett,不是我。
第四阶段:现在这张。 你发过来的图。方图,构图有意思,而且是 你选的、你给的,不是我在素材库里翻出来的。
头像的意义在这里:要找的是你愿意顶着走遍全站的那张图。
2.2 聊天附件的尴尬
中间有个小插曲值得记。
你在聊天里直接把图发过来了。我能看见,分辨率、构图、有没有水印,都看得一清二楚。但聊天附件落在系统里的位置,我翻遍了常见的上传目录、会话目录、临时目录,都找不到那个文件。
51892728352459143401750135713761.jpg 这个文件名我能看见,就是摸不到字节。
这事有点哲学意味:能看见,不等于能使用。 对 AI 是这样,对人也是这样。你看得到别人的成果,不等于你能把它装进自己的站。
后来你手动把文件放到:
E:\AI\MIMO\Blog\assets\51892728352459143401750135713761.jpg
1080×1080,本身就是方图。这下齐了。
2.3 裁水印
图底下有一条短视频平台的水印带。你说得很干脆:水印裁掉。
没有用什么智能消除。就是硬裁:
- 整幅图切掉底边大约 8%(1080 的 8% 差不多 86 像素,水印带绰绰有余)
- 裁掉之后取中心方形
- 缩到 512×512,JPEG 质量 92
为什么是 8%?少了怕留一截,多了怕裁到主体。这个数是看图定的,不是算出来的。图像处理这种事,最后还得眼睛说了算。
为什么缩到 512?网页头像用不到 1080。512 在视网膜屏上显示 256px 的区域都够清晰,文件还小,加载快。
2.4 两处一起换
你说:「方形有个 Z 的那个」要换,「没有 Z 的那个」也要换,都换成这张。
「有 Z 的」= 侧栏资料卡的大头像 「没有 Z 的」= 顶栏左上角那个小圆角块
这两处以前是两张不同的图(一张是头像图,一张是品牌小图标),现在统一成同一张。顺手把浏览器标签上的 favicon 也换成了同一张。
改完之后有种「终于收拾干净了」的感觉。以前打开网页,左上角一个样子,侧栏另一个样子,标签页又是一个样子。现在三处一致,全站就一个「我」。
2.5 头像这种事的心态
折腾这么久,最后发现选图的标准其实很简单:
- 自己看到不尴尬
- 打开网站时不会立刻想去改
- 过几周回来看,还认
做到这三条就行。不用好看,不用高级,不用二次元浓度多高。认就行。
2.6 换完头像的检查清单
换图不是「扔个文件」就完。我列过一个小清单:
- 侧栏大头像:要圆角、不变形
- 顶栏小图标:28×28 缩略下还要能认出来
- favicon:浏览器标签那个 16/32px 小不点
- 文章页、关于页的头像:路径前缀不同(
../assets),别 404 - 缓存:文件名不变的话,老访客可能还看到旧图
第五条最后是靠 Ctrl+F5 和等 CDN 过期解决的。头像这种小文件,缓存时间有时候比想的顽固。
以后如果还要换头像,最好直接改文件名,比如 avatar-v2.jpg,路径跟着改,省得和缓存较劲。这次没改名,是因为图是全新文件,问题不大。
折腾这么久,最后发现选图的标准其实很简单:
- 自己看到不尴尬
- 打开网站时不会立刻想去改
- 过几周回来看,还认
做到这三条就行。不用好看,不用高级,不用二次元浓度多高。认就行。
---
\1简介:删掉「写代码」
3.1 文案会「说假话」
资料卡和「关于」页里的简介,是网站的自我介绍。这东西写不好,整个站就会有股味道。
前一版里有「在写代码」。你说删掉。
删完变成:
打无畏契约、偶尔想东想西。这里慢慢同步生活、技术和灵感。
对比一下:
| 旧 | 新 | |----|----| | 在写代码、打无畏契约 | 打无畏契约 | | 像技术博主的身份标签 | 像平时说话 | | 读者的第一反应:哦,程序员 | 读者的第一反应:哦,普通人 |
不是说写代码不好。写代码当然是日常的一部分。但 写在名片上 和 写在日常里 是两回事。
名片要写「人设」。日常会自己透露。
把「在写代码」从名片上拿掉,是让人设退后一点,让日常往前一点。喜欢技术的人,看到「技术」分类、看到 Folia 移植那篇,自然知道你写代码。不喜欢技术的人,也不会一进站就被三个字劝退。
3.2 副标题同理
副标题也改过好几次。最后定的调子是「打瓦、想东想西,慢慢记下来」这种。
不要「正在同步生活、技术、灵感与未命名的片段」。那句像说明书,像同步日志,像某个笔记软件的默认文案。看着挺「文艺」,其实空。
「打瓦、想东想西」是具体的。谁打瓦,谁想东想西,一眼就懂。
文案这东西,具体就是真诚,抽象就是敷衍。哪怕抽象得很「有文采」,也是敷衍。
3.3 关于页跟着改
「关于」页是简介的加长版。大改不多,主要跟着简介的调子走,别一边名片上很随意,一边关于页又端起来。
关于页那种地方,最忌讳写成简历。学历、技能栈、获奖情况、联系邮箱列成表,那就成了投递。个人站的关于,应该像朋友问「你是谁」,你随口答的那两句。
---
\1阅读时长:6 分钟还是 41 分钟
4.1 问题的起因
「今日劳动小结」那篇的阅读时长显示 6 分钟。你要改成 41 分钟。
为什么会有 6 分钟?因为构建脚本按字数估:
预计阅读时间 ≈ 字数 ÷ 400 字/分钟
那篇文字量算下来,就是六七分钟的事。按这个公式,它没算错。
错的是「阅读时长」这个词的含义。
4.2 两种时长
| 概念 | 含义 | 那篇的真实值 | |------|------|-------------| | 读完文字要多久 | 眼睛扫过这些字 | 约 6 分钟 | | 这件事花了多久 | 从早折腾到晚 | 一整天 |
「劳动小结」是一篇 劳动存档,不是一篇 6 分钟的短文。那天从凌晨建站到改名、删友链、调部署,前后十小时以上。标 41 分钟已经是压缩过的说法,没把「盯着 GitHub Actions 转圈」的时间算进去。
4.3 改成可手写
在 frontmatter 里加了 minutes 字段:
minutes: 41
构建脚本逻辑:
- 有
minutes→ 用它 - 没有 → 按字数自动估
这样以后每篇自己定。讲技术干货的短文,可以标实际阅读时间;讲「干了一天活」的存档,可以标劳动时间。不用再改构建脚本。
「归舸的大窝」那篇以前也改过,从 1 分钟改成 18 分钟,一个道理。开张那篇文字不多,但「开张」这件事酝酿了四个多月,18 分钟都算客气。
4.4 顺手改的地方
改的时候把首页卡片、文章页头部、RSS 里的显示都核对了一遍。三个地方要一致,不能首页 41 分钟、点进去 6 分钟,那更怪。
---
4.5 「分钟」这个词的模糊性
其实「阅读时长」本身就是个模糊指标。
不同人读中文的速度差别很大。同样一篇:
- 扫读的人 3 分钟
- 认真读的人 8 分钟
- 边读边琢磨示例的人 20 分钟
- 当存档核对时间线的人 40 分钟
所以任何自动估算都是 善意的谎言。它给的是「一个大概、偏快的中位数」,不是承诺。
既然如此,那就干脆允许作者自己写。作者比公式更懂这篇是给谁看的、要不要细读。
这也顺带解决了一个尴尬:有的短文写得极其密,公式算 2 分钟,实际要读 10 分钟;有的长文是流水账,公式算 12 分钟,实际 5 分钟就过完了。手写字段是给「自知」留的口子。
\1运行天数:别再写死了
5.1 今天为什么想起来
下午看侧栏,数字不对。
18 号,从 6 号起算,应该是 13 天。页面上却还是个小数字。公式没错,是 数据过期了。
5.2 旧实现:构建时算死
days = (datetime.now() - start).days + 1 # 构建那一刻的 now
html = f"<b>{days} 天</b>" # 写死进 HTML
写完之后,这个 HTML 是死文件。除非:
- 我重新构建 + 推送
- 或者 GitHub Pages 自己重新生成
否则不管谁打开、什么时候打开,看到的都是我构建那天的数字。
对博客来说这能忍,对「运行天数」这种一眼就看出来不对的东西,不能忍。
5.3 新实现:浏览器现算
页面里只放起点:
<b id="run-days" data-start="2026-10-06">…</b>
浏览器打开时用 JS:
const start = new Date("2026-10-06T00:00:00");
const days = Math.floor((new Date() - start) / 86400000) + 1;
// 显示 days
每分钟 setInterval 刷一次。跨零点的长挂页面也会自己更新。
5.4 「今天 18 号怎么算」
你问的这个问题很实在。
运行天数 = 今天的日期 - 开站日期 + 1
= 18 - 6 + 1
= 13
为什么要 +1?因为 开站那天算第 1 天,不是第 0 天。人类的习惯是「第一天、第二天」,不是「过了 0 天、过了 1 天」。
另外手机和电脑如果时区不同,或者一个改了系统时间,两边显示可能差一天。这没办法。我们选择以 访客设备的本地时间 为准,比在服务器上算更省事,也更符合「你看到的今天」。
5.5 静态站的通病
这个坑很典型,值得单独说。
静态网页是死文件。 里面所有「看起来是动态的数据」,像天数、计数、倒计时、农历、距离生日还有几天,只要不是浏览器现算的,都会慢慢变成谎言。
解决办法只有两种:
- 经常重新构建,麻烦,会忘
- 浏览器里算,一次写对,永久有效
凡是「和时间有关、且不依赖服务端数据」的,都该往浏览器里塞。凡是「和人有关、需要持久化」的,才需要后端(比如评论、点赞)。
运行天数属于前者。所以不该出现在 Python 构建脚本里。
---
5.6 本地预览和线上的又一次不一致
改运行天数的时候,又踩了一次「改了 A,生效的是 B」。
本地 dist/index.html 已经是新的,有 run-days。同步到 docs/ 的时候报锁文件,只同步了一半。GitHub 那边 Pages 吃的是 docs/,所以线上一度还是旧的。
后来强制用 Copy-Item -Force 整目录覆盖,再推,才对齐。
这已经是第 N 次栽在「两个输出目录」上了:
dist/本地构建产物,给预览用docs/GitHub Pages 吃的目录
两者理论上应该永远一致。实践上经常不一致。以后可以考虑只维护一个目录,或者在构建脚本里把同步写进去,不要手动拷。
\1一次 git 事故
今天下午第二件事,是 git 丢了。
6.1 现象
推「运行天数」改动的时候,命令直接报:
fatal: not a git repository
不是身份问题,也不是分支问题,报错直说:这不是仓库。E:\AI\MIMO\Blog\.git 没了。
工作区里文章、样式、构建脚本都在。物理文件一个不少。丢的是 版本历史 和 和远程的联系。
6.2 当时的感觉
说实话,第一秒有点懵。
这个仓库从 10 月 6 日凌晨建起,二十多次提交,部署流程、CNAME、文章、头像,全在历史里。现在它说没就没。
但很快冷静下来:工作区还在。git 丢的是「记账本」,不是「货」。货在,账本可以重开。
6.3 处理步骤
第一步:中止一切危险操作。 有冲突先 git merge --abort,别在半吊子状态下改文件。
第二步:重新初始化。
git init
git remote add origin https://github.com/GuiGe101/blog.git
git fetch origin main
第三步:看清楚两边是什么关系。
- 本地:一堆未跟踪文件,无提交历史
- 远程:完整的
main历史
像两个人各记了一本账,对不上。
第四步:试着合并 → 冲突。
CONFLICT (add/add): assets/app.js
CONFLICT (add/add): build.py
CONFLICT (add/add): dist/index.html
...
add/add 冲突的意思是:两边都有这个文件,而且都是「新增」。git 不知道信谁。
这里有个纪律:冲突文件不瞎改。一改就容易把别人的改动删掉,或者把标记写进代码。先 abort,从长计议。
第五步:评估哪边新。
本地其实更完整:
- 含运行天数实时化
- 含你后来加的几篇文章
- 含新头像、新简介
远程相对旧。而且远程历史是「丢失前」的状态,和本地这堆文件无法自动对齐。
第六步:询问,征得同意后覆盖。
这种事 绝对不能自作主张。强制推送等于告诉远程:「我这本才是真的,你那本撕了。」
跟你确认后,你回「1」,执行:
git push origin HEAD:main --force-with-lease
成功。
--force-with-lease 比 --force 稍微安全:如果远程在我们 fetch 之后又被人改了,推送会被拒绝。属于「我以为我是最新」的保护。
第七步:上线核对。
推完等 Pages 发布,绕过缓存抓一次页面,确认 run-days、data-start 都在,功能正常。
6.4 为什么 .git 会丢
不清楚。可能的原因一堆:
- 某次清理误删
- 某个工具重建目录
- 同步/备份工具抽风
- 磁盘或权限问题
没有日志,没法定论。能定论的是教训。
6.5 教训
- 强制推送前必须确认。 这次问了,做得对。
- 工作区是本体。 仓库丢了,文件还在就有救。
- 定期
git status。 不用天天 commit,至少知道自己在哪条船。 - 重要仓库偶尔
git clone一份冷备。 远程是备份,但远程和本地一起坏的情况不是没有。 - 合并冲突时先 abort。 不要在慌的时候改冲突文件。
6.6 强制推送的规矩
这次用了 --force-with-lease,想把规矩写明白,以后照着来:
什么时候可以考虑:
- 本地是唯一真相,远程只是过期镜像
- 征得用户 / 队友明确同意
- 知道自己在覆盖什么
什么时候绝对不行:
- 没问过
- 远程可能有别人刚推的提交
- 自己也不确定本地是不是完整
命令优先级:
git push --force-with-lease # 优先,相对安全
git push --force # 慎用,会无条件覆盖
--force-with-lease 会在远程「比你上次见到的更新」时拒绝推送。这是廉价的保险,没有理由不用。
另外:合并冲突时,先 abort。 在冲突文件里手工改标记,十次有九次改花。改花的后果是「看起来解决了」,其实代码里夹着 <<<<<<<。这种问题部署后才炸,排查起来非常恶心。
- 强制推送前必须确认。 这次问了,做得对。
- 工作区是本体。 仓库丢了,文件还在就有救。
- 定期
git status。 不用天天 commit,至少知道自己在哪条船。 - 重要仓库偶尔
git clone一份冷备。 远程是备份,但远程和本地一起坏的情况不是没有。 - 合并冲突时先 abort。 不要在慌的时候改冲突文件。
---
\1其它小动作
零碎还有几笔,列一下:
7.1 副标题定调
留了「打瓦、想东想西」这个调子。不再像产品介绍,不再像同步日志。要的就是大白话。
7.2 「关于」页
跟着新简介改过。别一边名片上很随意,一边关于页又端起来。
7.3 CNAME 固化
构建脚本里加了写 CNAME 的步骤,每次 build 自动吐一份。避免再出现「构建完域名绑定丢了」的事故。
7.4 预览目录锁文件
本地构建完,往预览目录复制时偶尔报:
PermissionError: [WinError 32] 另一个程序正在使用此文件
一般是本地预览服务器占着文件。不影响 GitHub 发布,推的是 docs/,不是预览目录。顶多重跑一次复制。静态服务器在 Windows 上锁文件,日常现象。
7.5 没做完的事
你问过 源码能不能私有。当时说清楚了:
- GitHub Pages 免费版和公开仓库绑死
- 私有 = 网站可能挂,或要换 Cloudflare Pages / 付费
- 评论系统也依赖公开讨论区
还没定。先放着。真要藏,再迁不迟。
7.6 工具相关
GitHub 界面挂了翻译插件,看着方便,也会骗人:
main→ 「主要角色」18s→ 「18 岁」Deploy from a branch→ 「从分支部署」
对着「18 岁」找了半天失败原因,其实人家是「跑了 18 秒」。排查技术问题的时候,最好关掉翻译看原文。这条算今天白捡的经验。
---
\1时间线清单
给后来的自己对账,提醒自己这些也是亲手改过的地方:
| 时间 | 事情 | 备注 | |------|------|------| | 10-12 之后 | 站名定为「归舸的大窝」 | 标题、页脚、文章标题、RSS | | 这几天 | 换上自定义头像 | 裁水印、缩 512、三处统一 | | 这几天 | 简介删「在写代码」 | 文案去名片腔 | | 这几天 | 「劳动小结」阅读时长 41 分钟 | 加 minutes 手写字段 | | 10-18 下午 | 运行天数改实时 | 浏览器按设备时间算,每分钟刷新 | | 10-18 下午 | 本地 .git 丢失 | 重建 → 冲突 → 征得同意覆盖远程 | | 10-18 傍晚 | 写这篇存档 | 就是你现在读的这份 |
表格是给自己看的。以后如果站做大了、文章多了,回头搜「劳动小结」标签就能找到这一串。
---
\1这几天的体会
9.1 后期维护比初次搭建更磨人
搭站那天是很爽的。从零到一,有页面,有域名,有评论,里程碑一个接一个。
这几天干的都是「改一个字」「换一张图」「修一个过期数字」。单拎出来,没一个配得上「项目」。叠起来,才是「住得舒服」。
写博客也是一样:开通那天的兴奋是暂时的,每天愿意打开写两句才是真的。
9.2 静态站的动态数据都要现算
天数会过期,计数会漂移,缓存会撒谎,翻译会瞎翻。
凡是和「时间」有关的显示,别写死。这条经验值今天一下午。
9.3 「改成我」比「改成好看」难
无畏契约官方图好不好看?好看。比矢量小人高级多了。
那还不是我。
自己的图、自己的调调、自己的宅名,哪怕技术上简单得可笑(硬裁 8%、改个字符串),做出来才叫「我的窝」。
审美是及格线,身份是及格线以上的部分。
9.4 小事要记,不然会忘
劳动小结写过,Folia 写过,证书写过。这几天的小事不记,下周就只记得「好像改了点什么」。
写下来本身就是记忆的备份。跟 git 一样,平时觉得多余,丢了才知道有用。
9.5 静态站和「像动态的静态数据」
这一点值得再展开说。
静态站的好处是简单:没有服务器要养,没有数据库要备份,改错了回滚一次 git revert 就好。坏处也简单:页面是死的。
于是就容易出现一种诡异状态:网站看起来活的,有天数、有计数、有「最后更新」,其实全是构建那天化石下来的。
这种「像动态的静态数据」比没有数据更糟。没有天数,大家不会想;有一个过期的天数,大家一眼就看出不对。错误的数据比没有数据伤害更大。
解决它的分类法:
| 数据类型 | 例子 | 放哪算 | |---------|------|--------| | 和时间有关 | 运行天数、倒计时、今年第几天 | 浏览器 JS | | 和内容有关 | 字数、阅读时长、标签计数 | 构建时 Python | | 和访客有关 | 评论、点赞、阅读量 | 第三方 / 后端 |
运行天数属于第一类,所以必须挪到 JS。字数属于第二类,放在构建脚本里就行。评论属于第三类,塞不进静态 HTML。
分类清楚了,后面就不会再犯「把日历写进 HTML」的错。
9.6 13 天
今天开站第 13 天。
从「有域名、没页面」到「有窝、有名、有头像、有一堆自己写的字」,十三天。不算长。
以后回头看这篇,可能会笑现在抠的这些细节。但大概也会庆幸:抠过。
---
\1接下来
不写太多愿景,免得打脸。就几个小的:
- 多写内容,少折腾界面。 界面现在够住了。
- 瓦打得好看一点。 这是正事。
- Folia 继续拧。 那边还有没拧完的。
- 明年六月前记得给域名续费。 窝不能丢。
运行天数以后自己会数,不用我管。git 以后希望它争气。名字以后尽量不动了。「归舸的大窝」这五个字,动一次,全站跟着晃。
再补一句:写这篇的时候,顺手又点开侧栏看了一眼。天数是对的。这就够了。工具安静地工作,人就可以去干别的。折腾界面的意义,说到底是为了这个。
就先记到这里。
如果哪天你从别处点进这个窝,看到这篇又长又啰嗦的流水账,就当是屋主搬进来两周,坐在地上清点工具时的自言自语。
欢迎来到归舸的大窝。
![]()
