diff --git a/cli/src/run.ts b/cli/src/run.ts
index 51225423..1a293a01 100644
--- a/cli/src/run.ts
+++ b/cli/src/run.ts
@@ -2,6 +2,7 @@ import type { PromptResult, ResolvedData } from './types.js'
import path from 'node:path'
import process from 'node:process'
import { intro, outro, spinner } from '@clack/prompts'
+import { sleep } from '@pengzhanbo/utils'
import { execaCommand } from 'execa'
import colors from 'picocolors'
import { Mode } from './constants.js'
@@ -21,6 +22,10 @@ export async function run(mode: Mode, root?: string) {
await generate(mode, data)
+ // Delay for some time, I/O may not be completed yet,
+ // executing subsequent tasks at this point may cause issues.
+ await sleep(200)
+
const cwd = path.join(process.cwd(), data.root)
if (data.git) {
progress.message(t('spinner.git'))
diff --git a/cli/templates/deploy/github/.github/workflows/deploy.yml.handlebars b/cli/templates/deploy/github/.github/workflows/deploy.yml.handlebars
index ede07401..83e34c58 100644
--- a/cli/templates/deploy/github/.github/workflows/deploy.yml.handlebars
+++ b/cli/templates/deploy/github/.github/workflows/deploy.yml.handlebars
@@ -23,6 +23,7 @@ jobs:
{{#if (equal packageManager "pnpm")}}
- name: Setup pnpm
uses: pnpm/action-setup@v4
+
{{/if}}
- name: Setup Node.js
uses: actions/setup-node@v4
diff --git a/docs/.vuepress/themes/components/ThemeColors.vue b/docs/.vuepress/themes/components/ThemeColors.vue
index 54d185f2..4b448d24 100644
--- a/docs/.vuepress/themes/components/ThemeColors.vue
+++ b/docs/.vuepress/themes/components/ThemeColors.vue
@@ -36,7 +36,7 @@ const { lightColors, darkColors, css, reset } = useThemeColors()
-
复制下方的代码到您的项目中,请参考 主题定制
+ 复制下方的代码到您的项目中,请参考 主题定制
diff --git a/docs/notes/theme/guide/知识笔记.md b/docs/notes/theme/guide/知识笔记.md
index 32c9883a..7d3142ac 100644
--- a/docs/notes/theme/guide/知识笔记.md
+++ b/docs/notes/theme/guide/知识笔记.md
@@ -82,6 +82,60 @@ export default defineUserConfig({
:::
+### 编写notes配置
+
+由于 `notes` 配置全部写在 `plumeTheme({ })` 中可能会导致 代码层级嵌套过深,因此更推荐使用主题提供的
+`defineNotesConfig()` 和 `defineNoteConfig()` 将 notes 配置提取到外部,它们还能帮助你获得更好的类型提示,
+更具可读性和便于维护。
+
+::: code-tabs
+
+@tab .vuepress/notes.ts
+
+```ts
+import { defineNoteConfig, defineNotesConfig } from 'vuepress-theme-plume'
+
+/**
+ * 配置 单个 note
+ */
+const typescript = defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ '/guide/intro.md',
+ '/guide/getting-start.md',
+ '/config/config-file.md',
+ ]
+})
+
+/**
+ * 配置 notes
+ */
+export default defineNotesConfig({
+ // 声明所有笔记的目录,(默认配置,通常您不需要声明它)
+ dir: '/notes/',
+ link: '/',
+ // 在这里添加 note 配置
+ notes: [typescript] // [!code ++]
+})
+```
+
+@tab .vuepress/config.ts
+
+```ts
+import { defineUserConfig } from 'vuepress'
+import { plumeTheme } from 'vuepress-theme-plume'
+import notes from './notes' // [!code ++]
+
+export default defineUserConfig({
+ theme: plumeTheme({
+ notes // [!code ++]
+ }),
+})
+```
+
+:::
+
### 侧边栏配置
以 `typescript` 目录为例,它拥有如下的文件结构:
@@ -171,21 +225,21 @@ interface SidebarItem {
}
```
-::: info
-以下代码块中 `sidebar` 表示传入到 `notes` 中的 `sidebar` 参数。
-
-这里为了方便演示说明,将其单独使用 `const sidebar: Sidebar = [...]` 进行说明。
-:::
-
当 传入类型为 `string` 时,表示 markdown 文件的路径:
```ts
-const sidebar: Sidebar = [
- '/guide/intro.md',
- '/guide/getting-start.md',
- '/config/config-file.md',
- // ...
-]
+import { defineNoteConfig } from 'vuepress-theme-plume'
+
+export default defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ '/guide/intro.md',
+ '/guide/getting-start.md',
+ '/config/config-file.md',
+ // ...
+ ]
+})
```
你也可以省略 `.md` 文件后缀,简写为 `/guide/intro` 。主题会解析 对应的文件,获取 **标题** 和 **页面链接地址**
@@ -194,32 +248,44 @@ const sidebar: Sidebar = [
当传入类型为 `SidebarItem` 时:
```ts
-const sidebar: Sidebar = [
- { text: '介绍', link: '/guide/intro' },
- { text: '快速上手', link: '/guide/getting-start' },
+import { defineNoteConfig } from 'vuepress-theme-plume'
+
+export default defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ { text: '介绍', link: '/guide/intro' },
+ { text: '快速上手', link: '/guide/getting-start' },
// ...
-]
+ ]
+})
```
也可以进行多层嵌套:
```ts
-const sidebar: Sidebar = [
- {
- text: '指南',
- prefix: '/guide', // 使用 prefix 拼接,可以简写 下面的 items 中的 link 为相对路径
- items: [
+import { defineNoteConfig } from 'vuepress-theme-plume'
+
+export default defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ {
+ text: '指南',
+ prefix: '/guide', // 使用 prefix 拼接,可以简写 下面的 items 中的 link 为相对路径
+ items: [
// 可以混用 string 和 SidebarItem
- { text: '介绍', link: 'intro' },
- 'getting-start',
- ],
- },
- {
- text: '配置',
- prefix: '/config',
- items: 'auto', // items 为 'auto',会根据 prefix 的文件结构自动生成侧边栏
- },
-]
+ { text: '介绍', link: 'intro' },
+ 'getting-start',
+ ],
+ },
+ {
+ text: '配置',
+ prefix: '/config',
+ items: 'auto', // items 为 'auto',会根据 prefix 的文件结构自动生成侧边栏
+ },
+ ]
+})
```
### 关于 `prefix`
@@ -230,23 +296,29 @@ const sidebar: Sidebar = [
需要注意的是,`items` 中的链接 仅有 相对路径的链接才会与 `prefix` 拼接,而绝对路径则不进行处理。
```ts
-const sidebar: Sidebar = [
- {
- prefix: '/guide',
- items: [
- 'intro', // 相对路径, 最终拼接为 /guide/intro
- '/config/config-file', // 绝对路径,不拼接
- {
- text: '博客',
- link: 'blog', // 相对路径, 最终拼接为 /guide/blog
- },
- {
- text: '配置',
- link: '/config', // 绝对路径,不拼接
- }
- ]
- }
-]
+import { defineNoteConfig } from 'vuepress-theme-plume'
+
+export default defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ {
+ prefix: '/guide',
+ items: [
+ 'intro', // 相对路径, 最终拼接为 /guide/intro
+ '/config/config-file', // 绝对路径,不拼接
+ {
+ text: '博客',
+ link: 'blog', // 相对路径, 最终拼接为 /guide/blog
+ },
+ {
+ text: '配置',
+ link: '/config', // 绝对路径,不拼接
+ }
+ ]
+ }
+ ]
+})
```
同时,`items` 内还支持 深层嵌套,内部还依然支持 `prefix`,这里也遵循相同的规则,`prefix` 如果是相对路径,
@@ -254,28 +326,34 @@ const sidebar: Sidebar = [
上一层级 `prefix` 拼接。
```ts
-const sidebar: sidebar = [
- {
- prefix: '/guide',
- items: [
- 'intro', // 相对路径, 最终拼接为 /guide/intro
- {
- prefix: '/config',
- items: [
- 'config-file', // 相对路径, 最终拼接为 /config/config-file
- 'configuration', // 相对路径, 最终拼接为 /config/configuration
- ]
- },
- {
- prefix: 'blog',
- items: [
- 'intro', // 相对路径, 最终拼接为 /guide/blog/intro
- 'getting-start', // 相对路径, 最终拼接为 /guide/blog/getting-start
- ]
- }
- ]
- }
-]
+import { defineNoteConfig } from 'vuepress-theme-plume'
+
+export default defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ {
+ prefix: '/guide',
+ items: [
+ 'intro', // 相对路径, 最终拼接为 /guide/intro
+ {
+ prefix: '/config',
+ items: [
+ 'config-file', // 相对路径, 最终拼接为 /config/config-file
+ 'configuration', // 相对路径, 最终拼接为 /config/configuration
+ ]
+ },
+ {
+ prefix: 'blog',
+ items: [
+ 'intro', // 相对路径, 最终拼接为 /guide/blog/intro
+ 'getting-start', // 相对路径, 最终拼接为 /guide/blog/getting-start
+ ]
+ }
+ ]
+ }
+ ]
+})
```
**是否是绝对路径的判断标准是,如果以 `/` 开头,则为绝对路径,否则为相对路径**
@@ -290,33 +368,45 @@ const sidebar: sidebar = [
你可以使用超过 `200k` 的图标,仅需要添加 `icon` 配置即可。
```ts
-const sidebar: Sidebar = [
- {
- text: '指南',
- prefix: '/guide',
- icon: 'ep:guide', // iconify icon name // [!code hl]
- items: [
- { text: '介绍', link: 'intro', icon: 'ph:info-light' }, // [!code hl]
- ],
- },
-]
+import { defineNoteConfig } from 'vuepress-theme-plume'
+
+export default defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ {
+ text: '指南',
+ prefix: '/guide',
+ icon: 'ep:guide', // iconify icon name // [!code hl]
+ items: [
+ { text: '介绍', link: 'intro', icon: 'ph:info-light' }, // [!code hl]
+ ],
+ },
+ ]
+})
```
也可以使用本地图标,或者本地图片:
```ts
-const sidebar: Sidebar = [
- {
- text: '指南',
- prefix: '/guide',
- icon: '/images/guide.png', // iconify icon name // [!code hl]
- items: [
- { text: '介绍', link: 'intro', icon: '/images/info.png' }, // [!code hl]
- // 也可以是一个远程图片
- { text: '快速上手', link: 'getting-start', icon: 'https://cn.vuejs.org/images/logo.png' },
- ],
- },
-]
+import { defineNoteConfig } from 'vuepress-theme-plume'
+
+export default defineNoteConfig({
+ dir: 'typescript',
+ link: '/typescript/',
+ sidebar: [
+ {
+ text: '指南',
+ prefix: '/guide',
+ icon: '/images/guide.png', // iconify icon name // [!code hl]
+ items: [
+ { text: '介绍', link: 'intro', icon: '/images/info.png' }, // [!code hl]
+ // 也可以是一个远程图片
+ { text: '快速上手', link: 'getting-start', icon: 'https://cn.vuejs.org/images/logo.png' },
+ ],
+ },
+ ]
+})
```
**请注意,使用本地图片必须以 `/` 开头,表示为 静态资源路径,它将从 `.vuepress/public/` 目录中加载。**
diff --git a/docs/notes/theme/guide/自定义样式.md b/docs/notes/theme/guide/自定义样式.md
index 10614928..f38bae78 100644
--- a/docs/notes/theme/guide/自定义样式.md
+++ b/docs/notes/theme/guide/自定义样式.md
@@ -20,10 +20,10 @@ permalink: /guide/custom-style/
@tab .vuepress/client.ts
-```ts {1}
+```ts
import { defineClientConfig } from 'vuepress/client'
-import './styles/index.css'
+import './styles/index.css' // [!code ++]
export default defineClientConfig({
// ...
diff --git a/theme/src/node/prepare/prepareSidebar.ts b/theme/src/node/prepare/prepareSidebar.ts
index 5517f50c..a6cdf6d0 100644
--- a/theme/src/node/prepare/prepareSidebar.ts
+++ b/theme/src/node/prepare/prepareSidebar.ts
@@ -179,7 +179,10 @@ function getAllSidebar(localeOptions: PlumeThemeLocaleOptions): Record