routes 关联 pages 解析
routes 和 pages 的生成是由 internal-router 生成的
internal-router 核心代码
module.exports = (options, ctx) => ({
name: "@vuepress/internal-routes",
// @internal/routes
async clientDynamicModules() {
const code = importCode(ctx.globalLayout) + routesCode(ctx.pages);
console.log("code: " + code);
return { name: "routes.js", content: code, dirname: "internal" };
}
});
这里的 ctx.pages 就是 resolvePages 解析的所有 pages; clientDynamicModules 做的就是生成客户端的依赖文件。
下面是这个项目输出的 code, 也就是在.temp 下面的 routes.js
// 输出
import { injectComponentOption, ensureAsyncComponentsLoaded } from "@app/util";
import rootMixins from "@internal/root-mixins";
import GlobalLayout from "/Users/xiangxiao/Documents/work/workspace/vuepress-analysis/node_modules/@vuepress/core/lib/client/components/GlobalLayout.vue";
injectComponentOption(GlobalLayout, "mixins", rootMixins);
export const routes = [
{
name: "v-9d2814e2",
path: "/",
component: GlobalLayout,
beforeEnter: (to, from, next) => {
ensureAsyncComponentsLoaded("Layout", "v-9d2814e2").then(next);
}
},
{
path: "/index.html",
redirect: "/"
},
{
name: "v-02aefb2c",
path: "/main/webpack/webpackconfig.html",
component: GlobalLayout,
beforeEnter: (to, from, next) => {
ensureAsyncComponentsLoaded("Layout", "v-02aefb2c").then(next);
}
},
...,
{
path: "*",
component: GlobalLayout
}
];
还有一个就是对应 pages 的 internal-page-comonents
, 也是在.temp 文件件下面。
其实生成这个文件就一目了然整个项目的结构了
中间没有什么华丽的操作,运用了 2 个方法 injectComponentOption
和 ensureAsyncComponentsLoaded
, 让整个 router 赋予了灵魂
/**
* Generated by "@vuepress/internal-page-components"
*/
export default {
"v-9d2814e2": () => import("/Users/xiangxiao/Documents/work/workspace/vuepress-analysis/docs/README.md"),
...
"v-5be8b2fc": () => import("/Users/xiangxiao/Documents/work/workspace/vuepress-analysis/docs/plugin/pluginAPI.md"),
"v-02aefb2c": () => import("/Users/xiangxiao/Documents/work/workspace/vuepress-analysis/docs/main/webpack/webpackconfig.md")
}
internal-page-comonents
将 name 的 key 值和 routes.js
的对应起来继而实现了 router 和页面的对应关系并加载在最终挂在到 vue 实例中。
client/app.js
import { routes } from "@internal/routes";
const routerBase = typeof window !== 'undefined'
? window.__VUEPRESS_ROUTER_BASE__
: (siteData.routerBase || siteData.base)
const router = new Router({
base: routerBase,
mode: 'history',
fallback: false,
routes,
...
})
项目中把 routerBase 的配置也写在一个静态的 temp 里面
总结
这里是搭建 vuepress 网站地图的中心,将地图拆解成部分碎片并分布到 temp 文件中。设计的理念还是将非配置类需要的文件给抽离出来,并根据 config 和 router 去生产相应的代码,中间还夹杂了 global 控件,和将 theme 的相关控件也集成到里面