<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Markdown on kenji.blog</title><link>http://kenji.blog/zh-cn/tags/markdown/</link><description>Recent content in Markdown on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 02:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/zh-cn/tags/markdown/index.xml" rel="self" type="application/rss+xml"/><item><title>使用Hugo的静态网站生成器入门（从WordPress迁移步骤）</title><link>http://kenji.blog/zh-cn/p/hugo-static-site-generator-wordpress-migration/</link><pubDate>Sun, 13 Sep 2026 02:00:00 +0900</pubDate><guid>http://kenji.blog/zh-cn/p/hugo-static-site-generator-wordpress-migration/</guid><description>&lt;img src="http://kenji.blog/p/hugo-static-site-generator-wordpress-migration/img/eyecatch.jpg" alt="Featured image of post 使用Hugo的静态网站生成器入门（从WordPress迁移步骤）" />&lt;p>在现代Web开发和博客运营中，网站的加载速度、安全性以及可维护性已成为极其重要的因素。长期以来，作为博客和企业网站基础而占据压倒性市场份额的“WordPress”，凭借其灵活的插件生态系统和直观的管理界面，深受广大用户喜爱。然而，由于它需要与数据库进行通信以及在服务器端进行动态页面生成（通过PHP处理），因此也面临着应对流量激增时的脆弱性以及加载延迟（Latency）等问题。&lt;/p>
&lt;p>因此，近年来“静态网站生成器（SSG: Static Site Generator）”正在迅速普及。在本文中，我们将深入探讨在众多SSG中基于Go语言开发、以其惊人的构建速度而闻名的“&lt;strong>Hugo&lt;/strong>”。我们将从它与WordPress等动态CMS（Content Management System）的技术架构对比，到具体的迁移步骤、使用数理模型进行的性能评估，以及Hugo特有的目录结构和模板查找顺序，进行彻底的解析。&lt;/p>
&lt;hr>
&lt;h2 id="1-动态cmswordpress与静态网站生成器hugo的技术差异">1. 动态CMS（WordPress）与静态网站生成器（Hugo）的技术差异
&lt;/h2>&lt;p>在网站分发机制方面，WordPress和Hugo采用了根本不同的方法。&lt;/p>
&lt;h3 id="11-wordpress架构动态生成">1.1 WordPress架构（动态生成）
&lt;/h3>&lt;p>WordPress是每次收到请求时在服务器端构建页面的动态CMS代表。当用户（浏览器）访问页面时，Web服务器（如Apache、Nginx）会执行PHP脚本，并向MySQL（或MariaDB）等关系型数据库发出查询。将从数据库获取的内容（文章数据、分类、标签、网站设置等）与模板文件结合，生成最终的HTML并返回给客户端。&lt;/p>
&lt;p>这种机制的优点是能够实时为每位访客生成不同的内容（例如：电商网站的购物车、登录用户的专属页面），但如果不恰当地设计缓存机制（如反向代理或插件等），将会剧烈消耗服务器资源。&lt;/p>
&lt;h3 id="12-hugo架构构建时预生成">1.2 Hugo架构（构建时预生成）
&lt;/h3>&lt;p>另一方面，正如“静态网站生成器”这个名称所示，Hugo不是在“请求时”而是在“构建时”生成内容。内容不保存在数据库中，而是作为受Git等版本控制管理的本地“Markdown文件”保留。
当开发者执行命令（&lt;code>hugo&lt;/code>）时，Hugo会读取Markdown文件，将数据注入到指定的HTML模板（布局文件）中，并生成完整的、纯粹的HTML/CSS/JS文件集合。&lt;/p>
&lt;p>生成的这些文件（静态资产）只需部署到Amazon S3、Cloudflare Pages、Netlify、Vercel或简单的Nginx服务器等“静态托管环境”中即可进行分发。由于既不需要数据库也不需要服务器端语言（如PHP），安全风险（如SQL注入和PHP漏洞等）会急剧降低，同时内容会被缓存到CDN（Content Delivery Network）的边缘节点上，使加载速度达到极限。&lt;/p>
&lt;p>下面通过Mermaid图来展示各自架构的差异。&lt;/p>
&lt;pre class="mermaid">
flowchart TD
subgraph WordPress[&amp;#34;动态CMS (WordPress)&amp;#34;]
direction TB
Req1[&amp;#34;用户请求&amp;#34;] --&amp;gt; WebServer1[&amp;#34;Web服务器 (Nginx/Apache)&amp;#34;]
WebServer1 --&amp;gt; PHP[&amp;#34;PHP处理系统&amp;#34;]
PHP &amp;lt;--&amp;gt; DB[&amp;#34;数据库 (MySQL)&amp;#34;]
PHP --&amp;gt; HTML1[&amp;#34;生成HTML&amp;#34;]
HTML1 --&amp;gt; Res1[&amp;#34;返回响应&amp;#34;]
end
subgraph Hugo[&amp;#34;静态网站生成器 (Hugo)&amp;#34;]
direction TB
Dev[&amp;#34;开发者 / CI・CD&amp;#34;] --&amp;gt; HugoBuild[&amp;#34;Hugo构建处理&amp;#34;]
Markdown[&amp;#34;Markdown文件群&amp;#34;] --&amp;gt; HugoBuild
Templates[&amp;#34;模板 (HTML)&amp;#34;] --&amp;gt; HugoBuild
HugoBuild --&amp;gt; StaticFiles[&amp;#34;静态文件群 (HTML/CSS/JS)&amp;#34;]
StaticFiles --&amp;gt; CDN[&amp;#34;CDN / 静态托管&amp;#34;]
Req2[&amp;#34;用户请求&amp;#34;] --&amp;gt; CDN
CDN --&amp;gt; Res2[&amp;#34;立即返回响应&amp;#34;]
end
&lt;/pre>
&lt;hr>
&lt;h2 id="2-基于数理模型的性能评估">2. 基于数理模型的性能评估
&lt;/h2>&lt;p>从WordPress迁移到Hugo的最大优势之一就是性能（加载速度）的提升。为了定量地理解这一点，让我们用一个简单的数学模型来表达。&lt;/p>
&lt;p>页面加载完成所需的时间（Load Time: $T_{load}$）主要分为服务器响应时间（TTFB: Time To First Byte）和浏览器渲染与资源获取时间（$T_{render}$）。&lt;/p>
$$ T_{load} = T_{ttfb} + T_{render} $$&lt;p>对于动态CMS（WordPress），$T_{ttfb}$ 是以下要素的总和：网络延迟（$T_{network}$）、服务器端脚本执行时间（$T_{php}$）以及数据库查询处理时间（$T_{db}$）。&lt;/p>
$$ T_{ttfb\_wp} = T_{network} + T_{php} + T_{db} $$&lt;p>在访问集中的状态（高负载时），$T_{php}$ 和 $T_{db}$ 会呈非线性增长，整个系统可能成为瓶颈。用数学公式表示，相对于请求数（$N$），可以观察到如下的响应时间恶化（$k$ 是处理的开销系数）。&lt;/p>
$$ T_{php}(N) \approx O(N^k), \quad T_{db}(N) \approx O(N^k) \quad \text{where } k > 1 $$&lt;p>另一方面，在结合了静态网站生成器（Hugo）和CDN的架构中，不存在服务器端的动态处理（如PHP或DB查询）。由于内容被缓存在分布于世界各地的边缘服务器上，因此 $T_{ttfb}$ 纯粹仅依赖于客户端到最近边缘服务器的网络延迟（$T_{edge}$）。&lt;/p>
$$ T_{ttfb\_hugo} = T_{edge} $$&lt;p>由此，$T_{edge} \ll (T_{network} + T_{php} + T_{db})$ 成立，TTFB被极大地缩短至几毫秒到几十毫秒左右。此外，即使请求数 $N$ 增加，得益于边缘服务器的负载均衡功能，响应时间也基本保持恒定（$O(1)$）。&lt;/p>
$$ \lim_{N \to \infty} T_{ttfb\_hugo}(N) \approx \text{Constant} $$&lt;p>这就是Hugo（静态网站）在应对流量高峰（如内容爆火时）表现得极其稳健的数理依据。&lt;/p>
&lt;hr>
&lt;h2 id="3-hugo的基本结构与工作原理">3. Hugo的基本结构与工作原理
&lt;/h2>&lt;p>为了掌握Hugo，理解其独特的目录结构以及“Front Matter”和“Template Lookup Order（模板查找顺序）”的概念是必不可少的。&lt;/p>
&lt;h3 id="31-目录结构详细解析">3.1 目录结构详细解析
&lt;/h3>&lt;p>当新建一个Hugo项目（&lt;code>hugo new site mysite&lt;/code>）时，会生成如下的目录结构：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">mysite/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── archetypes/ # 新建内容时的模板（Front Matter的样板）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── assets/ # 由Hugo Pipes处理的文件群（SCSS/Sass, JavaScript等）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── content/ # 实际的网站内容（Markdown文件群）。这是数据库的替代品。
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── data/ # 网站全局使用的外部数据或设置（JSON, TOML, YAML, CSV等）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── layouts/ # 决定网站外观的HTML模板群（使用Go html/template）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── public/ # 执行构建命令后生成的静态文件的输出位置
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── static/ # 原样发布的静态文件（图片、favicon、robots.txt等）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── themes/ # 第三方或自制的主题目录
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">└── hugo.toml # 网站全局配置文件（以前 config.toml 较为主流）
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>在WordPress中，内容存储在MySQL的 &lt;code>wp_posts&lt;/code> 表中，而在Hugo中，一切都作为 &lt;code>content/&lt;/code> 目录下的文本文件（主要为Markdown）进行管理。这使得内容版本控制（Git）变得非常容易。&lt;/p>
&lt;h3 id="32-内容管理markdown与front-matter">3.2 内容管理：Markdown与Front Matter
&lt;/h3>&lt;p>Hugo的每一篇文章文件在最顶部都有一个被称为“Front Matter（前置数据）”的元数据块，其下方则是正文（Markdown）。Front Matter可以使用TOML、YAML、JSON中的任何一种编写，但YAML被最广泛地使用。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;理解Hugo的分类法（Taxonomy）&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">date&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ld">2026-09-13T10:00:00&lt;/span>&lt;span class="m">+09&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">draft&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">categories&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;技术解说&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">tags&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;Hugo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;Go&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">aliases&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/old-category/hugo-taxonomy/&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="l">这里开始是正文。使用**Markdown**来编写。&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="l">我们将为您讲解Hugo的强大功能...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>这里值得注意的是 &lt;code>aliases&lt;/code> 键。从WordPress迁移时，如果固定链接（URL）发生改变，将对SEO造成很大的负面影响。利用Hugo的别名功能，只需指定旧URL，Hugo就会自动生成用于重定向的HTML（通过meta refresh跳转）。由于不再需要服务器端的重定向配置（如.htaccess等），因此非常方便。&lt;/p>
&lt;h3 id="33-模板查找顺序template-lookup-order">3.3 模板查找顺序（Template Lookup Order）
&lt;/h3>&lt;p>Hugo强大的功能之一就是灵活的模板探索机制（Template Lookup Order）。在渲染特定页面时，Hugo会按照特定的顺序搜索目录和文件名，以找到最合适的模板。&lt;/p>
&lt;p>例如，在渲染单篇文章（Single Page） &lt;code>content/post/hello-world.md&lt;/code> 时，Hugo大致会按以下顺序查找布局文件：&lt;/p>
&lt;ol>
&lt;li>&lt;code>layouts/post/single.html&lt;/code>&lt;/li>
&lt;li>&lt;code>layouts/post/list.html&lt;/code> （虽然不是错误，但通常用于列表）&lt;/li>
&lt;li>&lt;code>layouts/_default/single.html&lt;/code>&lt;/li>
&lt;li>&lt;code>themes/&amp;lt;THEME_NAME&amp;gt;/layouts/post/single.html&lt;/code>&lt;/li>
&lt;li>&lt;code>themes/&amp;lt;THEME_NAME&amp;gt;/layouts/_default/single.html&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>开发者无需直接修改主题的源代码，只需在自己项目的 &lt;code>layouts/&lt;/code> 目录中创建同名文件，即可**覆盖（Override）**主题模板。这样，可以在不妨碍基础主题更新的情况下进行自定义。&lt;/p>
&lt;h3 id="34-分类法taxonomy">3.4 分类法（Taxonomy）
&lt;/h3>&lt;p>在Hugo中，相当于WordPress中的“分类（Categories）”和“标签（Tags）”的分类系统被称为“分类法（Taxonomy）”。
Hugo默认支持 &lt;code>categories&lt;/code> 和 &lt;code>tags&lt;/code> 分类法，通过编辑 &lt;code>hugo.toml&lt;/code>，您可以自由添加自定义分类法（例如：&lt;code>series&lt;/code>, &lt;code>authors&lt;/code> 等）。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># hugo.toml示例&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">taxonomies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">category&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;categories&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">tag&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;tags&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">series&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;series&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">author&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;authors&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>这使得从多维度对内容进行整理和列表化成为可能。&lt;/p>
&lt;hr>
&lt;h2 id="4-从wordpress到hugo的迁移过程migration">4. 从WordPress到Hugo的迁移过程（Migration）
&lt;/h2>&lt;p>从WordPress迁移到Hugo的成功关键在于：如何将数据库中的动态内容干净地转换为静态文件（Markdown + Front Matter），并保持现有的URL结构。&lt;/p>
&lt;p>下面展示了一般的迁移流水线流程。&lt;/p>
&lt;pre class="mermaid">
flowchart LR
WPDB[&amp;#34;WP数据库&amp;#34;] --&amp;gt;|插件| Exporter[&amp;#34;导出工具&amp;#34;]
Exporter --&amp;gt;| 提取文本, \n元数据, 图片 | ZipFile[&amp;#34;Zip / 文件夹&amp;#34;]
ZipFile --&amp;gt;|解压| MarkdownFiles[&amp;#34;Markdown文件 \n(content/)&amp;#34;]
ZipFile --&amp;gt;|解压| ImageFiles[&amp;#34;图片 \n(static/wp-content/)&amp;#34;]
MarkdownFiles --&amp;gt; Formatting[&amp;#34;审查 &amp;amp; 格式化 \n(修复简码)&amp;#34;]
Formatting --&amp;gt; Git[&amp;#34;提交到Git&amp;#34;]
&lt;/pre>
&lt;h3 id="41-数据的提取与markdown化">4.1 数据的提取与Markdown化
&lt;/h3>&lt;p>要导出WordPress数据供Hugo使用，最简单、最可靠的方法是使用专用插件。下面介绍几种代表性的方法。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>使用Jekyll Exporter插件&lt;/strong>
由于Hugo与同样是SSG的Jekyll数据结构非常相似，所以常用的方法是使用WordPress的“Jekyll Exporter”插件。安装并运行此插件后，所有的文章和页面都将转换为带有Front Matter的Markdown文件，并连同图片文件一起打包为ZIP文件供下载。&lt;/li>
&lt;li>&lt;strong>利用WordPress API自制脚本&lt;/strong>
这种方法是使用Python或Node.js等请求WordPress的REST API（&lt;code>/wp-json/wp/v2/posts&lt;/code>），解析JSON数据并自己编写脚本来生成Markdown文件。对于大量使用了插件无法完全兼容的复杂自定义字段（如ACF等）的网站非常有效。&lt;/li>
&lt;li>&lt;strong>活用wp2hugo工具&lt;/strong>
还有一种方法是利用Go语言等编写的CLI工具，将WordPress的导出XML文件（WXR）直接转换为Hugo格式。&lt;/li>
&lt;/ol>
&lt;h3 id="42-固定链接url结构的保持">4.2 固定链接（URL）结构的保持
&lt;/h3>&lt;p>为了继承SEO评分，原样保留WordPress时代的URL是极其重要的。如果WordPress中的固定链接设置为类似 &lt;code>https://example.com/2026/09/13/my-post/&lt;/code> 的格式，可以在Hugo的 &lt;code>hugo.toml&lt;/code> 中指定固定链接结构。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">permalinks&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">post&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;/:year/:month/:day/:slug/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>或者，也可以在每篇文章的Front Matter中直接指定 &lt;code>url&lt;/code> 参数，强制固定URL。
此外，对于URL会发生变更的页面，请使用前文提到的 &lt;code>aliases&lt;/code> 来设置重定向。&lt;/p>
&lt;h3 id="43-简码shortcodes的转换">4.3 简码（Shortcodes）的转换
&lt;/h3>&lt;p>WordPress特有的简码（如：&lt;code>[gallery]&lt;/code>, &lt;code>[caption]&lt;/code>，以及各种插件的专属代码）在导出时往往会作为原样字符串残留，因此需要处理。
可以使用替换脚本（sed或Python）批量删除它们，或者利用Hugo强大的&lt;strong>自定义简码功能&lt;/strong>（在 &lt;code>layouts/shortcodes/&lt;/code> 目录下创建独立的布局），将其迁移以便在Hugo端被正确渲染。&lt;/p>
&lt;hr>
&lt;h2 id="5-hugo的cli工具与构建部署">5. Hugo的CLI工具与构建・部署
&lt;/h2>&lt;p>迁移工作完成后，终于可以使用Hugo构建网站并向世界发布了。作为Go语言的二进制文件提供的Hugo，其令人惊叹的速度能在短短几秒内完成包含数千到数万个页面的网站构建。&lt;/p>
&lt;h3 id="51-启动本地开发服务器">5.1 启动本地开发服务器
&lt;/h3>&lt;p>在撰写文章或调整设计时，需要启动本地服务器。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 启动开发服务器命令（若包含Draft草稿文章则加上 -D）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hugo server -D
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>执行此命令后，您就可以在 &lt;code>http://localhost:1313/&lt;/code> 预览网站。Hugo内置了强大的“LiveReload”功能，当您编辑并保存Markdown文件、模板或CSS时，浏览器画面将自动高速刷新。得益于此，写作和开发体验将比WordPress的管理界面舒适得多。&lt;/p>
&lt;h3 id="52-生产环境构建与性能优化">5.2 生产环境构建与性能优化
&lt;/h3>&lt;p>要生成用于部署到生产环境的静态文件，只需输入 &lt;code>hugo&lt;/code> 即可。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 运行生产环境构建。使用 --minify 选项压缩HTML/CSS/JS&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hugo --minify
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>该命令将整个站点的文件输出到 &lt;code>public/&lt;/code> 目录。添加 &lt;code>--minify&lt;/code> 选项后，不必要的换行和空格将被删除，从而进一步缩减文件大小。这直接有助于降低前文数学模型中所述的网络延迟（$T_{network}$）。&lt;/p>
&lt;h3 id="53-部署自动化cicd">5.3 部署自动化（CI/CD）
&lt;/h3>&lt;p>每次都在本地PC生成静态文件然后通过FTP等方式上传是非常低效的。在现代SSG运营中，最佳实践是构建一个以推送到Git仓库（如GitHub等）为触发条件，自动进行构建和部署的CI/CD环境。&lt;/p>
&lt;p>例如，使用GitHub Actions部署到Cloudflare Pages或GitHub Pages的配置（YAML文件）基本形式如下所示：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># .github/workflows/hugo.yml 示例&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Deploy Hugo site to GitHub Pages&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">push&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branches&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">workflow_dispatch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">permissions&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">contents&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">read&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pages&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">write&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">id-token&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">write&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Checkout&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/checkout@v3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">submodules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">recursive&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># 如果使用子模块管理主题&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fetch-depth&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Setup Hugo&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">peaceiris/actions-hugo@v2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hugo-version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;latest&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">extended&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">hugo --minify&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Upload artifact&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/upload-pages-artifact@v2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">./public&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">deploy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">environment&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">github-pages&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">url&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ steps.deployment.outputs.page_url }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">needs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Deploy to GitHub Pages&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">deployment&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/deploy-pages@v2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>通过这样的配置，只需“用Markdown写文章并Push到GitHub”这一个操作，几分钟后最新的站点就会在生产环境上发布，从而完成自动化流水线的搭建。&lt;/p>
&lt;hr>
&lt;h2 id="6-迁移后的seo与运营层面的优势">6. 迁移后的SEO与运营层面的优势
&lt;/h2>&lt;p>完成从WordPress迁移到Hugo的网站运营者，大多能切实感受到以下三个显著的优势：&lt;/p>
&lt;h3 id="61-网站速度与core-web-vitals的急剧提升">6.1 网站速度与Core Web Vitals的急剧提升
&lt;/h3>&lt;p>由于排除了数据库查询和服务器端的渲染，页面的加载时间被缩短到毫秒级。这直接关系到作为Google排名因素的“核心网页指标（Core Web Vitals）”（LCP、FID/INP、CLS）得分的大幅提升。可以期待用户跳出率的下降以及SEO排名的提升。&lt;/p>
&lt;h3 id="62-摆脱安全威胁">6.2 摆脱安全威胁
&lt;/h3>&lt;p>由于WordPress在世界各地被广泛使用，它经常成为攻击目标。始终伴随着利用插件漏洞进行的篡改、或通过暴力破解突破登录等风险。
但是，由Hugo生成的静态网站中，既不存在数据库，也不存在PHP环境，甚至连管理界面（登录表单）都没有。黑客没有空间入侵服务器并篡改数据库，安全风险无限接近于零。&lt;/p>
&lt;h3 id="63-免维护的运营">6.3 免维护的运营
&lt;/h3>&lt;p>在WordPress的运营中，需要进行本体版本升级、插件更新、PHP版本跟进等不间断的维护工作。还必须时刻担忧因兼容性问题导致网站崩溃的风险。
而使用Hugo，只需根据需要对工具本身进行升级即可，网站的代码本身是独立的文本文件群，因此拥有“即使放任不管也不会坏”的巨大安全感。&lt;/p>
&lt;hr>
&lt;h2 id="7-总结">7. 总结
&lt;/h2>&lt;p>在本文中，我们详细讲解了从类似WordPress的动态CMS迁移到基于Go语言的强大静态网站生成器“Hugo”的整个过程，包括技术架构的差异、利用数理模型进行的性能证明以及具体的迁移步骤。&lt;/p>
&lt;p>向静态网站生成器迁移虽然需要前期的学习成本（如Git的操作、Markdown语法、从终端执行CLI命令、理解模板引擎的规范等），但它能带来“压倒性的加载速度”、“坚固的安全性”以及“免维护”的回报，这些足以弥补其学习成本且绰绰有余。&lt;/p>
&lt;p>如果您的网站不需要频繁的设计变更或复杂的动态处理（如会员专属功能或高级电商功能等），而是主要用于信息发布（博客、媒体、企业网站），那么迁移到Hugo将是您最有效的技术投资之一。请务必参考本文，迈出使用Hugo运营新一代网站的第一步吧。&lt;/p></description></item><item><title>使用 Markdown 撰写技术博客：让写作速度翻倍的编辑器设置</title><link>http://kenji.blog/zh-cn/p/markdown-editor-setup-for-tech-blogs/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/zh-cn/p/markdown-editor-setup-for-tech-blogs/</guid><description>&lt;img src="http://kenji.blog/p/markdown-editor-setup-for-tech-blogs/img/eyecatch.jpg" alt="Featured image of post 使用 Markdown 撰写技术博客：让写作速度翻倍的编辑器设置" />&lt;p>为了能够持续撰写技术博客，优化写作环境是必不可少的。本文将深入探讨如何通过高级编辑器设置，在使用 Markdown 撰写技术博客时使写作速度得到飞跃性的提升。我们将全面介绍 Visual Studio Code (VS Code) 和 Neovim 的极限自定义、代码片段的运用、引入日语（中文）语法检查工具 textlint 以及在 CI/CD 流水线中实现自动化，最后还会介绍利用 GitHub Copilot 等 LLM 的最前沿写作技巧。&lt;/p>
&lt;h2 id="1-提高写作速度的数学模型">1. 提高写作速度的数学模型
&lt;/h2>&lt;p>编辑器设置的优化到底能在多大程度上影响写作时间呢？首先让我们用简单的数学公式来进行建模。假设撰写一篇博客文章的总输入时间为 $T_{total}$。&lt;/p>
$$
T_{total} = T_{think} + T_{type} + T_{format} + T_{review}
$$&lt;p>这里，$T_{think}$ 是思考时间，$T_{type}$ 是打字时间，$T_{format}$ 是调整 Markdown 等格式的时间，$T_{review}$ 是推敲和校对时间。&lt;/p>
&lt;p>通过编辑器的自定义（例如引入代码片段或 Linter 设置等）所节省的时间 $T_{saved}$，可以用某个特定模式（例如 Hugo 的短代码或 Markdown 表格）的出现次数 $N$，手动输入所需时间 $t_{manual}$，以及通过代码片段等自动化手段所需时间 $t_{snippet}$，来表示如下：&lt;/p>
$$
T_{saved} = \sum_{i=1}^{k} N_i \times (t_{manual, i} - t_{snippet, i}) + T_{review\_saved}
$$&lt;p>此外，通过引入自动格式化和 Lint 工具，能够大幅减少人工目视检查的时间 $T_{review}$。将这个 $T_{saved}$ 最大化，正是本文的目的。&lt;/p>
&lt;h2 id="2-visual-studio-code-vs-code-的最强设置">2. Visual Studio Code (VS Code) 的最强设置
&lt;/h2>&lt;p>VS Code 是目前最普及的编辑器之一，在 Markdown 写作方面也拥有强大的扩展插件生态系统。&lt;/p>
&lt;h3 id="推荐扩展插件">推荐扩展插件
&lt;/h3>&lt;p>为了加快写作速度，强烈建议安装以下扩展插件：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Markdown All in One&lt;/strong>：提供通过快捷键实现加粗、斜体、自动延续列表、自动生成目录 (TOC) 等 Markdown 写作所需的所有基本功能。&lt;/li>
&lt;li>&lt;strong>markdownlint&lt;/strong>：实时警告 Markdown 语法错误或样式违规。&lt;/li>
&lt;li>&lt;strong>vscode-textlint&lt;/strong>：应用面向技术文档的规则集，防止出现表达不一致或语法错误。&lt;/li>
&lt;/ol>
&lt;h3 id="hugo-专属代码片段设置-markdownjson">Hugo 专属代码片段设置 (&lt;code>markdown.json&lt;/code>)
&lt;/h3>&lt;p>如果你使用 Hugo 或 Docusaurus 等静态网站生成器作为技术博客，就会频繁输入 Frontmatter 或专属的短代码。使用 VS Code 的代码片段功能，可以一键展开这些内容。&lt;/p>
&lt;p>从命令面板中选择 &lt;code>Preferences: Configure User Snippets&lt;/code>，并在 &lt;code>markdown.json&lt;/code> 中添加以下设置：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Hugo Frontmatter&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prefix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;frontmatter&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;body&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;title: \&amp;#34;${1:标题}\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;slug: \&amp;#34;${2:slug-name}\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;date: \&amp;#34;$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE T$CURRENT_HOUR:$CURRENT_MINUTE:$CURRENT_SECOND+09:00\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;image: \&amp;#34;img/eyecatch.jpg\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;math: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;mermaid: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;categories: [\&amp;#34;${3:Category}\&amp;#34;]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;tags: [\&amp;#34;${4:Tag1}\&amp;#34;, \&amp;#34;${5:Tag2}\&amp;#34;]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;${0}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;展开用于 Hugo 的 YAML Frontmatter&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Hugo Figure Shortcode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prefix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;hfig&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;body&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;{{&amp;lt; figure src=\&amp;#34;${1:image.jpg}\&amp;#34; title=\&amp;#34;${2:图片标题}\&amp;#34; &amp;gt;}}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Hugo 的 Figure 短代码&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Markdown Table&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prefix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;mtable&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;body&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| ${1:Header 1} | ${2:Header 2} | ${3:Header 3} |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| :--- | :---: | ---: |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| ${4:Row 1} | ${5:Data} | ${6:Data} |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| ${7:Row 2} | ${8:Data} | ${9:Data} |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;$0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;生成 3 列的 Markdown 表格&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>通过此设置，只需输入 &lt;code>frontmatter&lt;/code> 然后按下 Tab 键，包含当前时间的 YAML Frontmatter 就会瞬间展开，极大提升了写作的初始速度。&lt;/p>
&lt;h3 id="利用-github-copilot-辅助写作">利用 GitHub Copilot 辅助写作
&lt;/h3>&lt;p>在 VS Code 中启用 GitHub Copilot 后，根据上下文的 AI 补全功能同样适用于 Markdown。特别是在技术博客中，AI 会预判并建议“接下来应该说明的结构”或“相关的代码块”，因此可以大幅减少打字时间 $T_{type}$。&lt;/p>
&lt;h2 id="3-neovim-的极限自定义">3. Neovim 的极限自定义
&lt;/h2>&lt;p>虽然 VS Code 的 GUI 非常优秀，但对于终端爱好者和 Vimmer 来说，双手完全不离开键盘即可完成所有操作的 Neovim 才是最强的选择。&lt;/p>
&lt;h3 id="neovim-lsp-架构">Neovim LSP 架构
&lt;/h3>&lt;p>在 Markdown 环境下，Neovim 的 LSP (Language Server Protocol) 及 Linter 架构如下所示：&lt;/p>
&lt;pre class="mermaid">
classDiagram
class Neovim {
+&amp;#34;Text Buffer&amp;#34;
+&amp;#34;Keymaps&amp;#34;
}
class nvim_lspconfig {
+&amp;#34;marksman (Markdown LSP)&amp;#34;
}
class null_ls_or_none_ls {
+&amp;#34;markdownlint&amp;#34;
+&amp;#34;textlint&amp;#34;
}
class LuaSnip {
+&amp;#34;Dynamic Snippets&amp;#34;
}
class CMP {
+&amp;#34;Auto Completion Engine&amp;#34;
}
Neovim --&amp;gt; nvim_lspconfig : &amp;#34;提供语义功能&amp;#34;
Neovim --&amp;gt; null_ls_or_none_ls : &amp;#34;诊断与格式化&amp;#34;
Neovim --&amp;gt; CMP : &amp;#34;补全请求&amp;#34;
CMP --&amp;gt; nvim_lspconfig : &amp;#34;LSP 源&amp;#34;
CMP --&amp;gt; LuaSnip : &amp;#34;代码片段源&amp;#34;
&lt;/pre>
&lt;h3 id="使用-luasnip-实现高级代码片段展开">使用 LuaSnip 实现高级代码片段展开
&lt;/h3>&lt;p>比 VS Code 的 JSON 代码片段更强大的是 Neovim 的插件 &lt;code>LuaSnip&lt;/code>。它可以利用 Lua 的逻辑，动态地计算和展开代码片段的内容。&lt;/p>
&lt;p>以下是动态获取当前时间并展开 Hugo Frontmatter 的 LuaSnip 设置示例：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-lua" data-lang="lua">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">ls&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;luasnip&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">s&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.snippet&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.text_node&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.insert_node&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.function_node&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">-- 获取当前 JST 时间的函数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="kr">function&lt;/span> &lt;span class="nf">get_current_date_jst&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">return&lt;/span> &lt;span class="n">os.date&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;!%Y-%m-%dT%H:%M:%S&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">..&lt;/span> &lt;span class="s2">&amp;#34;+09:00&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">end&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ls.add_snippets&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;markdown&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">s&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;frontmatter&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;title: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Title&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;slug: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;slug-name&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;date: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kr">function&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kr">return&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="n">get_current_date_jst&lt;/span>&lt;span class="p">()}&lt;/span> &lt;span class="kr">end&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;image: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">img/eyecatch.jpg&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;math: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;mermaid: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;categories: [&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Category&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;tags: [&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Tag&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">s&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;mtable&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;| &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Header 1&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; | &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Header 2&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;|---|---|&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;| &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Cell 1&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; | &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Cell 2&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; |&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>像这样，借助于编程语言 (Lua) 的力量，我们不仅可以插入固定的字符串，还可以嵌入函数的返回值，或者根据输入的字符数动态增减表格的列数，创建这种极其灵活变态的代码片段。&lt;/p>
&lt;h2 id="4-兼顾写作质量与速度的静态分析-textlint-与正则表达式">4. 兼顾写作质量与速度的静态分析 (textlint 与正则表达式)
&lt;/h2>&lt;p>为了保证博客的质量，必须防止出现错别字、漏字或表达不一致的情况。如果手动进行这项工作，将会导致 $T_{review}$ 爆炸式增长，因此我们需要引入 &lt;code>textlint&lt;/code> 进行静态分析。&lt;/p>
&lt;h3 id="textlint-的引入与规则集">textlint 的引入与规则集
&lt;/h3>&lt;p>在 Node.js 环境下安装 textlint：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install -D textlint textlint-rule-preset-ja-technical-writing textlint-rule-prh textlint-filter-rule-comments
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>在项目根目录下创建 &lt;code>.textlintrc.json&lt;/code>，并进行如下设置：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;filters&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;comments&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rules&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;preset-ja-technical-writing&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ja-no-mixed-period&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;periodMark&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;。&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sentence-length&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;max&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">100&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prh&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rulePaths&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;./prh.yml&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>创建 &lt;code>prh.yml&lt;/code>，定义技术术语的统一表达方式。例如，统一“服务器”与“伺服器”、“Javascript”与“JavaScript”等。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">rules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">expected&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;JavaScript&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Javascript&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">expected&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;服务器&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;伺服器&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">expected&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;接口&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;介面&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>这样一来，每次在编辑器中输入文字时，都会实时警告表达不一致的情况，使得校对时间几乎降至为零。&lt;/p>
&lt;h3 id="使用正则表达式进行批量替换与结构化模式">使用正则表达式进行批量替换与结构化模式
&lt;/h3>&lt;p>将现有文章迁移到 Markdown 或从外部引入文本时，使用正则表达式进行批量替换会非常方便。&lt;/p>
&lt;p>例如，将 HTML 的 &lt;code>&amp;lt;b&amp;gt;强调&amp;lt;/b&amp;gt;&lt;/code> 标签转换为 Markdown 的 &lt;code>**强调**&lt;/code> 的正则表达式：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>搜索模式&lt;/strong>：&lt;code>&amp;lt;b&amp;gt;(.*?)&amp;lt;/b&amp;gt;&lt;/code>&lt;/li>
&lt;li>&lt;strong>替换模式&lt;/strong>：&lt;code>**$1**&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>将多余的连续换行合并为一个：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>搜索模式&lt;/strong>：&lt;code>\n{3,}&lt;/code>&lt;/li>
&lt;li>&lt;strong>替换模式&lt;/strong>：&lt;code>\n\n&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>通过在 VS Code 的搜索替换功能（正则表达式模式）或 Neovim 的 &lt;code>%s&lt;/code> 命令（&lt;code>:%s/&amp;lt;b&amp;gt;\(.*?\)&amp;lt;\/b&amp;gt;/**\1**/g&lt;/code>）中执行这些操作，可以瞬间统一格式。&lt;/p>
&lt;h3 id="通过-cicd-流水线进行自动检查">通过 CI/CD 流水线进行自动检查
&lt;/h3>&lt;p>此外，利用 GitHub Actions 构建 CI 流水线，在 push 博客文章时自动运行 textlint。这样可以防患于未然，避免部署存在违规的文章。&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;作者&amp;#34;] --&amp;gt;|推送更改| B[&amp;#34;GitHub 仓库&amp;#34;]
B --&amp;gt; C{&amp;#34;触发 GitHub Actions&amp;#34;}
C --&amp;gt; D[&amp;#34;检出仓库&amp;#34;]
D --&amp;gt; E[&amp;#34;设置 Node.js&amp;#34;]
E --&amp;gt; F[&amp;#34;npm install&amp;#34;]
F --&amp;gt; G[&amp;#34;运行 textlint&amp;#34;]
G --&amp;gt;|通过| H[&amp;#34;构建 Hugo 网站&amp;#34;]
G --&amp;gt;|失败| I[&amp;#34;向 PR/Commit 报告错误&amp;#34;]
H --&amp;gt; J[&amp;#34;部署到托管平台 (Vercel/Netlify)&amp;#34;]
&lt;/pre>
&lt;h2 id="5-llm-时代的-markdown-写作技巧">5. LLM 时代的 Markdown 写作技巧
&lt;/h2>&lt;p>在现代技术博客的写作中，LLM (Large Language Model) 的运用是不可避免的。通过利用编辑器内置的 AI 工具，写作速度将进一步成倍增长。&lt;/p>
&lt;h3 id="编辑器内的提示词工程">编辑器内的提示词工程
&lt;/h3>&lt;p>使用 VS Code 的 GitHub Copilot Chat，或者 Neovim 的 &lt;code>ChatGPT.nvim&lt;/code> 和 &lt;code>Copilot.vim&lt;/code> 等工具，无需离开编辑器即可发出如下提示词：&lt;/p>
&lt;blockquote>
&lt;p>“请针对以下技术要素，为初学者以 Markdown 的层级结构编写大纲：Docker, Kubernetes, CI/CD”&lt;/p>
&lt;/blockquote>
&lt;p>这样，AI 会立即生成带有标题和项目符号的 Markdown。我们只需要在这些骨架上填充血肉即可。&lt;/p>
&lt;p>此外，对于复杂的 Mermaid 图表或数学公式 (LaTeX) 的编写，通过向 AI 下达指令，它也能生成准确的语法。例如，本文中展示的数学公式和图表布局的基础，也是通过与 LLM 结对写作而加速完成的。&lt;/p>
&lt;h2 id="6-总结">6. 总结
&lt;/h2>&lt;p>本文介绍了在使用 Markdown 撰写技术博客时，能使写作速度翻倍的编辑器设置。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>建立数学模型的意识&lt;/strong>：为了将 $T_{saved}$ 最大化，消除所有重复性工作。&lt;/li>
&lt;li>&lt;strong>活用 VS Code&lt;/strong>：通过扩展插件和 &lt;code>markdown.json&lt;/code> 中的代码片段来省略输入。&lt;/li>
&lt;li>&lt;strong>Neovim 的极限自定义&lt;/strong>：利用 &lt;code>LuaSnip&lt;/code> 实现动态代码片段和纯键盘操作。&lt;/li>
&lt;li>&lt;strong>textlint 与静态分析&lt;/strong>：整合本地 Linter 与 CI/CD，将校对时间逼近于零。&lt;/li>
&lt;li>&lt;strong>整合 LLM&lt;/strong>：直接在编辑器中让 AI 输出 Markdown 的结构和图表代码。&lt;/li>
&lt;/ol>
&lt;p>将这些设置引入到自己的环境中，就能消除写作的“麻烦感”，极大提高技术输出的数量与质量。不妨从注册一个小小的代码片段开始尝试一下吧。&lt;/p></description></item></channel></rss>