清淨
  • Java

    • Java 基础
  • 框架

    • Flyway
    • MapStruct
    • Spring Cloud
  • 中间件

    • Elasticsearch
    • Redis
    • RabbitMQ
    • Kafka
  • 三剑客

    • HTML
    • CSS
    • JavaScript
  • 进阶

    • jQuery
    • ECMAScript6
    • TypeScript
  • Vue

    • Vue2
    • Vue3
    • VuePress
  • Linux
  • Jenkins
  • Maven
  • MySQL
  • 插件工具
  • 代码集成
  • 其它

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • 设计模式
迁移日志
订阅号
微信订阅号
微信订阅号
GitHub
  • Java

    • Java 基础
  • 框架

    • Flyway
    • MapStruct
    • Spring Cloud
  • 中间件

    • Elasticsearch
    • Redis
    • RabbitMQ
    • Kafka
  • 三剑客

    • HTML
    • CSS
    • JavaScript
  • 进阶

    • jQuery
    • ECMAScript6
    • TypeScript
  • Vue

    • Vue2
    • Vue3
    • VuePress
  • Linux
  • Jenkins
  • Maven
  • MySQL
  • 插件工具
  • 代码集成
  • 其它

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • 设计模式
迁移日志
订阅号
微信订阅号
微信订阅号
GitHub
  • VuePress

    • 简介
    • 快速入门
    • 部署
    • 个性化
    • PicGo 插件
    • 升级到 VuePress 2.0.0-rc.31

升级到 VuePress 2.0.0-rc.31

目标:把本站从 vuepress@2.0.0-beta.64 升级到 2.0.0-rc.31。
包管理器:npm。打包工具:Vite(@vuepress/bundler-vite),与当前实际用法一致。
本文只整理升级事项,不包含实际改代码。官方 changelog:vuepress/core CHANGELOG。

当前项目现状

核对过 package.json、lockfile 和 .vuepress 源码,现状如下:

项当前值升级后要求
Nodenvm 当前是 v16.20.1用 nvm 切到 >= 22.18.0(推荐 22 LTS),不要单独安装 Node
npm8.19.4(随 Node 16)切到 Node 22 后随版本自带 npm 10.x
vuepress^2.0.0-beta.64钉死 2.0.0-rc.31
打包工具lockfile 里已是 vuepress-vite / @vuepress/bundler-vite显式安装并配置 @vuepress/bundler-vite@2.0.0-rc.31
主题继承 @vuepress/theme-default,未单独声明依赖必须单独安装 @vuepress/theme-default@next
搜索@vuepress/plugin-docsearch@^2.0.0-beta.64改为 @vuepress/plugin-docsearch@next
vue未单独安装npm 不用显式安装;只有 pnpm 才需要作为 peer 手动装
Sass部署笔记里写过 node-sass + sass-loader(那是 webpack 时期)继续用 Vite,一般不必装 sass-loader;只有编译 .scss 报错时再补 sass

补充两点:

  1. 本仓库 package.json 只写了 vuepress,没有写 bundler。beta.29 起 vuepress 默认 bundler 已经是 Vite,lockfile 也印证了这一点。升级后仍用 Vite,只是 RC 要求显式安装并在配置里声明 @vuepress/bundler-vite。
  2. 配置文件已经是 ESM(import / export),但根 package.json 还没有 "type": "module"。升级后建议补上。

1. 环境:nvm / Node / npm

Node 用 nvm 管理,不要从官网或安装包单独装一份 Node,以免和 nvm 抢 PATH。

Node 版本(硬门槛)

官方最新文档要求:

Node.js >= 22.18.0
引擎范围大约是:^22.18.0 || ^24 || >=26

注意:

  • 不要用 Node 16 / 18 / 20,rc.24 已 drop Node 18,rc.31 文档要求 22.18+。
  • 不要用 Node 23 / 25(已 EOL,官方不让跑)。
  • 中文站有的页面仍写着 v20.9.0+,那是旧信息,以英文文档 / changelog 为准。
  • 本地当前 nvm 切在 v16.20.1,不先切到 22,后面任何安装、dev、build 都会失败。
  • CI / 部署机如果也要 npm run build,同样用 nvm 切到 22+,不要另装系统级 Node。

Windows(nvm-windows)示例:

nvm list                 # 看已安装的版本
nvm list available       # 看可安装的版本(可选)
nvm install 22.18.0      # 没有 22.18+ 时再装;已有 22 LTS 可跳过
nvm use 22.18.0          # 切换到该版本
node -v                  # 确认 >= v22.18.0
npm -v                   # 应变成 10.x

如果已经装过 22 的某个小版本(只要 >= 22.18.0),直接 nvm use 即可,不必再 install。

Unix / Git Bash 下的 nvm 若要把 22 设为默认:

nvm alias default 22

nvm-windows 没有 alias default,下次新开终端仍需 nvm use 22.18.0,或在 nvm 设置里指定默认版本。

npm

继续用 npm 即可,不必换成 pnpm。用 nvm 切到 Node 22 后,npm 会跟着变成 10.x。注意:

  • 官方写得很清楚:只有 pnpm 才需要显式安装 vue 作为 peer-dependencies。npm 会自己处理,本仓库保持现状即可,不要多装一个 vue。
  • 升级前删掉 node_modules 和 package-lock.json,重新 npm install,避免 beta 残留。
  • 确认 where node / where npm 指向 nvm 目录,而不是单独安装的 Node。

建议补到 package.json

{
  "type": "module",
  "engines": {
    "node": "^22.18.0 || ^24 || >=26"
  }
}

2. 依赖怎么装(core 和 ecosystem 版本号不同)

从 RC 开始拆成两个仓库,版本号不要强行对齐成同一个 rc.xx:

来源包版本
core(vuepress/core)vuepress、@vuepress/bundler-vite必须同版本:2.0.0-rc.31
ecosystem(vuepress/ecosystem)@vuepress/theme-default、@vuepress/plugin-docsearch用 @next(目前大约 rc.100+,和 core 的 rc.31 不是一回事)

不要把 @vuepress/plugin-docsearch 也钉成 2.0.0-rc.31,对不上会报 useRouteLocale() is called without provider(项目注释里已经踩过)。

推荐安装命令

# 1. 用 nvm 切到 Node 22(不要单独安装 Node)
nvm use 22.18.0
node -v   # 需要 v22.18.0+

# 2. 清掉旧依赖
rmdir /s /q node_modules
del package-lock.json

# 3. core:vuepress 和 vite bundler 必须同版本
#    npm 不需要显式安装 vue(pnpm 才需要)
npm i -D vuepress@2.0.0-rc.31 @vuepress/bundler-vite@2.0.0-rc.31

# 4. ecosystem:主题、搜索(代码高亮用默认主题自带的 PrismJS,不必另装插件)
npm i -D @vuepress/theme-default@next @vuepress/plugin-docsearch@next

tippy.js 继续留在 dependencies,clipboard 插件还在用。

装完后 package.json 的 devDependencies 大致应是:

{
  "vuepress": "2.0.0-rc.31",
  "@vuepress/bundler-vite": "2.0.0-rc.31",
  "@vuepress/theme-default": "^2.0.0-rc.xxx",
  "@vuepress/plugin-docsearch": "^2.0.0-rc.xxx"
}

3. Vite 专项

3.1 必须显式声明 bundler

RC 起不再内置默认 bundler,不写 bundler 会直接起不来。

docs/.vuepress/config.js 需要变成:

import { defineUserConfig } from 'vuepress'
import { viteBundler } from '@vuepress/bundler-vite'
import { baseConfig } from './config/base-config'
import { theme } from './config/theme'
import { plugins } from './plugins/index'

export default defineUserConfig({
  ...baseConfig,
  bundler: viteBundler(),
  theme,
  plugins,
})

当前项目没有自定义 Vite 配置,先用空的 viteBundler() 即可。

可选参数(一般用不到):

viteBundler({
  viteOptions: {},
  vuePluginOptions: {},
})

3.2 rc.31 的 bundler 接口变化

rc.31 给 bundler 补了 type、mergeConfig,并新增 configureVite / viteMergeConfig。用官方 viteBundler() 即可,不必自己实现接口。

如果以后要改 Vite 配置,优先改 viteOptions;若用 configureVite 做合并,用官方的 viteMergeConfig,不要假设返回值会自动 merge。

3.3 Sass

Vite 内置处理 .scss / .sass,不需要 sass-loader。部署笔记里 node-sass + sass-loader@10 是 webpack 时期的写法,本次不要照搬。

  • node-sass 已废弃,也不支持 Node 22。
  • Vite 编译 Sass 用的是 Dart Sass 包 sass。npm 通常会通过默认主题把 sass 带进来。
  • 如果启动时报找不到 sass 或无法编译 .scss,再补:npm i -D sass。

本站有大量 .scss(styles/、NotFound.vue),升级后若样式编译失败,优先检查有没有 sass,而不是去装 webpack 的 loader。

3.4 base 与 Public 文件

Vite 会给 Public 文件自动处理 base,比 webpack 省事。当前站点 base: '/',线上若仍是根路径,无感。

如果以后又改成 /note/ 这类子路径:

  • Vite 会给 public 资源补前缀。
  • JS 里手写的绝对路径(如 useInit.js 的 /images/wx/qrcode_258_8.jpg)仍不会自动加 base,需要自己处理,或改用 VuePress 的 withBase()。
  • 部署笔记里 nginx location /note + base: '/note/' 这条经验仍然有效。

3.5 部署时的 MIME

打包产物里会有 .mjs。nginx 需要:

application/javascript    js mjs;

这条在 deploy.md 里已经记过,升级后仍然要保留。

4. 配置 API 必改项

4.1 导入路径

VuePress 内部包改为从 vuepress/* 子路径导出:

旧(beta.64)新(rc.31)本仓库文件
@vuepress/clientvuepress/clientclient.js、clipboard 的 client/index.js
@vuepress/utilsvuepress/utilsconfig/base-config.js、clipboard 的 index.js

@vuepress/theme-default 这个包名不变,但必须单独安装。

defineUserConfig 仍从 vuepress 导入,不用改。

4.2 markdown.code 已删除

docs/.vuepress/config/base-config.js 里这段会失效:

markdown: {
  headers: { level: [1, 2, 3, 4] }, // 保留
  code: {                           // 已删除
    vPre: { inline: true, block: true },
  },
}

改为:

markdown: {
  headers: { level: [1, 2, 3, 4] },
  vPre: { inline: true, block: true },
}

代码高亮不再由 VuePress core 内置。使用默认主题时,主题已经集成了 @vuepress/plugin-prismjs,不必单独安装,也不要再手动注册一份高亮插件。只要不要把 themePlugins.prismjs 设成 false 即可。关掉的话代码块没有高亮,clipboard 插件依赖的 div[class*="language-"] 也可能对不上。

4.3 主题 option 大多还能用

config/theme.js 里这些 locale / 功能开关仍然有效,可先不动:

  • colorMode / colorModeSwitch / toggleColorMode
  • navbar / sidebar / sidebarDepth / logo / logoDark
  • repo / repoLabel / docsBranch / docsDir / editLink*
  • lastUpdated / lastUpdatedText / contributors / contributorsText
  • tip / warning / danger / notFound / backToHome

lastUpdated、contributors 依赖 Git 信息。默认主题会带 @vuepress/plugin-git,仓库里要有 commit。

自定义字段 userConfig(背景图、打字机、页脚文案)是传给默认主题的额外 option,会进 theme-data。数据还能读到,但下面第 6 节的 DOM 选择器会失效。

4.4 其它站点配置

这些可以先保持:

  • port: 8088
  • dest: 'docs/dist'
  • temp: 'docs/.temp'
  • cache: 'docs/.cache'
  • alias(@components / @hooks)
  • head 里的 favicon、iconfont

rc.31 的 shouldPrefetch 默认从 true 改成 'as-needed'。文档站页面多,建议保持新默认,不必改回 true。

5. 自定义主题:还能用的部分

当前结构:

// theme/index.js
extends: defaultTheme(options)
// layouts/Layout.vue
import ParentLayout from '@vuepress/theme-default/layouts/Layout.vue'
// client.js
layouts: { Layout, NotFound }

官方仍支持:

  • extends: defaultTheme(options) 做子主题
  • Layout 插槽:page-bottom 等(navbar / sidebar / page-top 也都还在)
  • 从 @vuepress/theme-default/layouts/Layout.vue 引入父布局
  • 在 client.js 的 layouts 里覆盖 Layout、NotFound

也就是说:子主题继承方式不用推倒重来。真正会坏的是样式选择器和 DOM 查询。

theme/index.js 里不要再写 layouts(beta.51 已移除,本仓库已经改到 client.js,这块是对的)。

6. 自定义主题:一定会坏的部分(重点)

默认主题在 ecosystem 做过破坏性重构:

  • 组件加 VP 前缀:Navbar → VPNavbar
  • class 加 vp- 前缀:.navbar → .vp-navbar
  • 暗色模式:html.dark → html[data-theme='dark']
  • CSS 变量:--c-* → --vp-c-*

容器根节点 class 从 .theme-container 变成 .vp-theme-container,但 no-sidebar 这个修饰 class 还在。

6.1 CSS class 对照

按当前源码,升级后选择器要改成类似:

本仓库现在写的rc 默认主题
header.navbar.vp-navbar
.navbar-items-wrapper.vp-navbar-items-wrapper
nav.navbar-itemsnav.vp-navbar-items
.navbar-item.vp-navbar-item
.toggle-color-mode-button对应 VPToggleColorModeButton(大概率 .vp-toggle-color-mode-button,以实际 DOM 为准)
div.theme-container.vp-theme-container
main.home.vp-home
header.hero / .hero.vp-hero
p.description.vp-hero-description
.site-name / img.logo以 VPNavbarBrand 实际 DOM 为准
.sidebar / .sidebar-item.vp-sidebar 等(以实际 DOM 为准)
.custom-container.tip默认主题已改用 @vuepress/plugin-markdown-hint,不再是 .custom-container
div.back-to-top回到顶部已抽到独立插件,class 会变

涉及文件:

  • styles/navbar.scss
  • styles/home.scss
  • styles/sider.scss
  • styles/normal.scss
  • styles/back-to-top.scss
  • styles/scroll.scss(html:has(.theme-container.no-sidebar) 也要改)
  • styles/footer.scss(首页 footer 结构也可能变)

6.2 CSS 变量对照

styles/variables.scss、NotFound.vue、LoadingPage.vue 里的旧变量要换:

旧新
--c-brand--vp-c-accent / --vp-c-accent-bg
--c-brand-light--vp-c-accent-hover
--c-bg--vp-c-bg
--c-text--vp-c-text
--c-text-accent--vp-c-accent
--c-bg-navbar--vp-navbar-c-bg
html.dark { ... }[data-theme='dark'] { ... }

layout 类变量名大多还在,例如 --content-width、--navbar-height、--navbar-padding-v。品牌色和暗色选择器必须改,否则会回到默认主题的绿色 / 默认暗色。

默认主题现在约定:

  • Sass 变量覆盖:.vuepress/styles/palette.scss(断点等,当前项目几乎没覆盖 Sass 变量)
  • 额外 CSS / CSS 变量:.vuepress/styles/index.scss(当前就是这个入口,可继续用)

6.3 JS 里的 DOM 查询(首页和导航会挂)

这些是按 beta 默认主题 DOM 写的,升级后选择器对不上,功能会静默失效:

hooks/useUserConfig.js

document.querySelector('#app .no-sidebar main.home')
document.querySelector('#app .no-sidebar main.home header.hero .description')

hooks/useBackgroundImgLoaded.js

document.querySelector('#app .no-sidebar main.home header.hero')
document.querySelector('#app .no-sidebar main.home')

hooks/useInit.js(微信二维码挂在倒数第二个导航项上)

document.querySelector('nav.navbar-items .navbar-item:nth-last-child(2)')

建议对照:

旧:#app .no-sidebar main.home
新:.vp-theme-container.no-sidebar .vp-home

旧:header.hero / p.description
新:.vp-hero / .vp-hero-description

旧:nav.navbar-items .navbar-item
新:nav.vp-navbar-items .vp-navbar-item

useThemeData 从 @vuepress/plugin-theme-data/client 导入这条路还在(默认主题内置了 theme-data),userConfig 一般还能读到。不要在 Node 环境或 SSR 阶段直接操作 document,继续放在 onMounted / watch(route) 里。

长期更稳的做法:用 Layout 插槽或 @theme 组件替换,少依赖 querySelector。升级第一轮可以先改选择器,保证功能回来。

7. 自定义 clipboard 插件

文件:docs/.vuepress/plugins/clipboard/

必改:

  1. Node 入口把 @vuepress/utils 换成 vuepress/utils。
  2. ESM 不要依赖 __dirname。rc.31 CLI 已从 esbuild 换成 rolldown,注入行为可能变:
import { getDirname, path } from 'vuepress/utils'

const __dirname = getDirname(import.meta.url)
  1. 客户端入口:
import { defineClientConfig } from 'vuepress/client'
  1. 代码高亮走默认主题自带的 PrismJS,代码块 DOM 仍是 div[class*="language-"]。clipboard 的 selector 保持这个即可,真实页面上再验一次。
  2. tippy.js 继续用,确认 Vite 能正确处理 tippy.js/dist/tippy.css。

8. DocSearch

docsearchPlugin({ appId, apiKey, indexName, translations }) 用法大体兼容,但:

  • 必须装 ecosystem 的 @next,不要跟 core 一样钉 rc.31。
  • indexName 还能用,文档说会弃用,新字段是 indices。
  • 默认主题 DOM 变了,Algolia 爬虫选择器要改,否则搜索框能开、命中和跳转可能不准。官方现在类似:
recordProps: {
  lvl0: {
    selectors: '.vp-sidebar-heading.active',
    defaultValue: 'Documentation',
  },
  lvl1: '[vp-content] h1',
  lvl2: '[vp-content] h2',
  content: '[vp-content] p, [vp-content] li',
}

自定义搜索按钮样式(normal.scss 里的 .DocSearch-Button)一般还能用,变量是否还叫 --docsearch-* 以插件实际注入为准。

9. 建议的落地顺序

按这个顺序改,避免一次改太多、问题分不清是依赖还是样式。

  1. 用 nvm 切到 Node 22.18+(nvm install / nvm use,不要单独装 Node),确认 node -v、npm -v。
  2. 删 node_modules / package-lock.json,按第 2 节重装依赖,加上 "type": "module"。
  3. 改能编译的配置:
    • bundler: viteBundler()
    • 导入路径 vuepress/client、vuepress/utils
    • markdown.vPre;代码高亮用默认主题自带的 PrismJS(不要关 themePlugins.prismjs,也不要另装 shiki / prismjs)
    • clipboard 的 __dirname / 导入路径
  4. 先求 npm run dev 能起来(允许首页样式乱)。
  5. 打开首页 / 文档页,对照实际 DOM 改:
    • styles/*.scss 的 class、CSS 变量、[data-theme='dark']
    • useUserConfig / useInit / useBackgroundImgLoaded 的选择器
  6. 回归清单:
    • [ ] npm run dev 能启动(Vite,端口 8088)
    • [ ] 首页背景图随机切换
    • [ ] 首页打字机文案
    • [ ] 导航栏「订阅号」微信二维码
    • [ ] 亮色 / 暗色切换
    • [ ] 侧边栏、自定义 container(tip/warning/danger)
    • [ ] 代码高亮 + 复制按钮
    • [ ] DocSearch
    • [ ] 404 页
    • [ ] 文章页 footer(page-bottom 插槽)
    • [ ] 回到顶部按钮
  7. npm run build,检查 docs/dist;部署环境同样用 nvm 切到 22+,nginx 仍识别 .mjs。

10. 本仓库需要动的文件清单

文件原因
package.json依赖、"type": "module"、可选 engines
docs/.vuepress/config.js增加 viteBundler()
docs/.vuepress/config/base-config.jsvuepress/utils;markdown.code → markdown.vPre
docs/.vuepress/client.jsvuepress/client
docs/.vuepress/theme/index.js确认 defaultTheme 仍从 @vuepress/theme-default 导入
docs/.vuepress/config/theme.js关掉 copyCode(继续用自定义 clipboard);PrismJS 保持默认主题自带,不要设 prismjs: false
docs/.vuepress/plugins/index.js不要加 shiki / prismjs 插件;docsearch 继续用但版本改为 @next
docs/.vuepress/plugins/clipboard/index.jsvuepress/utils + getDirname
docs/.vuepress/plugins/clipboard/client/index.jsvuepress/client
docs/.vuepress/hooks/useUserConfig.jsDOM 选择器
docs/.vuepress/hooks/useBackgroundImgLoaded.jsDOM 选择器
docs/.vuepress/hooks/useInit.js导航 DOM 选择器
docs/.vuepress/styles/variables.scssCSS 变量 + 暗色选择器
docs/.vuepress/styles/navbar.scssvp- class
docs/.vuepress/styles/home.scssvp-home / vp-hero
docs/.vuepress/styles/sider.scsssidebar class
docs/.vuepress/styles/normal.scsscontainer / html.dark / --c-brand
docs/.vuepress/styles/scroll.scsshtml.dark、.theme-container
docs/.vuepress/styles/back-to-top.scss回到顶部 class
docs/.vuepress/styles/footer.scss视首页 footer DOM 是否变化
docs/.vuepress/components/NotFound.vue--c-brand
docs/.vuepress/components/LoadingPage.vue--c-bg
docs/.vuepress/layouts/Layout.vue父布局导入路径先保持,确认仍能解析

config/navbar、config/sidebar 的数据结构可先不动;config/theme.js 只需处理 themePlugins(关掉 copyCode、保留默认 PrismJS),等页面起来再看导航高亮、侧边栏折叠有没有问题。

参考链接

  • 快速上手(含 Node 版本;pnpm 才需显式安装 vue)
  • Vite bundler
  • 默认主题配置
  • 默认主题样式变量
  • 继承默认主题 / 布局插槽
  • DocSearch
  • PrismJS(默认主题已集成)
  • Core changelog
  • rc.31 发布说明
想要编辑此页?
上次更新: 2026/8/29 14:13
贡献者: 1718
←PicGo 插件
[ 纸上得来终觉浅绝知此事要躬行 ]
Copyright © 2021-present Junfeng Dai
蜀ICP备2021009537号