2.3 模板与框架:选一个顺手的静态生成器
创业页活过第一个月就开始变异:老板要加博客,运营要加活动落地页,产品要加帮助文档。每加一页,我就复制一份 index.html,把 header、footer 改一遍,再逐一替换导航链接。第三周新增“关于我们”时,我指着屏幕里 7 个长得差不多的 html 文件跟同事说:该上模板了。本节记我们给 Vue 静态站选型多页方案的过程,以及最后落到 VitePress 的配置实录。
2.3.1 需求清单:让复制粘贴消失
先把要解决的问题写清楚,选型才不跑偏:
- 多页共用 header 与 footer,改一处全站生效;
- 内容页用 Markdown 写(博客、文档),交互页保留 Vue 组件;
- 构建产物纯静态,能直接推上 网站托管;
- 学习成本低,团队两人都能改。
2.3.2 四个方案对比
Node 生态的静态生成器不少,我们认真比较了四个:
| 方案 | 技术栈 | 学习成本 | 客户端 JS | 适用场景 |
|---|---|---|---|---|
| VitePress | Vue 加 Vite | 低,会 Vue 即会 | 极少 | 站点与文档混合 |
| Eleventy | 纯 Node | 低,模板语法多 | 零 | 博客与内容站 |
| Nuxt SSG | Vue 全栈 | 中,概念较多 | 按需 | 需要动态能力的站 |
| Hexo | Node | 中,吃主题生态 | 看主题 | 传统博客 |
最后选 VitePress:团队本来就用 Vue,Markdown 里能直接嵌 Vue 组件,交互页(创业页主体)与内容页(博客)可以在同一套体系里共生。如果纯粹只做内容站,Eleventy 更轻。选型不是选最好,是选最顺——这个决策记在 docs/decisions 里,新人来了先看这个文件比问人快。把架构决策写下来这个习惯,在 腾讯云实践案例集 里也反复被强调。
2.3.3 目录与最小配置
VitePress 的目录约定即文档目录,非常简洁:
cloud-pages-node/
├─ .vitepress/
│ ├─ config.ts # 站点配置与主题
│ └─ theme/ # 自定义主题覆盖
├─ index.md # 首页
├─ product/ # 产品页(每页一个 .md)
├─ blog/ # 博客目录
├─ public/ # 原样资源
└─ package.json
config.ts 最小配置:
import { defineConfig } from "vitepress";
export default defineConfig({
title: "云页创业",
description: "一个 Vue 静态创业页",
base: "/",
cleanUrls: true,
build: { outDir: "../dist" },
themeConfig: {
nav: [
{ text: "产品", link: "/product/" },
{ text: "博客", link: "/blog/" },
],
},
});
base 要和部署路径一致:放在 网站托管根目录 就是 /,放子路径则填对应子路径。cleanUrls 去掉 .html 后缀,对 SEO 友好。outDir 指向 2.2 定义好的 dist,构建产物和其他脚本天然接轨。
2.3.4 模板复用:三招覆盖九成页面
第一招,默认主题的导航与侧边栏配置,在 config.ts 里写一次,全站所有页面自动渲染 header。
第二招,自定义组件。把创业页的交互模块封成 Vue 组件,在 md 里以插件方式引入使用:
<script setup>
import HeroBanner from "./components/HeroBanner.vue";
</script>
<HeroBanner title="一键上云" />
第三招,全局组件注册。在自定义主题入口里 app.component 注册一次,全站 md 直接写组件名即可。改 header 从此只改一个文件,7 个 html 的复制粘贴彻底成为历史。
2.3.5 数据驱动:构建时拼页面
博客列表不写死。2.2 的构建脚本在 bundle 之前先扫描 blog/ 目录生成文章索引 JSON,VitePress 构建时把它注入数据层。产物仍是纯静态,部署到 腾讯云网站托管 后与普通 dist 没有任何区别,该享有的 CDN 加速与 SSL 能力一样不少。
2.3.6 页面元信息:frontmatter 与 SEO
每篇 md 头部用 frontmatter 声明标题、描述与发布日期,构建时注入模板的 meta 标签,是 4.4 SEO 优化的输入:
---
title: 从静态页到托管产品
description: 我们为什么把创业页迁到云托管
date: 2026-09-18
layout: doc
---
约定三条:每篇必须有 title 与 description,description 不超过 40 字;date 用 ISO 格式,博客列表按它排序;layout 缺省走默认主题。同步维护一份 sitemap 生成脚本,构建时从 frontmatter 汇总所有页面地址,输出 sitemap.xml 到 public/,搜索引擎收录靠它,详见后面的 SEO 优化 一节。
2.3.7 部署前自检清单
每次构建完,跑一遍这五项检查再传云:
- dist/index.html 存在且 base 路径正确(浏览器打开不白屏);
- 全部内部链接可点开,没有 404(脚本扫一遍 dist 里的 a 标签即可);
- 图片尺寸在合理区间,首屏请求不超过 1MB;
- favicon.ico、robots.txt、sitemap.xml 都在 dist 根目录;
- npm run build 在干净机器(或 CI)上能从零跑通。
清单不长,但救过我们好几次:有次部署前没查内部链接,产品页目录改了名,线上点进去一片 404,搜索引擎还把错误链接收录了。这个教训后来直接写进了第三篇的 常见构建失败与排查。
2.3.8 主题微调:改默认主题的三个点
默认主题已经能交付,但创业页需要品牌色对齐。微调集中在三处:主题色 CSS 变量、首页布局、代码块字体。在 theme 目录下覆盖:
import DefaultTheme from "vitepress/theme";
import "./custom.css";
export default {
extends: DefaultTheme,
enhanceApp(app) {
app.component("HeroBanner", HeroBanner);
},
};
custom.css 里覆盖容器宽度与主色变量即可,不动默认主题的源文件,升级 VitePress 版本时改动不丢。品牌色相关变量一共四个:主题色、链接色、代码背景、边框色,产品同学给一份色卡半小时就能对齐。主题定制做到这个程度就够了——再深挖属于过度工程,网站还没上线,别把时间花在换皮肤上。
2.3.9 踩过的坑
坑一:base 没改导致样式 404。本地好好的,部署到子路径后 CSS 全丢。排障先看浏览器控制台请求路径是否带 base 前缀,改 config 重构建即可。
坑二:图片引用。md 里写相对路径图片在 dev 与 build 下解析行为不同,统一放 public/ 或用显式 import 解决,详见 2.4 图片处理。
坑三:大写路由。Mac 上文件名 About.md 生成 about 路由偶尔带大写,部分环境大小写敏感,统一小写加中划线的文件名规范。
小结
模板化改造后,新增一篇博客从复制改 7 个文件变成写 1 个 md。VitePress 让 Vue 与 Markdown 共处,对 Vue 团队几乎没有学习成本,base 对齐是唯一的部署注意点。下一节处理内容站最头疼的资源:图片压缩与 WebP。
延伸阅读
- Node.js 网站托管实战:本书目录,本篇承接第二篇构建主题。
- 云开发 Python 实战:云函数渲染页面内容的另一种多页思路。
