VuePress
VuePress 是一个以 Markdown 为中心的静态网站生成器。你可以使用 Markdown 来书写内容(如文档、博客等),然后 VuePress 会帮助你生成一个静态网站来展示它们。如果你已经有了 docsify/Hexo 等 Markdown 架构网站,简单就能切换到 VuePress。
不过,VuePress 网站需要依赖包环境,生成的静态文件在本地运行会缺少组件,需要服务器或其他云服务上运行。如果本地部署中出现未知 bug,推荐使用 StackBlitz 在线 IDE 工具测试,打开 https://stackblitz.com/github/用户名/仓库名
即可将对应 GitHub 仓库导入 StackBlitz。开发时,建议用 dev 命令测试,这样可以查看打包前的动态代码,发现组件间的内部链接。
LearnData 的主题为 vuepress-theme-hope,图标为 Iconfont 精选图标,页面修改查看 样式配置,其他主题和插件参考 Awesome VuePress V2 和 看板娘。
初始配置
- 环境配置:安装 pnpm,也支持 npm 和 yarn,可参考环境部署教程。
- 新建文件夹,然后在该路径下运行命令
pnpm create vuepress-theme-hope@next docs
。vuepress-theme-hope 主题的样例文件会存储在该路径下。有时因版本问题,样例运行会报错,此时须用固定版本号来安装依赖环境,终端中输入pnpm add vuepress@2.0.0-beta.64 @vuepress/client@2.0.0-beta.64 vuepress-theme-hope@2.0.0-beta.230 && pnpm docs:dev
。 - 执行命令
pnpm docs:dev
启动样例网站。 docs\.vuepress
路径下的 config.ts,navbar.ts,sidebar.ts,theme.ts 可以修改页面属性,设置方法参考 官方案例。- config.ts:配置网站环境依赖和网站属性。
- sidebar.ts:侧边栏,集合所有文档的目录。
- navbar.ts:导航栏,放最常用的文档链接。
- theme.ts:对主题和插件进行设置。
- 如果遇到报错,执行命令
pnpm add vuepress@next vuepress-theme-hope@next && pnpm i && pnpm up
修复并升级相关依赖包。如果依然有问题,则删除 node_modules 和 lock 文件,执行pnpm install && pnpm i && pnpm up
重置依赖包文件。
如果遇到错误 [ERR_MODULE_NOT_FOUND]: Cannot find package
,则将 package.json 放在 demo project 中生成 lock 文件,比对 lock 文件是否为正确生成依赖树,将正确的 lock 文件复制到项目下。
每个插件和主题版本只支持一个 VuePress 版本,因此要稳定的话,需用固定版本号的环境依赖才可以,比如主题 vuepress-theme-hope@2.0.0-beta.230
仅支持 vuepress@2.0.0-beta.64
。如果你需要升级主题和 VuePress 版本,请执行以下命令 pnpm dlx vp-update
。
搜索插件
本地搜索插件:search 根据你的页面,在本地生成搜索索引,然后在用户访问站点时加载搜索索引文件。默认情况下,该插件会将页面标题和小标题作为搜索索引。
在线搜索插件:algolia DocSearch 使用在线爬虫抓取全站,并提供网站搜索索引,抓取周期为一周。开源文档可以申请官方爬虫支持,商业化内容需要自己设置爬虫。
在 algolia 爬虫管理页 修改爬虫抓取规则,然后手动触发爬虫进行全站搜索。之后,algolia 搜索数据库 可以查看搜索次数与数据。
Webpack 打包
VuePress v2 默认使用 Vite,打包时会引入时间戳和 hash 对文件重命名,导致网站大部分的文件发生更改。即使你并没有更新文章,生成的静态文件也会改变。比如我的笔记网站用的 VuePress 默认配置,每次服务器部署需要 5-15 分钟。
如果不想每次架构都重命名文件,可以复制「nohashname」branch。我把 nohashname 分支的打包工具换成了 Webpack,并用 chainWebpack 设置文件命名规则,避免文件非必要重命名。
修改 config.ts 的导入设置,将
import { defineUserConfig } from "vuepress"
替换为import { defineUserConfig } from "@vuepress/cli"
,将import { viteBundler } from "@vuepress/bundler-vite"
替换为import { webpackBundler } from "@vuepress/bundler-webpack"
。Webpack 环境依赖包安装,并运行服务。
#组合命令,打包使用 Webpack pnpm add vuepress@next vuepress-theme-hope@next && pnpm remove vuepress && pnpm add vuepress-webpack@next sass-loader && pnpm i && pnpm up #运行在本地服务器 yarn docs:dev
组合命令也能解决报错,升级相关依赖包。相关命令的分步解释见下方。
#确保你正在使用最新的 vuepress 和 vuepress-theme-hope 版本 pnpm add vuepress@next vuepress-theme-hope@next #更换打包工具,Webpack 需手动下载 sass-loader pnpm remove vuepress pnpm add -D vuepress-webpack@next sass-loader #常用插件:google-analytics,search pnpm add @vuepress/plugin-google-analytics@next @vuepress/plugin-search@next #升级当前目录的依赖以确保你的项目只包含单个版本的相关包 pnpm i && pnpm up
修改文件命名规则:打开 config.ts,使用 webpack-chain 修改 webpack 输出文件名规则,停止对 js 文件 hashname。[1]
.filename
加路径容易报错,这里只把 chunk 文件放入子文件夹。export default defineUserConfig({ bundler: webpackBundler({ chainWebpack(config) { // do not use chunk hash in js //参照案例:https://github.com/vuepress/vuepress-plugin-named-chunks/blob/b9fb5a1d3475530b1d74b6616f92a6e3bf14a7ed/__tests__/docs/.vuepress/config.js config.output .filename(`[name].js`) .chunkFilename("assets/chunks/[name].js"); }, }), });
在查找 chainWebpack 配置前,我依照 vue.config.js 的指引添加了
filenameHashing: false
,但是 VuePress 并未停止 hashname。事实上,我理解错了。根据 @Mister-Hope 的说明,「这里的 filenameHasing 是 vue-cli 自己加的一个属性。拿到这里当例子很奇怪。就好比你按照 iOS 使用手册去设置 Android 结果无效,本不应该有效。另外本身为了防止应用程序出错,你也从不应该移除 hash。」
关闭 prefetch
preload 是一种声明式的资源获取请求方式,用于提前加载一些需要的依赖,并且不会影响页面的 onload 事件。prefetch 是一种利用浏览器的空闲时间加载页面将来可能用到的资源的一种机制;通常可以用于加载非首页的其他页面所需要的资源,以便加快后续页面的首屏速度。preload 主要用于预加载当前页面需要的资源;而 prefetch 主要用于加载将来页面可能需要的资源。
VuePress Build 配置项默认开启了 preload 和 prefetch。但是,开启了 prefetch,所有其它页面所需的文件都会被预拉取。页面较多或服务器宽带后付费的话,建议关闭 prefetch。
docs\.vuepress
路径下的 config.ts 配置中插入 shouldPrefetch: false,
,即可关闭 prefetch。
页面模板
VuePress 页面生成规则基于主题模板,如果修改全站 html 内容,最简单的方式就是修改模板。
我的主题模板文件是 @vuepress-theme-hope/templates/index.build.html
,将其下载到本地后,修改为你想要的样式,放入 .vuepress 文件夹内。最后在 config.ts 中添加代码,即可启用修改模板。
import { path } from "@vuepress/utils";
export default defineUserConfig({
...
templateBuild: path.resolve(__dirname, "index.build.html"),
});
除修改页面模板外,也可以通过修改 config.ts 配置来添加自定义标签。插入下方代码后,网站所有页面都会在 header 前添入对应代码,其效用等同于 <meta name="keywords" content="关键词,内容标签,相关词">
和 <img referrerpolicy="no-referrer-when-downgrade" src="https://tongji.newzone.top/matomo.php?idsite=7&rec=1" style="border:0" alt="" />
。
head: [
[
"meta",
{
name: "keywords",
content: "关键词,内容标签,相关词",
},
],
[
"img",
{
referrerpolicy: "no-referrer-when-downgrade",
src: "https://tongji.newzone.top/matomo.php?idsite=7&rec=1",
style: "border:0",
alt: "",
},
],
],
时间参数
vuepress-plugin-seo2 在网页中插入 og:updated_time
和 article:modified_time
,这两个参数都引用自 page.git.updatedTime
。theme.ts
中无法设置 ogp。你需要打开 config.ts,使用 vuepress-plugin-seo2 的 ogp 参数重新设置 meta,并删除你不想要的参数。根据 @Mister-Hope 的说明:「API 的设计很容易理解,就是给你个自动生成的对象然后等你返回。所以你只需要在原对象上把属性删掉,返回这个对象就是了。」
import { seoPlugin } from "vuepress-plugin-seo2";
export default defineUserConfig({
...
plugins: [
seoPlugin({
hostname: "https://vuepress-theme-hope.github.io",
ogp: (ogp, page) => ({
...ogp,
"og:updated_time": "",
"og:modified_time": "",
}),
],
});
另外,如果想停止向页面导入 lastUpdated 参数,在 theme.ts
中插入 lastUpdated: false
即可。
export default hopeTheme({
lastUpdated: false,
});