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
- 命令行工具
cac
chokidar
- 其他依赖
envinfo
esbuild
通过阅读 bin/vuepress.js
可以知道引用了 lib/index.js
,而后者通过阅读 tsconfig.build.json
得知是 src
作为入口。(正确的废话)
未完待续。
后续,debugger 跑。