首页 / 资讯中心 / 文章详情

Caveman极简实践:用单文件HTML构建个人网站

Caveman极简实践:用单文件HTML构建个人网站 ★ FEATURED ARTICLE
今天想认真聊一聊 caveman 这个项目。它不是什么惊天动地的开源框架也不是某个新冒出来的AI工具更不是只有技术极客才能看懂的高深概念——恰恰相反caveman 是我给自己的一套极简实践起的代号。穴居人原始简陋返璞归真。有一次我折腾个人网站本来计划上框架、上数据库、上打包工具做到一半突然觉得不对劲我不过是想发几十篇文字为什么要养一堆依赖最后我把整个项目砍成一个单文件 HTML竟然比原先那个“完整方案”更顺手。之后我把这套思路搬到了笔记、文档和日常任务里发现很多看似复杂的事情最笨的办法反而是最快的。这篇就是那次实践的全部记录包括操作步骤、踩过的坑以及后来一步步总结出的避坑清单。如果你正被各种工具、框架、平台折腾得头大或者只是想做一个能稳定运行很多年的小网站这篇文章应该能帮上忙。你能看到单文件 HTML 怎么做出一个真正能用的个人网站怎么把它发布到公网遇到乱码、缓存、手机适配这类问题时怎么快速排查以及这套“返璞归真”的工作方法怎么扩展到日常任务里。没有编程基础的人照着抄也能完成有经验的人则可以当一份避坑清单来看。1. Caveman 是什么一个代号背后的极简主义1.1 为什么叫“穴居人”起这个名字不是一时兴起。穴居人给人的第一印象是原始、工具少、日子过得糙但换个角度看他们恰恰是“用最少资源解决生存问题”的高手。现代数字生活则相反工具多到人成了工具的附属品写一篇文章要先想用哪个编辑器做个页面要先想用哪套框架存个笔记要先想数据放在哪个平台。工具越来越多产出却越来越难。caveman 这个代号就是想提醒我真正重要的从来不是工具的多少而是你用手头那点东西能做出什么。一台电脑、一个编辑器、一个浏览器在很多场景下已经足够。别急着往项目里加东西先问自己一句“不加这些是不是也做得到”1.2 Caveman 要对抗的真正问题我们要对抗的不是框架本身而是“不必要的复杂度”。我自己就干过这种蠢事想写个十几篇文章的博客结果先搭了个脚手架装了打包器接好了数据库还要处理编译报错。等到真正坐下来写文章时我已经被环境配置磨掉了一半热情。做个对比你就有感觉了传统方案Caveman 方案Node.js 框架 打包工具 数据库单文件 HTML 静态托管每次更新内容都要跑一遍构建流程改动文字直接覆盖文件换台电脑先装一堆环境才能开工任意浏览器打开就能看依赖几十个第三方库随时可能有安全公告零依赖没有攻击面一个版本升级可能牵连整个项目文件和它自己自成一体这不是说传统方案一无是处而是说很多场景根本不值得付出这些成本。caveman 的立项逻辑就一句话先判断这件事是不是“杀鸡用牛刀”如果是赶紧收手换最笨的方式做。1.3 Caveman 的边界在哪里也得说清楚caveman 不是万能的。需要用户登录、需要实时多人协作、需要处理大量结构化数据的产品不该硬塞进一个单文件里。这是工具选择问题不是立场问题。我的做法是每接到一件事先分个类它本质上是“展示内容”还是“处理交互”前者非常适合 caveman 思路后者还是老老实实选成熟方案。这种边界意识反而让 caveman 这个极简方案变得可靠。知道自己能做什么、不能做什么才不会翻车。2. Caveman 核心方案如何用单文件 HTML 做一个能用的网站2.1 为什么单文件可行早期我会觉得一个网站至少要有个服务器、一套后台后来才意识到对内容型页面来说浏览器就是最好的运行时。一个 html 文档就能承载文字、图片、样式和交互逻辑现代 CSS 已经把排版布局全包了原生 JavaScript 也足够处理绝大多数轻交互。你把文件保存在本地双击就能浏览上传到任意静态托管全世界就都能访问。我常打一个比方国宴确实需要一整套专业厨房但平时一个人做饭一把好刀加一口锅就够了。caveman 单页网站就是那把刀和那口锅。它丢掉的东西是过去为了应付极端复杂场景而准备的装备它留下的东西恰恰是内容最需要的安全、轻量和可复制。之后的实践证明一个展示性质的小站用这种方式维护远比想象中省事。2.2 从零写一个最小的 Caveman 单页直接上代码。这就是一个可用的 caveman 单页完整代码不需要安装任何东西新建一个index.html把内容粘进去浏览器打开就能跑!DOCTYPE html html langzh-CN head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 titleCaveman 单页示例/title style :root { --bg-color: #f7f7f5; --text-color: #222222; } body { font-family: system-ui, -apple-system, PingFang SC, Microsoft YaHei, sans-serif; max-width: 42em; margin: 4rem auto; padding: 0 1.2rem; background: var(--bg-color); color: var(--text-color); line-height: 1.8; } a { color: #b45309; } pre { background: #f0efe9; padding: 1rem; overflow-x: auto; } media (max-width: 600px) { body { margin: 2rem auto; } } /style /head body h1你好我是 Caveman/h1 p这是一整份网页的全部代码样式、内容、脚本都在同一个文件里。/p article idcontent h2写点什么/h2 p以后要改文字直接改这里。/p /article button idtoggle展开/收起/button div idextra hidden这里是原生 JavaScript 控制的交互区域。/div script document.getElementById(toggle).addEventListener(click, function () { var extra document.getElementById(extra); extra.hidden !extra.hidden; }); /script /body /html每一行都值得解释一下。langzh-CN告诉浏览器页面是简体中文对读屏软件和搜索引擎都更友好meta charsetutf-8防止中文变成乱码必须放在 head 靠前位置viewport是手机端适配的关键少了它手机上看页面字会小成一团。样式部分我用了一个 CSS 变量--bg-color和--text-color之后想换成暗色主题只需要改这两个值不用全局找颜色。字体栈从系统字体开始往后逐个降级这种写法能保证在不同设备上都有不错的观感。max-width: 42em限制行宽阅读长文时眼睛不容易疲劳。交互部分我没有引任何库一个原生事件绑定就够用。hidden属性在 HTML 里本来就存在配合 JavaScript 改一下它的值收起展开就完成了。这种效果放在大多数博客上都够用。2.3 把内容当一等公民如何把单页扩展成博客单文件直接当博客用完全可以。我的做法是让一个文件对应一篇文章文件名就当标题再维护一个最简单的索引页罗列文章链接本质上是静态网站最初的样子。如果觉得每篇文章都复制一整份公共头尾太麻烦也别急着上框架。写一个十几行的本地脚本做字符串替换就能完成模板拼接。比如建一个template.html里面留好!-- TITLE --和!-- CONTENT --占位符然后用一段脚本把文章正文填进去输出成品页面。这种“半自动”方式既没有引入外界依赖又剩下不少手工活。还有一个 Caveman 思路的变体正文用 Markdown 写日常编辑和阅读体验都不错发布之前用一个命令把 Markdown 渲染成一个独立 HTML 文件。这里不要求编辑器实时预览因为绝大多数时候你只需要做好一件事——把内容写出来。如果只有一篇文章连脚本都省了。复制模板改掉标题和正文保存上传完事。这套流程的最大特点是你可以完全掌控自己的内容没有平台锁也没有格式绑定的风险。2.4 加一点视觉体验但不要过度设计很多人一提到做页面脑子里就冒出各种动效、渐变色、粒子背景。我劝你缓一缓。caveman 不等于丑它只是把视觉优先级放得靠后。先把内容排清楚确保任何人都能顺畅读下来再考虑主题配色。CSS 变量很适合做这件事。你可以在:root里定义一套浅色默认值然后写一套深色变量覆盖方案:root { --bg-color: #f7f7f5; --text-color: #222222; } media (prefers-color-scheme: dark) { :root { --bg-color: #1a1a1a; --text-color: #f0efe9; } }prefers-color-scheme是 CSS 里非常实用的特性系统开了深色模式页面就自动切换完全不用 JavaScript 参与。字体、标题、链接、代码块这几个元素的样式定好之后整站基本就成型了。不要为了丰富视觉而加无关元素空白和克制本身就是设计。3. 从单文件到上线Caveman 的完整发布流程3.1 上线前做一次“单手测试”页面写完先别急着发布我最常提醒别人的一句话是先把自己当“完全不懂技术的人”测一遍。双击打开本地文件如果这一步就是打不开、乱码或者布局稀烂那后面多少优化都白搭。我列了一个简单的发布前检查清单每次上线前都照着过一遍检查项说明中文内容无乱码文件编码统一为 UTF-8手机布局缩小浏览器窗口或直接用手机浏览没有横向滚动条标签闭合所有 div、article、section 都有结束标签图片体积图片已经压缩不需要加载几 MB 的“原图”链接有效性页面里每个链接都点一遍确认没有 404主题适配浅色、深色模式都看一眼文字可读脚本报错浏览器控制台没有红色报错这一套检查做完不超过十分钟却能避免大量“上线后被人指出问题”的尴尬。特别是移动端适配很多人开发时只在电脑浏览器里看发布后才发现手机上字号、间距全都怪怪的。其实只需要打开开发者工具切换到手机尺寸预览几秒钟就能解决大半问题。3.2 发布到公网最接地气的三种方式文件准备好了接下来是怎么让别人也能访问。不需要浮夸的方案静态文件放在哪都行。第一种你有服务器的话直接把index.html放到站点目录下再配一段最简单的 Nginx 配置server { listen 80; server_name yourdomain.example; root /var/www/caveman; index index.html; }保存配置文件执行nginx -t检查语法然后nginx -s reload重载页面就能访问了。root指向的是文件所在目录index指明默认首页是index.html。如果服务器上有安全组或防火墙记得放行 80 端口不然别人访问时会有奇奇怪怪的超时。第二种没有服务器用对象存储的静态网站托管。流程都差不多建一个公开读的桶开启“静态网站托管”功能把index.html传上去再绑定自己的域名。这种方式的好处是无需关心服务器运维访问量大了也能自动扛住。第三种如果你日常会用 GitHub 或同类代码托管平台那上面的 Pages 功能也能直接托管静态文件。把index.html一推平台自动生成访问地址。这个方式适合文件已经放在代码仓库里的情况很方便做版本管理。无论用哪种方式发布这件事不应该成为负担。caveman 强调的就是从“写完”到“上线”距离越短越好。3.3 上线后的最小维护工作静态单页的维护本质上就是“更新文件”。今天想在首页加一篇文章两个方式任选如果文件在服务器上直接 ssh 进去改文本如果在对象存储或代码托管平台上下载、改好、传回或者直接在线编辑器里改。这里我有一个从实践中养成的习惯每次改版前先把旧文件复制一份文件名带日期比如index-20250425.html。这样做的好处很直接——哪天改坏了大不了把这个旧版本恢复回来。不要依赖“我我记得原来是什么样”版本备份是性价比最高的保险。“维护”听上去像是个苦差事但对于 caveman 单页来说它真的只是改文字而已。没有依赖升级的连环炸弹没有框架停更的焦虑页面文件自己就构成一个完整世界。哪怕三年后再打开内容和当初一模一样。4. Caveman 实践中常见的坑与排查方法4.1 中文乱码问题这是新手最容易遇到的坑也是最容易解决的一个。页面里如果没有meta charsetutf-8浏览器可能会按系统默认编码去猜中文就变成了一堆乱码。另一个隐蔽原因是文件本身存成了 GBK虽然页面声明了 UTF-8两者对不上照样乱。解决办法很简单编辑器保存文件时统一选择“UTF-8 无 BOM”编码HTML 里把 charset 声明放在 head 最前面假如服务器返回的响应头也带 charset尽量保持和文件一致。遇到乱码时先看这两处九成问题能解决。4.2 改了内容浏览器里却不显示这种是缓存搞的鬼而且几乎人人都会遇到。第一次访问页面浏览器把 CSS 和页面内容缓存了你再更新文件重新打开浏览器觉得本地缓存还“新鲜”就直接拿缓存展示改动自然看不到。经验做法是本地调试时按 CtrlShiftR 强制刷新正式发布时给资源链接加上版本号比如style?v20250425。不要小看这个动作它能让你处理线上问题时省下一大笔反复确认的时间。link relstylesheet hrefstyle.css?v20250425文件每次更新把版本号改一下浏览器就会当成新资源去加载。文件引用得少时这一招尤其好使。4.3 手机端打开布局一团糟相当一部分原因是少了viewport这个 meta 标签。没有它手机浏览器默认把页面按桌面宽度渲染用户看到的是一堆挤在一起的小字。加上meta nameviewport contentwidthdevice-width, initial-scale1页面就会按设备宽度缩放。布局上也有讲究。我建议所有宽度限制都用max-width而不是固定的px文字大小用rem而不是px图片给max-width: 100%。这样各种屏幕尺寸下都能自然缩放不用写一堆媒体查询去过适配。4.4 点了按钮没反应交互失灵原生 JavaScript 交互出问题先打开浏览器控制台看有没有红色报错。常见原因大概三个脚本写在元素前面结果绑定事件时元素还不存在某个 id 重复定义了getElementById找到了多个或找不到变量名拼写错误。最简单可靠的方案是把script标签放在 body 末尾确保脚本运行时页面里的元素都已经解析完。如果用了多个函数多加点console.log打印一段段缩小问题范围。caveman 方案里脚本量通常很小这个级别的排查就够用了。4.5 页面加载缓慢图片拖后腿单文件页面理论上加载非常快慢一般慢在图片和外部资源上。很多人直接把手机拍的照片传到页面里一张原图几 MB再快的网络也扛不住。个人站点上的图片全部压缩处理一下是最好习惯。还有一个常见问题用了外部字体库或在线图标库每次访问都要跨站请求如果对方服务不稳定又慢又影响可靠性。caveman 更推荐用系统自带字体或者把字体文件下载下来随页面一起发布。少依赖几个外部域名加载速度立竿见影。最后放一张速查表方便你日后对照现象常见原因快速解决中文乱码没有声明 charset 或文件编码不对统一 UTF-8声明放 head 最前改动后页面不变浏览器缓存强制刷新给资源加版本号手机端错位缺 viewport 标签加相应 meta用相对单位点击没反应脚本顺序、id 冲突、报错把 script 放尾部看 Console加载慢大图、外部字体依赖压缩图片资源本地化5. Caveman 工作法在日常生活里的扩展5.1 写文章先用纯文本现在很多人写东西第一步是打开编辑器选模板调字体配主题色折腾半小时一个字没写。我换到 caveman 思路后所有长文章一律先用纯文本或 Markdown 写排版、配图、格式统统留给最后处理。这样做的好处一是内容不会被任何平台绑架随时能导出去换地方二是写作时注意力集中在文字本身而不是页面长什么样。一篇三千字的文章如果一开始就在复杂编辑器里写光是滚动、拖动组件就能消耗大量精力。5.2 做个一次性小工具别急着做成“产品”技术领域也有 Caveman 时刻。我经常需要处理一些临时任务比如把散落在几个文档里的记录汇总成一张表或者批量重命名一批文件。以前我会想要不要做个界面要不要做成可配置工具后来发现用脚本直接跑一遍才是对的。拿按周汇总记录来说写一个几十行的小脚本一次运行拿到结果用完就删。它不需要界面不需要建配置文件更不需要做成线上服务。这种“一次性的极简工具”反而比精心打磨的完整系统更实用因为你不需要花时间为永远不会再用的功能付出维护成本。5.3 计划和备忘回归纸笔这个建议听起来有点反科技但我自己测试下来确实有效。头脑风暴、排版本周计划、记录临时灵感时纸和笔比任何笔记软件都快。它没有弹窗不会抖动没有通知打扰纯粹到只有“记下来”这一个动作。等过了几天再把其中真正有价值的条目录入到电子文档里。这时候你会发现八成内容不值得归档剩下两成才是真正要做的事。先粗糙地记录再刻意地筛选这本身就是一种 Caveman 式的工作流。5.4 怎么判断一件事需不需要复杂方案我后来总结出四个问题遇到任何任务都会先问一遍这件事的核心交付物到底是什么用户或读者真正需要的功能有几项三个月后还在用吗如果只用手头最简单的工具缺的是哪一块答案越清楚方案选型就越果断。更多时候你会发现所谓缺的那一块根本不存在你只是被“做得更完整”的惯性推着走。caveman 不拒绝复杂工具但它坚持一点复杂必须是被真实需求逼出来的而不是主动塞进去的。我自己在这套方法上最深的感受是做减法比做加法更考验判断力。每次往项目里加东西之前先想想能不能不加每次觉得“以后可能会用上”时先想想“现在是不是必须”。这样一个一个文件攒下来我手里的工具越来越少功能却越来越顺手。捎带说一句给单页文件的 CSS 和 JS 加?v20250425这种版本号习惯是我建议你第一天就养成的——线上缓存的问题几乎人人都要踩提前防住能省一堆事。按日期备份文件名这件事也一样看上去笨实际救过我好几次场。如果你最近也被各种复杂方案折腾得够呛不妨给自己也立一个 caveman 词条试试看哪些依赖是真正需要的哪些只是习惯使然。
阅读完成 · 觉得有帮助?
咨询建站