0 按
前几天的 vueconf2021 尤大提到了 vuepress 和 vitepress 的未来发展计划。大意提到对 vuepress 的规划还是长期支持。至于构建和打包,除了 webpack 常规支持,还会对 vite 提供支持。
今天一撇 vuepress-next ,果然有了 vite 的身影。这里尝试浅析 vuepress-next 也就是 vuepress2 的源码仓库。后续统一称为 vuepress2 。
注意:截至2021-06-07,vuepress2 的版本是 2.0.0-beta.17 ,随着时间发展,部分信息可能会发生变化,请注意甄别。
1 准备工作
克隆 - 删除文件夹和依赖 - 安装依赖 - 尝试运行 - 观察目录
克隆
找到仓库准备克隆。
git@github.com:vuepress/vuepress-next.git
删除文件夹
克隆下来,删除无关内容,让视觉更清爽:
没有明显的 e2e 等大包,略过。
安装依赖和运行
- 直接
tyarn - 运行
tyarn dev有输出,无报错
观察目录
第一步先看 package.json ,能够看到有价值的信息:
- 采用 lerna + yarn workspaces 的代码组织模式
- 启动命令,yarn dev
- 依赖
- anywhere
- cpx2
- rimraf
- sort-package-json
看下 packages 结构:
@vuepress- bundler-vite
- bundler-webpack
- cli
- client
- core
- markdown
- plugin-active-header-links
- plugin-back-top-top
- …省略很多 plugin-* 的官方插件
- shared
- theme-default
- theme-vue
- utils
- vuepress
- vuepress-vite
刚才提到 vuepress2 增加了对 vite 的支持,因为有两个包:
vuepress默认使用 webpack,配合@vuepress/webpack作为打包配置- vuepress-vite 使用 vite,配合
@vuepress/vite作为打包配置
有了上述信息可以明确,有 webpack 和 vite 两条明线。
通过阅读文档 深入 - 架构 - 概览 https://vuepress2.netlify.app/zh/advanced/architecture.html#%E6%A6%82%E8%A7%88
阅读下图,了解架构:
大致运行流程:
- 运行
vuepress app,左上角 - 首先进入
init初始化阶段 - 进入
prepare准备阶段,因为本质上是对 vue app 工程的封装,所以会先生成临时文件,到右上角。包括生成布局、页面、路由、组件等开发信息。可以理解为 vuepress 项目转 vue app 项目 - 有了临时文件,根据启动命令的不同,氛围 dev开发和build构建
- dev开发命令,通过node启动 dev server 开发服务器,根据上一层得到的临时文件进行渲染
- build构建命令,会通过node启动ssr,进行打包生成可供浏览器运行的项目资源。
具体到每个阶段,有一些核心的路程和hooks钩子。核心流程与 Hooks
上图展示了 VuePress 的核心流程以及 插件 API 的 Hooks :
在 init 阶段:
主题和插件会被加载。这意味着插件需要在初始化之前使用。
由于我们要使用 markdown-it 来解析 Markdown 文件,因此 extendsMarkdown 会在加载页面文件之前调用。
页面文件会被加载,因此 extendsPageOptions Hook 会被调用,用以创建页面。
在 prepare 阶段:
- 临时文件会被生成,因此所有和客户端文件相关的 Hooks 会在此处调用。
在 dev / build 阶段:
- Bundler 会被加载。由于 alias 和 define 依赖于 Bundler 的配置,所以它们会在此处调用。
这里先忽略。
2 源码阅读
我们把握两条明线串起来源码:
- vuepress + vuepress/webpack
- vuepress-vite + vuepress/vite 本次核心,精读。
- cli 入口,粗读
plugin-*的官方插件选读markdown和 theme 部分粗读
2.1 @vuepress/cli
依赖:
@vuepress/core@vuepress/utils- 命令行工具
cacchokidar - 其他依赖
envinfoesbuild
通过阅读 bin/vuepress.js 可以知道引用了 lib/index.js ,而后者通过阅读 tsconfig.build.json 得知是 src 作为入口。(正确的废话)
未完待续。
后续,debugger 跑。
上图展示了 VuePress 的核心流程以及 插件 API 的 Hooks :