VuePress
VuePress 是一个以 Markdown 为中心的静态网站生成器。你可以使用 Markdown 来书写内容(如文档、博客等),然后 VuePress 会帮助你生成一个静态网站来展示它们。如果你已经有了 docsify/Hexo 等 Markdown 架构网站,简单就能切换到 VuePress。
不过,VuePress 网站需要依赖包环境,生成的静态文件在本地运行会缺少组件,需要服务器或其他云服务上运行。如果本地部署中出现未知 bug,推荐使用 StackBlitz 在线 IDE 工具测试,打开 https://stackblitz.com/github/用户名/仓库名
即可将对应 GitHub 仓库导入 StackBlitz。开发时,建议用 dev 命令测试,这样可以查看打包前的动态代码,发现组件间的内部链接。
LearnData 的主题为 vuepress-theme-hope,图标来自 iconify,页面修改查看 样式配置,其他主题和插件参考 Awesome VuePress V2 和 看板娘。
初始配置
- 环境配置:安装 pnpm,也支持 npm 和 yarn,可参考环境部署教程。
- 新建文件夹,然后在该路径下运行命令
pnpm create vuepress-theme-hope docs
。vuepress-theme-hope 主题的样例文件会存储在该路径下。有时因版本问题,样例运行会报错,此时须用固定版本号来安装依赖环境。 - 执行命令
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 && 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-rc.50
仅支持 vuepress@2.0.0-rc.14
。如果你需要升级主题和 VuePress 版本,请执行以下命令 pnpm dlx vp-update
。
搜索插件
本地搜索
@vuepress/plugin-search 和 vuepress-plugin-search-pro 插件都会根据页面内容自动生成本地搜索索引,这些索引在访问者浏览网站时加载。默认情况下,该插件会将页面标题和小标题作为搜索索引。
在线搜索插件
对于包含大量页面的网站,推荐使用 Algolia DocSearch 插件。它通过一个在线爬虫周期性(每周一次)抓取整个网站,创建一个全面的搜索索引。开源项目可以免费申请 Algolia 的官方爬虫服务,而商业项目则需要配置私有爬虫。
爬虫的配置可以在 Algolia 爬虫管理页面 进行调整。修改抓取规则后,需要手动启动爬虫以更新站点索引。Algolia 搜索数据库 可以监控搜索操作和数据统计。
下面是我优化后的爬虫配置,结果将按文章标题分组展示:
actions: [
{
indexName: "newzone",
pathsToMatch: ["https://newzone.top/**"],
recordExtractor: ({ $, helpers }) => {
// 移除不需要的干扰文字或元素
// $(".external-link-icon-sr-only").remove();
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: [".vp-sidebar-page.active", ".vp-page-title h1"],
defaultValue: "Documentation",
},
// vuepress-theme-hope 默认的容器类名为 theme-hope-content
lvl1: ".theme-hope-content h1",
lvl2: ".theme-hope-content h2",
lvl3: ".theme-hope-content h3",
lvl4: ".theme-hope-content h4",
lvl5: ".theme-hope-content h5",
lvl6: ".theme-hope-content h6",
content: ".theme-hope-content p, .theme-hope-content li",
},
indexHeadings: true,
});
},
},
],
Webpack 打包
从 VuePress 2.0.0-rc.2 版本起,你可以自由选择 Vite 或 Webpack 作为打包工具。使用 Vite 进行打包时,系统会引入时间戳和 hash 值对文件进行重命名。这一机制虽然保证了文件的唯一性,但同时也带来了一个问题:即使没有更新内容,网站的大部分文件在每次生成时也会发生改变。例如,在我的 VuePress 默认配置的笔记网站中,每次服务器部署都需耗费 5 至 15 分钟的宝贵时间。新版的 LearnData 已经默认采用了 Webpack 作为打包工具,因此无需手动切换。
早期 VuePress 仅支持 Vite,因此我手动集成了 Webpack,目前此做法仅供记录。
如果不想每次架构都重命名文件,可以复制「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 && 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 #更换打包工具,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,
});
自定义主题
- 0
- 0
- 0
- 0
- 0