vitePress实现原理(四)

2.resolveAliases函数

源码位置:src/node/alias.ts

typescript 复制代码
import { createRequire } from 'module'
import { resolve, join } from 'path'
import { fileURLToPath } from 'url'
import type { Alias, AliasOptions } from 'vite'
import type { SiteConfig } from './config'

const require = createRequire(import.meta.url)
const PKG_ROOT = resolve(fileURLToPath(import.meta.url), '../..')

export const DIST_CLIENT_PATH = resolve(PKG_ROOT, 'client')
export const APP_PATH = join(DIST_CLIENT_PATH, 'app')
export const SHARED_PATH = join(DIST_CLIENT_PATH, 'shared')
export const DEFAULT_THEME_PATH = join(DIST_CLIENT_PATH, 'theme-default')

// 特殊虚拟文件。我们不能直接导入 '/@siteData' 因为:
// - 它不是一个实际文件,所以无法使用 tsconfig 路径重定向它
// - TypeScript 不允许对以 '/' 开头的模块进行 shimming
export const SITE_DATA_ID = '@siteData'
export const SITE_DATA_REQUEST_PATH = '/' + SITE_DATA_ID

const vueRuntimePath = 'vue/dist/vue.runtime.esm-bundler.js'

export function resolveAliases(
  { root, themeDir }: SiteConfig,
  ssr: boolean
): AliasOptions {
  const paths: Record<string, string> = {
    '@theme': themeDir,
    [SITE_DATA_ID]: SITE_DATA_REQUEST_PATH
  }

  const aliases: Alias[] = [
    ...Object.keys(paths).map((p) => ({
      find: p,
      replacement: paths[p]
    })),
    {
      find: /^vitepress$/,
      replacement: join(DIST_CLIENT_PATH, '/index.js')
    },
    {
      find: /^vitepress\/theme$/,
      replacement: join(DIST_CLIENT_PATH, '/theme-default/index.js')
    },
    {
      find: /^vue-demi$/,
      replacement: require.resolve('vitepress/vue-demi')
    }
  ]

  if (!ssr) {
    // 在非 SSR 构建时,优先使用项目根目录下的 vue,如果找不到则回退到 vitepress 自带的 vue。
    // 这样做的原因是,在 SSR 构建期间,`vue` 需要被外部化处理
    let vuePath
    try {
      vuePath = require.resolve(vueRuntimePath, { paths: [root] })
    } catch (e) {
      vuePath = require.resolve(vueRuntimePath)
    }
    aliases.push({
      find: /^vue$/,
      replacement: vuePath
    })
  }

  return aliases
}
  1. 路径解析工具 :
    • 使用 createRequire 创建一个 CommonJS 的 require 函数,以便在 ES 模块环境中使用 CommonJS 的模块加载机制。
    • 使用 resolvejoin 方法来拼接和解析路径。
    • 使用 fileURLToPath 将文件 URL 转换为文件系统路径。
  2. 路径常量定义 :
    • PKG_ROOT: 包的根目录路径。
    • DIST_CLIENT_PATH: 客户端代码的输出目录。
    • APP_PATH: 应用程序代码的输出目录。
    • SHARED_PATH: 共享代码的输出目录。
    • DEFAULT_THEME_PATH: 默认主题的输出目录。
  3. 特殊路径处理 :
    • SITE_DATA_ID: 特殊虚拟文件 ID。
    • SITE_DATA_REQUEST_PATH: 特殊虚拟文件的实际请求路径。
  4. 路径别名配置 :
    • paths: 存储路径别名的映射关系。
    • aliases: 存储最终的路径别名配置数组。
  5. 路径别名生成 :
    • 遍历 paths 对象,生成基本的路径别名。
    • 添加其他特定的路径别名,如 vitepress, vitepress/theme, 和 vue-demi
    • 在非 SSR 构建时,优先查找项目根目录下的 vue 模块,并将其添加到路径别名配置中。

到这里,整个项目启动流程就结束了。本质其实就是搭建一个vite静态服务器,针对所有html文件做拦截,进行二次封装。通过读取.vitepress/config.ts配置转化基本vitepress配置等等,创建markdown插件扩展markdown文档能力。创建vitepress插件对md文件和vue文件做处理。

大家这时肯定好奇,怎么没有路由呢?下期揭晓...

相关推荐
玄魂几秒前
基于Vue框架的开源大屏项目实践
前端·开源·数据可视化
晴殇i2 分钟前
一行代码解决跨域问题,JavaScript新特性解析
前端
挖稀泥的工人5 分钟前
面试看这一篇webpack
前端·webpack
卖报的小行家_7 分钟前
Vue3源码,拦截对象,对比Vue2
前端
蒜香拿铁10 分钟前
vue3自动导入组合式api
前端·javascript
日升10 分钟前
Chrome 134 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器
Mike_jia11 分钟前
一篇文章带你了解一款强大的本地镜像库系统---Harbor
前端
_一条咸鱼_12 分钟前
Vue 框架组件模块之弹窗组件深度剖析(四)
前端
frontDeveloper12 分钟前
JavaScript基础知识概览(DOM-API部分)
javascript
某哈压力大13 分钟前
制作一个简单的水印组件
前端·vue.js