[特殊字符]你还不知道VitePress吗?

VitePress 基本功能及 Vitepress-theme-demoblock 插件使用指南

一、VitePress 基本功能介绍与使用示例

1.1 VitePress 简介

VitePress 是一个由 Vite 驱动的静态站点生成器(SSG),专为快速构建技术文档、博客等轻量级网站设计。它基于 Vue.js,具有简洁的配置、快速的热更新和良好的性能,能够帮助开发者轻松搭建美观且功能强大的文档站点。

1.2 基本功能

1.2.1 快速搭建项目

使用 npm 或 yarn 可以快速初始化一个 VitePress 项目。通过命令行运行

npm init vitepress@latestyarn create vitepress

按照提示完成项目创建,之后在项目目录下运行

npm run docs:devyarn docs:dev

即可启动本地开发服务器,在浏览器中预览站点。

1.2.2 Markdown 支持

VitePress 深度支持 Markdown 语法,允许用户使用简洁的 Markdown 编写内容。

同时,它还支持 Markdown 扩展语法,如 YAML Front Matter 用于设置页面元数据(标题、描述等),以及 Vue 组件的直接嵌入,让静态内容也能拥有动态交互效果。

例如,在 Markdown 文件中添加 YAML Front Matter:

---
title: 我的VitePress页面
description: 这是一个使用VitePress创建的页面
layout: layouts/MyLayout.vue
---
1.2.3 主题与定制

VitePress 提供了默认主题,具备简洁的 UI 风格。

用户也可以自定义主题,通过修改 CSS 样式、添加自定义 Vue 组件,甚至创建全新的主题布局,来满足个性化需求。

比如,在.vitepress/theme/index.js 文件中引入自定义样式:

import DefaultTheme from 'vitepress/theme'
import './styles/main.css'
export default {
 ...DefaultTheme,
  enhanceApp({ app }) {
    // 可以在这里注册全局组件等
  }
}
1.2.4 搜索功能

VitePress 内置了搜索功能,用户无需额外配置即可使用。在站点页面中,搜索框会自动根据文档内容进行关键词匹配,方便读者快速找到所需信息。

1.3 使用示例

假设我们要创建一个简单的技术文档页面。首先,在docs目录下创建一个新的 Markdown 文件,如example.md,内容如下:

---
title: 示例页面
description: 这是一个VitePress示例页面
---
# 欢迎来到示例页面
这里是一些示例内容,可以使用Markdown语法编写文本、标题、列表等。
- 列表项1
- 列表项2

保存文件后,启动本地开发服务器,在浏览器中访问对应的链接,即可看到创建的示例页面。

二、Vitepress-theme-demoblock 插件使用场景和功能配置及示例

2.1 插件使用场景

Vitepress-theme-demoblock 插件主要用于在技术文档中展示代码示例及其实际效果,特别适用于组件库文档、前端框架教程等场景。它可以让读者更直观地看到代码运行后的样子,增强文档的可读性和实用性。

例如,当你在编写一个 Vue 组件库的文档时,通过该插件可以直接展示组件的多种使用方式及效果,方便开发者参考和使用。

2.2 功能配置

2.2.1 安装插件

首先,在项目中安装vitepress-theme-demoblock插件。

使用 npm 安装的命令为:npm install vitepress-theme-demoblock

使用 yarn 安装则运行:yarn add vitepress-theme-demoblock

2.2.2 配置插件

配置基于 vitepress-theme-demoblock@^3.0.0"

.vitepress/theme/index.js 中使用 vitepress-theme-demoblock 主题,并注册组件(包含主题中默认的组件):

import DefaultTheme from 'vitepress/theme'
import "vitepress-theme-demoblock/dist/theme/styles/index.css";
import Demo from "vitepress-theme-demoblock/dist/client/components/Demo.vue";
import DemoBlock from "vitepress-theme-demoblock/dist/client/components/DemoBlock.vue";
import setup from "@/components"; // 组件组册方法

export default {
  extends: DefaultTheme,
  enhanceApp(ctx) {
    app.component("Demo", Demo);
    app.component("DemoBlock", DemoBlock);
    setup(ctx.app); // 只有全局组册组件,在demo示例中组件才能显示
  }
}

setup注册方法示例:

import { plugins, components } from "./index";
import type { App, Component } from "vue";

export function setupComponents(app: App) {
  plugins.forEach((plugin: { install: (app: App) => void }) => {
    app.use(plugin);
  });
  components.forEach((item: Component) => {
    app.component(item.name!, item);
  });
}

同时,.vitepress/config.js 文件中使用 demoblockPlugindemoblockVitePlugin 插件:

import { demoblockPlugin, demoblockVitePlugin } from 'vitepress-theme-demoblock'
export default defineConfig({
  // 其他配置...
  markdown: {
    config: (md) => {
      md.use(demoblockPlugin)
    }
  },
  vite: {
    plugins: [demoblockVitePlugin()]
  }
})
2.2.3 自定义主题

通过配置 customClass 类名称,自定义 demoblock 样式

markdown: {
  config: (md) => {
    md.use(demoblockPlugin, {
      customClass: 'demoblock-custom'
    })
  }
}

2.3 使用示例

假设我们有一个简单的 组件示例:basic.md,内容如下:

<template>
  <RePageCard>
    <ReList :items="items" :metas="metas"></ReList>
  </RePageCard>

  <RePageCard>
    <ReList :items="items" :metas="metas1"></ReList>
  </RePageCard>

  <RePageCard>
    <ReList :items="items" :metas="metas2"></ReList>
  </RePageCard>
</template>

<script setup lang="ts">
import { UserFilled } from "@element-plus/icons-vue";
import { ref } from "vue";
const metas = ref({
  avatar: {},
  title: {},
  subTitle: {},
  description: {},
  content: {}
});
const metas1 = ref({
  title: {
    dataIndex: "title2"
  },
  description: {},
  content: {}
});
const metas2 = ref({
  avatar: {},
  title: {},
  content: {}
});

const items = ref([
  {
    id: 1,
    title: "Title1",
    title2: "Title2",
    subTitle: "Sub-title",
    description: "Description",
    content: "Content",
    avatar: UserFilled
  },
  {
    id: 2,
    title: "Title1",
    title2: "Title2",
    subTitle: "Sub-title1",
    description: "Description1",
    content: "Content1",
    avatar: UserFilled
  }
]);
</script>

在 Markdown 文件中引用该示例文件,使用:::demo语法:

## 基础

通过 `metas` 字段配置列表项展示内容。支持配置列表项内容对于的数据字段,自定义渲染,绑定事件,自定义样式类。

:::demo

<!--@include: ../demo/list/basic.md-->

:::

上述组件示例会在文档中展示:

在这里插入图片描述

此版本的demo组件基于对markdown的代码片段的解析(基于markdonw-it),然后直接进行示例内容的渲染实现示例的展示,所以需要对示例中使用的组件进行全局注册,否则会导致渲染异常。

解析组件有误,可能是 @ 别名设置问题,需要在 .vitepress/config.js 文件中修改 vite.resolve.alias 配置。

<think>嗯,用户问的是在pnpm workspaces中,是否必须执行`pnpm add @shared/utils@workspace:*`这一步,以及有没有其他替代方法。我需要先确认用户对pnpm workspace协议的理解程度,可能他们想知道是否有更简便的方式,或者是否必须显式添加依赖。 首先,用户之前的问题是关于如何在monorepo中跨项目引用公共模块,之前的回答已经介绍了使用workspace协议的方法。现在用户可能在实际操作中遇到了问题,或者想了解是否有其他途径,比如相对路径引用或者全局安装等。 我需要考虑几种可能性: 1. **必须执行添加依赖吗?**:是的,因为如果将公共包添加到项目的依赖中,项目构建时无法解析该模块。pnpm的workspace协议确保本地包被正确链接,而是从远程安装。 2. **替代方法有哪些?**:比如使用相对路径导入、修改模块解析配置(如Webpack别名)、或者使用file:协议。但这些方法各有缺点,比如相对路径导致结构混乱,file:协议需要手动维护版本。 然后,我需要详细解释每个替代方案的优缺点,帮助用户理解为什么workspace协议是推荐的做法。同时,要指出其他方法可能带来的问题,比如维护困难、版本一致等。 用户可能担心频繁添加依赖是否麻烦,或者是否有更自动化的方式。需要说明workspace协议的优势,比如自动同步、版本管理方便,以及符号链接的高效性。 另外,用户可能对pnpm的内部机制太熟悉,需要简单说明workspace协议如何工作,比如创建符号链接,确保项目依赖指向本地代码,而无需发布到npm。 最后,总结各个方法的适用场景,强调在monorepo中使用workspace协议的最佳实践,同时提供替代方案供用户根据具体情况选择。确保回答结构清晰,步骤明确,让用户能根据自身需求做出决策。</think>在 pnpm workspaces 中,`pnpm add @shared/utils@workspace:*` 是 **推荐的核心操作**,但并非绝对唯一方案。以下分层次解析该操作的必要性及替代方案: --- ### 一、为什么需要执行 `pnpm add @shared/utils@workspace:*`? 1. **核心作用**: - **依赖声明**:将 `@shared/utils` 包声明为 `project1` 的正式依赖项,确保构建工具(如 Webpack/Vite)能正确解析模块路径。 - **符号链接**:通过 `workspace:*` 协议,让 `project1/node_modules/@shared/utils` 直接软链接到本地 `public` 目录,避免复制文件或安装远程包。 2. **可省略的关键原因**: - **模块化规范要求**:Node.js 和现代构建工具默认通过 `node_modules` 解析依赖。若添加依赖声明,直接通过相对路径 `../../public/utils/setVal` 引用会破坏模块化规范,导致构建失败或路径混乱。 - **版本同步管理**:`workspace:*` 协议确保始终使用本地最新代码,而无需手动升级版本号。 --- ### 二、替代方案及对比分析 #### 方案 1:直接使用 `file:` 协议(推荐) ```bash # 在 project1 中手动指定路径 pnpm add ../public ``` - **原理**:生成 `package.json` 中依赖项为 `"@shared/utils": "file:../public"` - **缺点**: - **路径耦合**:目录结构变动会导致引用失效(如移动 `project1` 位置)。 - **版本更新需手动触发**:修改公共代码后需重新运行 `pnpm install` 或 `pnpm up`。 - **构建工具兼容性问题**:某些工具(如 Vite)可能会监听 `file:` 协议依赖的源码变化。 #### 方案 2:通过 **相对路径直接导入**(临时调试用) ```vue // 在 index.vue 中硬编码路径 import { setVal } from '../../../public/utils/setVal' ``` - **缺点**: - **跨项目可移植**:若 `project2` 也需引用,路径结构同会导致重复修改。 - **构建工具需额外配置**:需在 Webpack/Vite 中配置别名(alias)解析,否则可能报错。 - **违反 monorepo 设计原则**:破坏了 workspace 的封装性,代码维护难度增加。 #### 方案 3:全局安装公共包(仅限工具类) ```bash # 在 public 目录发布到私有 npm 仓库 cd public pnpm publish --registry your-private-npm # 在 project1 中安装 cd project1 pnpm add @shared/utils ``` - **适用场景**:公共代码需跨多个 monorepo 共享。 - **缺点**: - **失去实时性**:每次代码修改需重新发布和安装,无法直接使用本地最新代码。 - **增加维护成本**:需搭建私有 npm 仓库并管理版本。 --- ### 三、方案对比总结 | 方案 | 实时同步代码 | 路径解耦 | 版本管理 | 构建工具兼容性 | 适用场景 | |--------------------|------------|--------|--------|--------------|----------------------| | `workspace:*` | ✅ | ✅ | ✅ | ✅ | 标准 monorepo 开发 | | `file:` 协议 | ❌ | ❌ | ⚠️ | ⚠️ | 简单本地测试 | | 相对路径导入 | ✅ | ❌ | ❌ | ❌ | 临时调试 | | 发布到私有 npm | ❌ | ✅ | ✅ | ✅ | 跨 monorepo 共享代码 | --- ### 四、强制需要 `pnpm add` 的典型场景 1. **TypeScript 项目**:若未声明依赖,TS 类型检查会报错 `Cannot find module '@shared/utils'`。 2. **SSR 或静态构建**:服务端渲染(如 Nuxt)或静态生成(如 VitePress)必须通过 `node_modules` 解析依赖。 3. **依赖树完整性**:若其他包间接依赖 `@shared/utils`,未显式声明会导致依赖树断裂。 --- ### 五、最佳实践建议 1. **始终优先使用 `workspace:*` 协议**: ```bash # 添加依赖 pnpm add @shared/utils@workspace:* # 升级操作(修改 public 代码后) pnpm up @shared/utils@latest ``` 2. **仅在调试时使用临时方案**: - 在 `vite.config.ts` 中添加别名(alias)临时映射: ```ts export default defineConfig({ resolve: { alias: { '@shared': path.resolve(__dirname, '../public') } } }) ``` - 配合 `pnpm link ../public` 创建全局软链(需手动维护)。 --- ### 六、底层机制解析 当执行 `pnpm add @shared/utils@workspace:*` 时,pnpm 会: 1. 在 `project1/package.json` 中写入: ```json { "dependencies": { "@shared/utils": "workspace:*" } } ``` 2. 创建符号链接: ```bash project1/node_modules/@shared/utils -> ../../../public ``` 3. 确保构建工具将 `@shared/utils` 视为正规 npm 包,而非本地文件。 --- **结论**:虽然存在替代方案,但 `pnpm add @shared/utils@workspace:*` 是唯一符合 monorepo 设计理念、保证长期可维护性的标准化方法。其他方案仅建议在临时调试或特殊场景下使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iWangsd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值