<?xml version="1.0" encoding="UTF-8"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>b1babo</title><description>写代码，也写字：记录构建、设计与日常思考。</description><link>https://gcbo.fun/</link><language>zh-cn</language><item><title>一篇 mdx 的旅程</title><link>https://gcbo.fun/posts/building-this-site/publishing/mdx/</link><guid isPermaLink="true">https://gcbo.fun/posts/building-this-site/publishing/mdx/</guid><description>frontmatter 元数据、路由总线与 PostLayout——单文件内容单元的完整管线。</description><pubDate>Sat, 31 Oct 2026 00:00:00 GMT</pubDate><category>MDX</category><content:encoded>&lt;article class="prose"&gt;&lt;h2 id="从落笔到页面"&gt;从落笔到页面&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#从落笔到页面"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;以 &lt;code&gt;posts/hello.mdx&lt;/code&gt; 为例。这个文件从写完到能访问，中间发生三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;lib/atlas.js&lt;/code&gt; 用 &lt;code&gt;import.meta.glob&lt;/code&gt; 读进所有 mdx 的 frontmatter，
和目录的 &lt;code&gt;atlas.json&lt;/code&gt; 合成一张登记表；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pages/[...slug].astro&lt;/code&gt; 按登记表生成路由——文件在 &lt;code&gt;posts/hello.mdx&lt;/code&gt;，
地址就是 &lt;code&gt;/posts/hello/&lt;/code&gt;，产物是 &lt;code&gt;dist/posts/hello/index.html&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;渲染时包上 &lt;code&gt;PostLayout&lt;/code&gt;：系列章节左栏挂目录树，题头带系列徽章、日期、
标签；散篇不挂树，上一篇/下一篇按日期相邻。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;frontmatter 长这样。有个小坑我踩过：日期要带引号，不然 YAML 会把它解析成
Date 对象，校验器直接报格式错误。&lt;/p&gt;
&lt;pre class="astro-code vitesse-light" style="background-color:#ffffff;color:#393a34;overflow-x:auto" tabindex="0" data-language="yaml"&gt;&lt;code&gt;&lt;span class="line"&gt;&lt;span style="color:#59873A"&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#998418"&gt;title&lt;/span&gt;&lt;span style="color:#999999"&gt;:&lt;/span&gt;&lt;span style="color:#B56959"&gt; 文章标题&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#998418"&gt;desc&lt;/span&gt;&lt;span style="color:#999999"&gt;:&lt;/span&gt;&lt;span style="color:#B56959"&gt; 一句话摘要（列表与 RSS 用）&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#998418"&gt;date&lt;/span&gt;&lt;span style="color:#999999"&gt;:&lt;/span&gt;&lt;span style="color:#B5695977"&gt; &quot;&lt;/span&gt;&lt;span style="color:#B56959"&gt;2026-10-31&lt;/span&gt;&lt;span style="color:#B5695977"&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#998418"&gt;tags&lt;/span&gt;&lt;span style="color:#999999"&gt;:&lt;/span&gt;&lt;span style="color:#999999"&gt; [&lt;/span&gt;&lt;span style="color:#B56959"&gt;检索词&lt;/span&gt;&lt;span style="color:#999999"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#998418"&gt;order&lt;/span&gt;&lt;span style="color:#999999"&gt;:&lt;/span&gt;&lt;span style="color:#2F798A"&gt; 1&lt;/span&gt;&lt;span style="color:#A0ADA0"&gt;        # 系列章节必填；分组里与兄弟同级排序&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#998418"&gt;draft&lt;/span&gt;&lt;span style="color:#999999"&gt;:&lt;/span&gt;&lt;span style="color:#1E754F"&gt; true&lt;/span&gt;&lt;span style="color:#A0ADA0"&gt;     # 草稿：不产出、不进列表与 RSS&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#59873A"&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mdx 和纯 markdown 的区别就一条：正文里可以 import 组件。开篇那篇 hello 里
的章节标题 &lt;code&gt;SectionHead&lt;/code&gt;，就是正文里一行 import 拿来用的——写文章时能用上
整套站点积木，这是当初选 mdx 而不是纯 markdown 的主要原因。&lt;/p&gt;&lt;/article&gt;</content:encoded></item><item><title>目录树侧栏与 RSS</title><link>https://gcbo.fun/posts/building-this-site/publishing/rss/</link><guid isPermaLink="true">https://gcbo.fun/posts/building-this-site/publishing/rss/</guid><description>分组上树、侧栏高亮，以及全文 RSS。</description><pubDate>Sat, 31 Oct 2026 00:00:00 GMT</pubDate><category>MDX</category><category>RSS</category><content:encoded>&lt;article class="prose"&gt;&lt;h2 id="左栏的树"&gt;左栏的树&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#左栏的树"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这个系列左边的目录树不用手工维护，数据就是目录结构本身：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;章节（mdx）是叶子链接；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;section&lt;/code&gt; 分组是分组标题，可以嵌套——“框架机制&quot;&quot;发布管线”就是两个分组；&lt;/li&gt;
&lt;li&gt;同级按 frontmatter 的 &lt;code&gt;order&lt;/code&gt; 混排，&lt;code&gt;SeriesTree&lt;/code&gt; 组件递归渲染，当前页高亮。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;桌面端侧栏 sticky 跟着滚动，移动端整棵树堆到正文上方。你现在在本页左侧看到
的就是它。&lt;/p&gt;
&lt;h2 id="prose-排版"&gt;prose 排版&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#prose-排版"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;mdx 渲染出来是裸 HTML，得有人管排版。&lt;code&gt;global.css&lt;/code&gt; 里一套 &lt;code&gt;.prose&lt;/code&gt; 样式接手：
标题下加虚线，引用块左边一条印章红，代码块用 Shiki 的 vitesse-light 配色。
文章页能和全站的纸面风格对上，靠的就是这一层。&lt;/p&gt;
&lt;h2 id="订阅源"&gt;订阅源&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#订阅源"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;rss.xml&lt;/code&gt; 也是构建期的产物：&lt;code&gt;src/pages/rss.xml.js&lt;/code&gt; 从登记表拿全部已发布文章，
生成标题、摘要、日期、分类，draft 天然不进。&lt;/p&gt;
&lt;p&gt;后来又补了一个构建后处理的小脚本：把每篇文章渲染出的 &lt;code&gt;&lt;article&gt;&lt;/code&gt; 整块注进
&lt;code&gt;content:encoded&lt;/code&gt;。原因是 Astro 7 的容器渲染不了 MDX 编译产物，只能在构建
完成后从产出的 HTML 里取。效果是订阅器里能直接读全文，不用点回网页。&lt;/p&gt;&lt;/article&gt;</content:encoded></item><item><title>你好，世界</title><link>https://gcbo.fun/posts/hello/</link><guid isPermaLink="true">https://gcbo.fun/posts/hello/</guid><description>小站开张：这是第一篇文章，也是 MDX 发布管线的验收单。</description><pubDate>Sat, 31 Oct 2026 00:00:00 GMT</pubDate><category>随笔</category><category>开场白</category><content:encoded>&lt;article class="prose"&gt;&lt;div class="relative max-w-prose mx-auto my-[1.8em] bg-paper-2/55 border-[1.5px] border-line rounded-card px-6 pt-[26px] pb-[18px]"&gt;&lt;span class="absolute -top-[13px] left-5 bg-paper px-2.5 font-brush text-[16px] leading-none text-seal tracking-[.15em]"&gt;引言&lt;/span&gt;&lt;p class="m-0 text-[16.5px] leading-[1.85] text-ink-2"&gt;这是第一篇。顺手把发布管线整个验收一遍。&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;小站开张。你现在看到的这页，就是这个 mdx 文件跑完 &lt;code&gt;astro build&lt;/code&gt; 的产物。
所以第一篇不讲道理，直接当验收单用——文中用到的每种排版能力，都是管线的
一部分。&lt;/p&gt;
&lt;div class="flex items-baseline gap-[14px] mb-2"&gt;&lt;span class="font-fell italic text-[15px] text-seal tracking-[.14em] whitespace-nowrap"&gt;No.01&lt;/span&gt;&lt;div&gt;&lt;h2 class="text-[31px] tracking-[.05em] leading-tight border-b-0 pb-0"&gt;这不是普通的 Markdown&lt;/h2&gt;&lt;svg class="w-[130px] h-[9px] mt-1 text-seal" viewBox="0 0 130 9" aria-hidden="true"&gt;&lt;path d="M2 6 C 18 2, 30 8, 46 5 S 78 2, 94 6 S 120 4, 128 5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" opacity=".65"&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;文件后缀是 &lt;code&gt;.mdx&lt;/code&gt;：markdown 里可以直接用组件。上面那块带「No.01」的章节
标题不是截图，是正文里一行 import 引入的 &lt;code&gt;SectionHead&lt;/code&gt; 组件。&lt;/p&gt;
&lt;h2 id="标题列表引用"&gt;标题、列表、引用&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#标题列表引用"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;标准 Markdown 全家桶都认：标题、列表、&lt;strong&gt;加粗&lt;/strong&gt;、&lt;a href="https://astro.build"&gt;链接&lt;/a&gt;、&lt;code&gt;行内代码&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;代码块带 Shiki 高亮：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="astro-code vitesse-light" style="background-color:#ffffff;color:#393a34;overflow-x:auto" tabindex="0" data-language="js"&gt;&lt;code&gt;&lt;span class="line"&gt;&lt;span style="color:#A0ADA0"&gt;// 路径即地址：内容目录树就是站点树&lt;/span&gt;&lt;/span&gt;
&lt;span class="line"&gt;&lt;span style="color:#1E754F"&gt;export&lt;/span&gt;&lt;span style="color:#AB5959"&gt; const&lt;/span&gt;&lt;span style="color:#59873A"&gt; u&lt;/span&gt;&lt;span style="color:#999999"&gt; =&lt;/span&gt;&lt;span style="color:#999999"&gt; (&lt;/span&gt;&lt;span style="color:#B07D48"&gt;p&lt;/span&gt;&lt;span style="color:#999999"&gt;)&lt;/span&gt;&lt;span style="color:#999999"&gt; =&gt;&lt;/span&gt;&lt;span style="color:#1E754F"&gt; import&lt;/span&gt;&lt;span style="color:#999999"&gt;.&lt;/span&gt;&lt;span style="color:#998418"&gt;meta&lt;/span&gt;&lt;span style="color:#999999"&gt;.&lt;/span&gt;&lt;span style="color:#B07D48"&gt;env&lt;/span&gt;&lt;span style="color:#999999"&gt;.&lt;/span&gt;&lt;span style="color:#B07D48"&gt;BASE_URL&lt;/span&gt;&lt;span style="color:#AB5959"&gt; +&lt;/span&gt;&lt;span style="color:#B07D48"&gt; p&lt;/span&gt;&lt;span style="color:#999999"&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;引用块长这样：左边一条印章红，底色微微泛红。&lt;/p&gt;
&lt;/blockquote&gt;




















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;元数据来源&lt;/th&gt;&lt;th&gt;载体&lt;/th&gt;&lt;th&gt;谁在用&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;目录&lt;/td&gt;&lt;td&gt;&lt;code&gt;atlas.json&lt;/code&gt;&lt;/td&gt;&lt;td&gt;索引页 / 系列&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;单文件&lt;/td&gt;&lt;td&gt;frontmatter&lt;/td&gt;&lt;td&gt;每篇 mdx&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id="图片直接住进文章"&gt;图片直接住进文章&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#图片直接住进文章"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://gcbo.fun/_astro/hello-cover.DI9BEt_y_680Ak.webp" alt="路径即地址" loading="lazy" decoding="async" width="640" height="360"&gt;&lt;/p&gt;
&lt;p&gt;图片跟 mdx 放同一目录、相对路径引用，构建时自动走 &lt;code&gt;astro:assets&lt;/code&gt; 优化，
产出带哈希的 &lt;code&gt;_astro/&lt;/code&gt; 资产。&lt;code&gt;content/&lt;/code&gt; 里不用另建资产目录。&lt;/p&gt;
&lt;h3 id="锚点与目录"&gt;锚点与目录&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#锚点与目录"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;每级标题都有了自己的 &lt;code&gt;id&lt;/code&gt;（悬停可见 &lt;code&gt;#&lt;/code&gt;），右侧的页内目录就是从这些 id
来的。长文回头翻某一段，不用滚来滚去。&lt;/p&gt;
&lt;p&gt;就写到这儿。下一篇见。&lt;/p&gt;&lt;/article&gt;</content:encoded></item><item><title>三条规矩</title><link>https://gcbo.fun/posts/building-this-site/framework/constitution/</link><guid isPermaLink="true">https://gcbo.fun/posts/building-this-site/framework/constitution/</guid><description>路径决定 URL、元数据自述身份、index.astro 自由创作——目录的四种角色。</description><pubDate>Fri, 30 Oct 2026 00:00:00 GMT</pubDate><category>Astro</category><category>框架设计</category><content:encoded>&lt;article class="prose"&gt;&lt;h2 id="三条规矩"&gt;三条规矩&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#三条规矩"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;给这个站立了三条规矩，多一条都嫌重：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;路径决定 URL&lt;/strong&gt;——目录层次就是地址层次，唯一的强约束；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;元数据自述身份&lt;/strong&gt;——目录的元数据写在 &lt;code&gt;atlas.json&lt;/code&gt; 里，单文件的写在 frontmatter 里；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;index.astro 是自由创作&lt;/strong&gt;——页面读哪些数据、拼哪些积木，框架不管。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第一条管地址，第二条管数据，第三条管自由度。这个站后来所有机制，都是从这三句
推出来的。&lt;/p&gt;
&lt;h2 id="目录的四种角色"&gt;目录的四种角色&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#目录的四种角色"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;目录在 &lt;code&gt;atlas.json&lt;/code&gt; 里自报一种 &lt;code&gt;type&lt;/code&gt;，和实际结构互验，写错了构建直接报错：&lt;/p&gt;






























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;type&lt;/th&gt;&lt;th&gt;结构条件&lt;/th&gt;&lt;th&gt;用途&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;&lt;td&gt;有子目录或散篇 mdx&lt;/td&gt;&lt;td&gt;索引页（如 &lt;code&gt;/posts/&lt;/code&gt;）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;series&lt;/code&gt;&lt;/td&gt;&lt;td&gt;有 mdx 章节&lt;/td&gt;&lt;td&gt;文档树：落地页 + 目录树侧栏&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;section&lt;/code&gt;&lt;/td&gt;&lt;td&gt;住在系列树里且非空&lt;/td&gt;&lt;td&gt;分组节点：只当树用，不承载页面&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;case&lt;/code&gt;&lt;/td&gt;&lt;td&gt;叶子&lt;/td&gt;&lt;td&gt;内容本身（自由创作的页面）&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;系列支持嵌套：&lt;code&gt;section&lt;/code&gt; 分组里还能再放 &lt;code&gt;section&lt;/code&gt;，像 doc 站那样把章节归组成树。
分组不需要 &lt;code&gt;index.astro&lt;/code&gt;——建个目录、写份元数据（&lt;code&gt;title&lt;/code&gt; + &lt;code&gt;order&lt;/code&gt;）就上树。
章节和分组的 &lt;code&gt;order&lt;/code&gt; 在同一层里混排，上一篇/下一篇沿整棵树深度优先走下来，
跨分组也是连续的。&lt;/p&gt;&lt;/article&gt;</content:encoded></item><item><title>构建期校验</title><link>https://gcbo.fun/posts/building-this-site/framework/validate/</link><guid isPermaLink="true">https://gcbo.fun/posts/building-this-site/framework/validate/</guid><description>两档校验与三向对账——坏数据在构建时报错，而不是上线后悄悄坏掉。</description><pubDate>Fri, 30 Oct 2026 00:00:00 GMT</pubDate><category>Astro</category><category>校验</category><content:encoded>&lt;article class="prose"&gt;&lt;h2 id="两档校验"&gt;两档校验&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#两档校验"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;lib/validate.js&lt;/code&gt; 在每次 dev / build 都会跑一遍，分两档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;data 模式&lt;/strong&gt;（恒开）：schema、角色和结构互验、markers 引用完整性、
mdx 地址与目录地址的撞车检测；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;full 模式&lt;/strong&gt;（设 &lt;code&gt;ATLAS_FULL=0&lt;/code&gt; 可临时关）：登记表和页面文件互相对账。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="它能拦住什么"&gt;它能拦住什么&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#它能拦住什么"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;举几个真实会报错的例子。同一目录下两个章节写了相同的 &lt;code&gt;order&lt;/code&gt;，构建直接失败：&lt;/p&gt;
&lt;pre class="astro-code vitesse-light" style="background-color:#ffffff;color:#393a34;overflow-x:auto" tabindex="0" data-language="txt"&gt;&lt;code&gt;&lt;span class="line"&gt;&lt;span&gt;[atlas] ../content/posts/building-this-site/publishing/rss.mdx: order 2 与 ../content/posts/building-this-site/publishing/mdx.mdx 重复——同一目录内序号必须唯一&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;往目录里塞 &lt;code&gt;index.mdx&lt;/code&gt;（目录索引只允许 &lt;code&gt;index.astro&lt;/code&gt; 承载）：&lt;/p&gt;
&lt;pre class="astro-code vitesse-light" style="background-color:#ffffff;color:#393a34;overflow-x:auto" tabindex="0" data-language="txt"&gt;&lt;code&gt;&lt;span class="line"&gt;&lt;span&gt;[atlas] (index.mdx): ../content/posts/index.mdx 不允许——目录索引一律用 index.astro（写系列引言请在落地页 astro 里写）&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还有散篇推导出的地址撞上目录、&lt;code&gt;section&lt;/code&gt; 分组建在系列树之外、markers 引用了
不存在的 id、散篇忘了写日期……全都一样：构建失败，错误信息带着文件路径，
当场改当场好。&lt;/p&gt;
&lt;h2 id="为什么这么严"&gt;为什么这么严&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#为什么这么严"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;静态站怕的不是报错，是错得没声音。章节顺序排错了、链接指空了，页面上一点
动静都没有，等哪天自己翻到了才发现，那时候它已经在线上挂了不知多久。&lt;/p&gt;
&lt;p&gt;构建期校验把这类事故拦在本地。报错烦人，但比悄悄坏掉强。&lt;/p&gt;&lt;/article&gt;</content:encoded></item><item><title>为什么自己搭</title><link>https://gcbo.fun/posts/building-this-site/why/</link><guid isPermaLink="true">https://gcbo.fun/posts/building-this-site/why/</guid><description>旧站是 Trilium + Next.js，这次换成纯静态的 Astro——记一下选型的考虑。</description><pubDate>Thu, 29 Oct 2026 00:00:00 GMT</pubDate><category>建站</category><category>静态站点</category><content:encoded>&lt;article class="prose"&gt;&lt;h2 id="从旧站说起"&gt;从旧站说起&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#从旧站说起"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;旧博客（blog.gcbo.fun）是 2025 年年中搭的：Trilium 管内容，Next.js 负责呈现，
中间靠 API 缝合。用着没什么大毛病，但它终究是个动态服务——要跑 Node、要管
进程守护，Trilium 那头的笔记和页面之间也永远隔着一层转换逻辑。&lt;/p&gt;
&lt;p&gt;这次想换个活法：内容就是文件，构建完就是 HTML，扔到任意静态托管上就完事。
没有服务要挂，没有依赖要追，过几年回来打开还能用。&lt;/p&gt;
&lt;h2 id="为什么选-astro"&gt;为什么选 Astro&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#为什么选-astro"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;选型时最后定了 Astro，理由很实际：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内容就是文件。一篇 &lt;code&gt;.mdx&lt;/code&gt; 一篇文章，git 管着，任意编辑器能写；&lt;/li&gt;
&lt;li&gt;默认零运行时，产物是纯 HTML，页面不背框架 JS；&lt;/li&gt;
&lt;li&gt;页面怎么写，框架不管。这一点最合口味——下一篇会讲，我只给这个站
立了三条规矩。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至于为什么不是 Hugo、Hexo 这类纯生成器：我想在文章里直接用组件，比如开篇
那篇 hello 里的章节标题就是正文里 import 来的 &lt;code&gt;SectionHead&lt;/code&gt;。mdx 的灵活度
对我是刚需。为什么不是 Next.js SSG：旧站就是 Next.js，太自由了，自由到每个
页面都可以有自己的写法，写到后面自己都记不住哪套是哪套。&lt;/p&gt;
&lt;h2 id="只留一条规矩"&gt;只留一条规矩&lt;a class="heading-anchor" aria-hidden="true" tabindex="-1" href="#只留一条规矩"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;新站只保留一条强约束：&lt;strong&gt;路径决定 URL&lt;/strong&gt;。&lt;code&gt;src/content/&lt;/code&gt; 的目录树就是站点树，
也是构建产物的镜像——文件放哪，地址就在哪。&lt;/p&gt;
&lt;p&gt;其余全部自由。规矩少一点，写得下去的可能性就大一点。&lt;/p&gt;&lt;/article&gt;</content:encoded></item></channel></rss>