架构

概览

上图展示了 VuePress 的简要架构:

  • Node App 会生成临时文件,包括页面、路由等。
  • Bundler 会将 Client App 和临时文件一起进行打包,就像处理一个普通的 Vue App 一样。

作为开发者,你必须要意识到 VuePress 分为两个主要部分: Node App 和 Client App ,这一点对于开发插件和主题来说都十分重要。

  • 插件或者主题的入口文件会在 Node App 中被加载。
  • 客户端文件会在 Client App 中被加载,也就是会被 Bundler 处理。比如组件、客户端配置文件等。

核心流程与 Hooks

上图展示了 VuePress 的核心流程以及 插件 API 的 Hooks :

  • 在 init 阶段:
    • 主题和插件会被加载。这意味着插件需要在初始化之前使用。
    • 由于我们要使用 markdown-it 来解析 Markdown 文件,因此需要在加载页面文件之前创建 markdown-it 实例:
    • 页面文件会被加载:
  • 在 prepare 阶段:
    • 临时文件会被生成,因此所有和客户端文件相关的 Hooks 会在此处调用。
  • 在 dev / build 阶段:
    • Bundler 会被加载:
      • extendsBundlerOptions Hook 会被调用,用以生成 Bundler 的配置。
      • alias Hook 和 define Hook 会被用在 Bundler 的配置中,所以它们会在此处调用。

开发插件

extendsBundlerOptions

  extendsBundlerOptions(bundlerOptions, app) {
	// 修改 @vuepress/bundler-vite 的配置项
	if (app.options.bundler.name === '@vuepress/bundler-vite') {
	  bundlerOptions.viteOptions.build.target ??= "es2020"
	}
	console.log("bundlerOptions", bundlerOptions);
  },

常用插件

常见问题

ERROR: Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides): 顶级作用域无法使用await

```js

export default defineConfig({ enter code here`plugins: [vue()], build:{ target: “esnext” // or “es2019”, } }


-  [Vite refuses to use the correct build target in my Svelte / TS project](https://stackoverflow.com/questions/76616620/vite-refuses-to-use-the-correct-build-target-in-my-svelte-ts-project)
- [(建议收藏) 深入了解 Top-level await](https://juejin.cn/post/7358737951025283084#heading-20)
- [[如何在setup中使用async await]]

## 扩展阅读

- [从零实现一个 VuePress 插件](https://github.com/mqyqingfeng/Blog/issues/250)
- [vuepress 插件原理 以及 如何实现一个博客访问验证插件](https://juejin.cn/post/7008594000122740744)
- [VuePress插件开发](http://ranxin.cc/web/01-vuepress-kai-fa-cha-jian.html)
- [[Vite]]
- [ VuePress源码阅读(二)--dev和build的执行流程分析](https://juejin.cn/post/6918015439922528269)