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。

延伸阅读