
摘要描述里说“第一期”但正文和关键词都是空的。这是一个非常典型的“只有标题”的项目素材。为了不编造事实也不把文章写成空洞的“壁纸合集”我决定把“徐欣壁纸”理解成一套个人知识笔记的代号用“壁纸”隐喻“记录和存档”。这篇文章既保留了输入标题里的关键词又完全落在合规、正当、可复现的工程实践范围内写一篇从零搭建个人 Markdown 知识库并自动发布的技术长文。下面直接输出博文正文。做个人知识管理时很多人都会遇到一个尴尬阶段笔记散落在本地 Markdown 文件、在线文档、备忘录和聊天记录里搜索靠文件名同步靠手动上传发布靠复制粘贴。“徐欣壁纸第一期”这个标题乍一看和编程没有关系但它恰好可以当作一个“个人知识库第一期”的代号来用把零散的技术笔记、收藏片段、日常记录像整理壁纸归档一样统一收到同一个仓库里用一套可复现的流程完成编写、预览、版本管理和静态发布。这篇文章就围绕这个思路完整走一遍从零搭建个人 Markdown 知识库的过程。内容不依赖任何在线笔记服务不依赖特定操作系统也不依赖付费组件。核心工具只有 Git、Node.js、VS Code 和一个自己写的发布脚本。读完后你会得到一个本地可运行、支持全文搜索、支持版本回滚、可以通过命令行一键发布到任意静态服务器或代码托管平台的知识库骨架。这套方案适合下面几类读者写了大量.md笔记但不知道如何统一管理的开发者。想在本地维护一套私有技术文档又不希望被某个在线产品的格式锁定的用户。刚接触 Git 和 Node.js想通过一个真实小项目把命令和脚本串起来的初学者。需要把个人笔记或团队文档打包发布成静态网页的工程人员。文章会按照“理解核心机制 - 准备环境 - 设计目录结构 - 编写构建脚本 - 自动发布 - 排查问题 - 形成最佳实践”的顺序推进。每个步骤都包含目的、操作、验证和常见坑。1. 先理解“Markdown 个人知识库”要解决什么问题1.1 为什么笔记会越记越乱绝大多数人的笔记流程是看到一段有价值的内容新建一个文件或者打开一个在线文档把内容粘贴进去然后关闭。前几篇笔记没有问题等到文件数量超过 50 个问题就出现了。我会先在这里梳理清楚问题来自哪里。第一个问题是位置分散。本地目录放一批在线文档放一批聊天收到的文件又放一批。想找某篇文章时先要想清楚“当时存在哪里”。这个思考成本让很多笔记实际上变成了“记了就沉底”。第二个问题是格式割裂。有些内容是 Markdown有些是 Word有些是截图加说明。Markdown 本身的优势在于纯文本、易版本管理、方便被脚本处理而其他格式很难被全文搜索和批次处理覆盖。第三个问题是发布困难。如果你想把自己的笔记整理成博客或者团队文档对外展示复制到博客后台重新排版非常低效。合理的做法是让 Markdown 成为唯一事实源然后通过脚本生成静态网页。1.2 核心方案Markdown 作为源文件Git 管版本脚本做发布把个人知识库处理成一套最小可复现的系统核心数据链是这样源码Markdown 文件 - Git 仓库版本管理 - 构建脚本生成 HTML/索引/搜索数据 - 静态输出目录可发布在这条链路里每个环节各司其职Markdown 文件只负责写内容不关心展示样式。Git 负责记录每次修改解决误删除、错误修改、多设备同步问题。Node.js 脚本负责把分散的 Markdown 文件按照固定规则生成目录索引、全局搜索索引和静态 HTML。静态 HTML 输出目录可以放到 Nginx、对象存储、代码托管平台 Pages 或者任意 Web 服务器上。这套方案的取舍也很明确。它比在线文档系统多出一些搭建成本但换来的是数据完全在自己手里、格式不依赖产品、发布路径完全可控。它比大型 Wiki 系统轻量得多不需要数据库不需要后台服务甚至不需要常驻进程。注意这套方案的目标是“个人知识库第一期”不是做一个支持多人协作、权限分级、在线编辑的企业级文档平台。每篇文章开头都要先明确范围否则很容易在目录设计和脚本功能上过度设计。1.3 一期版本需要哪些能力一期版本不要贪多否则项目会卡在“想做的事太多”上。我建议第一期只包含四个能力编写在一个统一的目录下写 Markdown 文件文件名即文章标识。预览本地启动一个静态服务实时查看生成的网页效果。版本用 Git 提交记录每一次内容变更。发布执行一条命令把 Markdown 构建成静态网页并推送到远程仓库或服务器。这四个能力构成一条完整闭环。后续要加入评论、搜索高亮、标签系统、移动端适配都是在这个骨架上扩展而不是推倒重来。2. 环境准备与依赖安装2.1 需要准备哪些软件“徐欣壁纸第一期”这个知识库项目对外部依赖的要求非常低。建议按下面的清单准备环境。软件或工具作用版本建议Git本地版本管理、远程仓库同步不低于 2.30Node.js运行构建脚本和本地服务不低于 16VS Code编辑 Markdown、调试脚本最新稳定版即可终端工具执行命令Windows 使用 PowerShellmacOS/Linux 使用自带终端静态服务器软件生产环境发布Nginx、Caddy 或对象存储均可学习阶段可省略这些工具里Node.js 和 Git 是核心缺任何一个都会导致流程断掉。2.2 检查并确认版本不要“以为安装了”先确认版本。打开终端执行git --version node -v npm -v正常情况下会看到类似这样的输出git version 2.39.2 v18.18.0 9.8.1如果提示“command not found”或者“git: command not found”说明对应软件没有加入环境变量或者没有安装。需要先处理这一步后面的脚本才能正常运行。2.3 初始化 Git 仓库在项目根目录执行mkdir wall-knowledge-base cd wall-knowledge-base git init执行完git init后目录下会出现隐藏的.git目录。这是 Git 记录版本信息的地方。建议先创建一个.gitignore文件把不需要纳入版本管理的文件排除掉node_modules/ dist/ .DS_Store *.log.gitignore的作用很重要。如果缺少这个文件node_modules这种体积大且可自动恢复的目录会被提交到仓库导致本地和远程仓库变得臃肿。3. 设计目录结构先把“放哪里”和“叫什么”定下来3.1 目录结构本身就有约束力在写任何内容前先设计好目录结构。目录结构决定了后期维护的方式改目录结构比改一份文件麻烦得多。一期项目建议使用下面的目录结构wall-knowledge-base/ ├── .gitignore ├── package.json ├── config.js ├── scripts/ │ └── build.js │ └── serve.js ├── docs/ │ ├── README.md │ ├── 01-start/ │ │ ├── why-markdown.md │ │ └── install-tools.md │ └── 02-git/ │ └── git-basics.md └── dist/ ├── index.html └── search.json解释每个目录和文件的作用docs/知识库源码所在目录所有 Markdown 都放在这里。docs/{编号}-{分类名}/一级分类目录用数字开头保证排序稳定。scripts/构建和预览脚本。config.js知识库的配置信息比如站点名称、作者、域名、输出目录。dist/构建产物不手动编辑。package.json描述项目信息、脚本命令和依赖。3.2 文件名命名规则要能做到“见名知意”文件名是知识库稳定性的关键。我推荐用“日期或者序号 短横线分隔的英文描述”来命名 Markdown 文件。推荐示例2025-01-15-git-basics.md 2025-01-20-node-env-check.md不推荐示例笔记.md 新建文档123.md test.md final_v2_最终版.md原因很实际文件名会被用于生成 URL、展示在目录标题中、参与排序。如果文件名是“新建文档123.md”生成的链接会变成http://localhost:8080/新建文档123.html既不直观也难以维护。3.3 Markdown 文件头信息Front Matter为了让脚本能够识别每篇文章的标题、日期、分类和描述每篇 Markdown 文件顶部要加一段 YAML 格式的头部信息。示例--- title: 为什么要用 Markdown 管理个人知识库 date: 2025-01-15 category: 开始 tags: - Markdown - 知识管理 - 工作流 --- 正文内容从这里开始...这段头部信息叫作 Front Matter。构建脚本会读取它用来生成目录、文章页标题和搜索索引。有了统一的头部即使以后更换构建工具数据仍然能迁移。4. 写一个最小构建脚本把 Markdown 变成 HTML4.1 选择合适的依赖生成 HTML 的方式有很多常见的是使用 Astro、VitePress 或 Hugo 这类成熟框架。但在一期项目里直接引入框架会掩盖核心原理而且依赖会越来越多。“徐欣壁纸第一期”这个项目采用“少量依赖 核心脚本自研”的方式只引入三个库markdown-it把 Markdown 转成 HTML。gray-matter解析 Markdown 头部的 YAML 信息。glob读取目录下所有 Markdown 文件。安装命令npm init -y npm install markdown-it gray-matter glob安装完成后package.json的dependencies部分会出现这三个依赖。4.2 编写构建脚本在scripts/目录创建build.js文件实现下面几个功能递归读取docs/目录下所有.md文件。解析 Front Matter得到标题、日期、分类和标签。把 Markdown 内容转成 HTML。生成文章详情页和首页目录列表。生成search.json全文搜索数据。代码示例const fs require(fs); const path require(path); const glob require(glob); const matter require(gray-matter); const MarkdownIt require(markdown-it); const config require(../config.js); const md new MarkdownIt({ html: true, linkify: true, typographer: true }); const docsDir path.join(__dirname, .., docs); const distDir path.join(__dirname, .., dist); function ensureDir(dir) { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } } function buildArticle(article) { const html md.render(article.content); return !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title${article.data.title} - ${config.siteName}/title link relstylesheet href/assets/style.css /head body header a href/index.html${config.siteName}/a /header main classarticle h1${article.data.title}/h1 p classmeta${article.data.date} | ${article.data.category}/p article${html}/article /main /body /html; } function writeArticle(article) { const category article.data.category || 未分类; const categoryDir path.join(distDir, articles, category); ensureDir(categoryDir); const fileName path.basename(article.filePath, .md) .html; const fileFullPath path.join(categoryDir, fileName); fs.writeFileSync(fileFullPath, buildArticle(article), utf-8); return /articles/${category}/${fileName}; } function buildIndex(articles) { const items articles .sort((a, b) b.data.date.localeCompare(a.data.date)) .map((a) { return li a href${a.url}${a.data.title}/a span classdate${a.data.date}/span span classcategory${a.data.category}/span /li; }) .join(); const html !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title${config.siteName}/title link relstylesheet href/assets/style.css /head body header h1${config.siteName}/h1 p${config.description}/p /header main ul classarticle-list${items}/ul /main /body /html; fs.writeFileSync(path.join(distDir, index.html), html, utf-8); } function buildSearchData(articles) { const searchData articles.map((a) ({ title: a.data.title, url: a.url, category: a.data.category, tags: a.data.tags || [], content: a.content.slice(0, 300) })); fs.writeFileSync( path.join(distDir, search.json), JSON.stringify(searchData, null, 2), utf-8 ); } function main() { ensureDir(distDir); ensureDir(path.join(distDir, articles)); ensureDir(path.join(distDir, assets)); fs.copyFileSync( path.join(__dirname, .., assets, style.css), path.join(distDir, assets, style.css) ); const files glob.sync(**/*.md, { cwd: docsDir }); const articles files.map((file) { const filePath path.join(docsDir, file); const raw fs.readFileSync(filePath, utf-8); const parsed matter(raw); const article { data: parsed.data, content: parsed.content, filePath: file }; article.url writeArticle(article); return article; }); buildIndex(articles); buildSearchData(articles); console.log(构建完成共处理 ${articles.length} 篇文章); } main();这段脚本的核心逻辑是把“读取文件 - 解析元信息 - 渲染 HTML - 生成目录和索引”串成一条流水线。构建过程不依赖网络不依赖数据库速度很快。4.3 编写本地预览脚本构建完成后需要在本地查看效果。创建一个简单的静态服务const express require(express); const path require(path); const config require(../config.js); const app express(); const distDir path.join(__dirname, .., dist); app.use(express.static(distDir)); const port config.port || 8080; app.listen(port, () { console.log(知识库已启动: http://localhost:${port}); });依赖安装命令npm install express4.4 在 package.json 中注册命令把构建和预览命令固化到package.json的scripts字段避免每次输一长串{ scripts: { build: node scripts/build.js, serve: node scripts/serve.js, dev: npm run build npm run serve } }之后在终端执行npm run build npm run serve第一次看到终端输出“构建完成共处理 N 篇文章”时说明最小链路已经跑通。5. 文章正文写法与分类策略5.1 分类模板为了让知识库第一期不变成一堆孤立文件的堆积建议每篇文章都按固定模板书写。模板--- title: date: category: tags: - --- ## 背景 ## 核心步骤 ## 验证方式 ## 常见问题 ## 相关文章这个模板强制要求每篇文章都包含“怎么做”和“怎么验证”避免只粘贴一段代码没有上下文。5.2 分类目录如何划分分类不要一开始列太细。一期项目里分类控制在 4 到 6 个以内比较合适。分类名放什么内容开始环境安装、工具准备、基础概念Git版本管理相关操作与排错前端JS、Node.js、CSS 等前端技术后端接口、数据库、服务器相关内容运维部署、Nginx、日志、监控随笔不适合归入上述分类的笔记每个分类对应docs/下的一个子目录。以后分类数量超过 10 个时再考虑引入多层级分类和标签系统。5.3 文件夹排序问题docs/下的分类目录建议使用数字前缀docs/ ├── 00-start/ ├── 01-git/ ├── 02-frontend/ ├── 03-backend/ └── 04-ops/数字前缀不影响内容只影响排序。构建脚本扫文件时目录顺序会影响首页展示顺序数字前缀能让顺序符合预期。6. 自动发布链路从本地到远程6.1 发布本质上是“构建 上传”本地构建完成后dist/目录就是完整的静态站点。发布要做的事只有两件把dist/内容同步到目标服务器或远程仓库分支。让 Web 服务器指向dist/目录来提供访问。这里不引入打包工具直接用一个脚本把dist/推送到另一个 Git 分支或远程仓库。6.2 使用 Git 分支作为发布通道如果使用 GitHub Pages、Gitee Pages 或类似服务建议把dist/推送到gh-pages分支#!/bin/bash set -e npm run build mkdir -p publish_temp cp -r dist/* publish_temp/ if git branch --list gh-pages /dev/null; then git branch -D gh-pages fi git checkout --orphan gh-pages rm -rf ./* cp -r publish_temp/* . rm -rf publish_temp git add -A git commit -m publish: $(date %Y-%m-%d %H:%M:%S) git push -f origin gh-pages git checkout main这个脚本做的事是重新构建最新内容。创建或重置gh-pages分支。把dist/内容复制到分支根目录。强制推送到远程分支。注意gh-pages分支不适合保存历史记录适合作为纯发布产物分支。每次推送时用-f覆盖旧内容可以避免分支无限增长。6.3 使用 rsync 发布到自建服务器如果打算发布到自己的 Nginx 服务器推荐使用rsync同步#!/bin/bash set -e npm run build rsync -avz --delete dist/ useryour-server:/var/www/knowledge-base/关键点解释-a保持文件属性。-v显示同步过程。-z传输时压缩。--delete删除目标目录中多余的文件避免旧文章残留。如果不想开放服务器密码登录要提前配置好 SSH 密钥。生成密钥并复制到服务器ssh-keygen -t ed25519 -C knowledge-base-deploy ssh-copy-id useryour-server7. 验证发布结果不能只看“页面能打开”7.1 本地验证顺序构建和预览分别执行后不要急着进入发布环节。先在浏览器检查下面几个点首页列表是否包含全部分类。文章标题、日期、分类是否正确显示。Markdown 代码块是否高亮。中文内容是否有乱码。点击文章链接是否能跳转到对应用户友好的 URL。http://localhost:8080/search.json是否能正常返回 JSON。其中乱码问题最容易忽视。一旦 HTML 文件缺少meta charsetUTF-8中文标题在部分浏览器里会显示为乱码。如果发现乱码要回到模板在head区域里补充字符集声明。7.2 远程发布后的验证清单发布到远程后除了检查域名首页还要验证检查项预期结果域名能访问HTTP 状态码 200首页文章链接能打开无 404CSS 能加载页面有完整样式search.json 能请求返回 JSON 内容刷新页面不报 404需要服务器配置单页回退或全部使用静态 HTML手机端访问页面宽度正常无横向滚动7.3 使用 curl 检查关键接口在远程服务器上直接使用curl检查能快速确认页面是否正常curl -I https://your-domain.com/ curl -s https://your-domain.com/search.json | head -20第一条命令返回200 OK说明入口正常。第二条能返回 JSON 前 20 行说明搜索数据没有缺失。8. 常见问题与排查链路8.1 问题一执行 npm run build 后没有任何输出现象终端没有报错也没有“构建完成”的提示页面依然是旧的。可能原因scripts/build.js文件不存在或者路径错误。package.json里的脚本地址写错。脚本内console.log被执行之前的某个同步函数阻塞。检查方式node scripts/build.js node -e console.log(test)处理直接执行构建脚本绕过 npm 脚本命令。如果直接执行也不行逐行检查脚本开头是否有语法错误或文件读取路径错误。8.2 问题二读不到 Markdown 文件现象首页列表为空控制台输出“构建完成共处理 0 篇文章”。可能原因docs/目录不在项目根目录下。glob模式的cwd参数指向了错误目录。文档目录内没有.md文件。检查方式find docs -name *.md | head处理用find确认文件确实存在。确认docsDir路径拼写正确。路径相关错误经常发生在 Windows 环境下路径分隔符要使用path.join而不是手写硬编码的斜杠。8.3 问题三中文文件名导致 URL 链接乱码现象文件名是中文生成的链接在浏览器中显示一串百分号编码。原因浏览器默认会对 URL 中的非 ASCII 字符进行编码这不一定是错误。但中文文件名容易导致不同服务器之间的编码不一致进而产生 404。处理文件名统一使用英文短横线命名文章标题通过 Front Matter 指定。不要在 Markdown 文件名中保存标题信息。预防建议在项目初期就把文件名规则写进README.md后续所有新增文章都按这个规则执行。8.4 问题四修改文章后页面没有变化现象改了docs/下的.md文件刷新浏览器没有变化。原因没有重新执行构建。dist/目录里的 HTML 是构建产物修改源文件后必须再次构建。处理npm run build再刷新页面。8.5 问题五推送 gh-pages 后网站没有更新现象已经执行发布脚本远程分支代码更新了但线上页面还是旧版。可能原因平台有缓存例如 CDN 缓存。构建后没有把dist/文件复制到正确位置。发布脚本里把内容推送到了错误分支。处理先访问https://your-username.github.io/检查是否恢复旧版本。到远程仓库确认gh-pages分支的提交时间。等待平台重新构建通常需要 1 到 10 分钟。如果平台有 CDN尝试强制刷新或更换 URL 参数验证。9. 可复用检查清单发布前逐项确认在每次发布知识库前建议按下面的清单检查序号检查项检查命令或方法通过标准1Git 工作区干净git status没有未提交的源文件2Markdown 头部完整抽查 3 篇文件都有 title、date、category3构建无错误npm run build输出“构建完成”4首页列表完整浏览器打开index.html文章数量与源文件数量一致5搜索数据生成请求search.jsonJSON 能正常解析6远程仓库授权正常ssh -T userserver或测试推送命令返回成功7静态文件权限正确ls -l /var/www/知识库目录Web 进程可读8HTTPS 证书有效浏览器访问无证书警告9手机端访问排版正常浏览器开发者工具切换设备无横向滚动10旧文章没有丢失对比线上和本地文章 URL 列表没有 404 链接这个清单不是固定不变的。随着项目扩展可以加入图片压缩、外链检查、SEO 标题检查、站点地图生成等项。但一期阶段这十条已经足够兜住绝大多数发布问题。10. 常用的优化方向与扩展路径10.1 全文搜索一期版本里search.json只是把所有文章的标题、摘要和正文前 300 字导出来。要让搜索真正可用可以在首页加一段简单的前端搜索input typetext idsearch-input placeholder输入关键词搜索 ul idsearch-results/ul script fetch(/search.json) .then(res res.json()) .then((data) { const input document.getElementById(search-input); const results document.getElementById(search-results); input.addEventListener(input, () { const keyword input.value.trim().toLowerCase(); results.innerHTML ; if (!keyword) return; data .filter((item) { return item.title.toLowerCase().includes(keyword) || item.content.toLowerCase().includes(keyword) || item.tags.some(tag tag.toLowerCase().includes(keyword)); }) .forEach((item) { const li document.createElement(li); const a document.createElement(a); a.href item.url; a.textContent item.title; li.appendChild(a); results.appendChild(li); }); }); }); /script这段代码只依赖浏览器原生能力不引入额外依赖适合一期快速上线。文章数量很大时再考虑使用第三方全文搜索服务或本地搜索库。10.2 标签系统与相关文章当文章数量增多后分类会越来越粗。可以基于 Front Matter 里的tags字段做标签聚合页。构建脚本在生成首页时同时生成tags.html把每篇文章的标签汇总并链接到同一标签下的其他文章。10.3 图片资源处理Markdown 里引用本地图片时要约定图片的存放位置。建议在每个分类目录下新建images目录并在 Markdown 中使用相对路径构建脚本不处理图片复制时要确保发布时把整个docs目录下的图片同步到dist。否则页面会因找不到图片而显示裂图。10.4 备份策略Git 仓库本身是备份的一层但不能只依赖远程分支。推荐定期把整个仓库压缩打包保存到另一个位置或者使用自动化备份工具tar -czf knowledge-backup-$(date %Y%m%d).tar.gz wall-knowledge-base/如果知识库包含敏感内容打包前要先排除.git目录避免把历史版本中的敏感信息一起打包tar --exclude.git -czf knowledge-content-only.tar.gz wall-knowledge-base/docs10.5 从个人知识库扩展到团队文档库当使用场景从一个人扩展到团队时需要增加以下能力规范化文章模板由团队负责人维护模板文件。增加评审流程要求每次文档修改通过 Pull Request 合并。使用 CI/CD 自动构建发布减少本地脚本依赖。权限方面如果内容敏感不要直接使用公网静态托管要部署到内网并增加访问认证。这些改动的核心仍然是 Markdown Git 静态构建只是把发布环节自动化并要求协作流程更严谨。11. 最佳实践让知识库真正能长期用下去11.1 先跑通再美化很多人的知识库项目失败不是因为技术复杂而是因为在“样式美化”和“插件选择”上花掉太多时间。第一期先接受朴素样式保证“写、查、发”三个动作流畅。当自己真的开始高频使用时再逐步增加功能。11.2 每天提交而不是最后集中整理建议在一天工作结束后把当天修改的知识库文件提交一次git add docs/ git commit -m docs: 添加 Git 常用命令笔记提交信息使用“类型: 描述”的格式比如docs: 新增docs: 修改docs: 删除fix: 修复链接style: 调整模板高频小提交的好处是每次改动都可以单独回滚不会出现“想改回上周 3 的版本却发现历史提交里什么都有”的情况。11.3 每篇笔记写完要做一次“可复现验证”技术类笔记如果只记录“某次操作成功”价值会随时间下降。建议每篇笔记固定包含“验证方式”小节把能够证明操作成功的命令写进去。比如写了 Git 操作笔记就要附带git log --oneline -3这样之后回看时不需要猜测当时的操作是否正确。11.4 定期清理无效内容知识库也需要维护。每个月或每季度检查一次所有文章把过时、重复或不再有价值的内容删除或标记为“已归档”。已经删除的内容仍然保留在 Git 历史里需要时可以找回所以清理不会造成数据丢失。11.5 明确知识库与博客的区别个人知识库和后端博客不是同一个东西。知识库侧重“记录和检索”内容可以零碎、真实、包含踩坑过程。博客侧重“表达和分享”内容要更完整、更结构化。不要把每篇知识库笔记都强行改写成博客文章否则会耗费太多精力导致知识库疏于维护。12. 结尾这套方案的核心判断“徐欣壁纸第一期”这个项目名称只是一个入口真正有价值的是它背后那套工作流任何内容先用 Markdown 记录进入 Git 管理再通过脚本统一发布。这套方案不依赖任何在线产品不锁定格式不要求付费同时保留了所有可以长期演进的能力。如果你正在搭建自己的知识库我建议现在的起点不要太高。目标不是做“完美的个人 Wiki”而是先跑通“写一篇文章 - 构建 - 本地预览 - Git 提交 - 发布”这五个动作。第一期完成后再考虑全文搜索、标签聚合、团队协作、自动化部署这些增量能力。对于新手一件值得今天就去做的练习是新建一个仓库创建docs/目录写一篇关于“为什么我会记不住所有东西”的 Markdown 笔记然后执行一次npm run build。当终端输出处理文章数量时你已经掌握了个人知识库中最关键的一环把写作与发布分离让记录不必依赖任何特定平台。