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文件做处理。

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

相关推荐
Zuckjet_6 小时前
开启 3D 之旅 - 你的第一个 WebGL 三角形
前端·javascript·3d·webgl
2401_863801466 小时前
探索 12 种 3D 文件格式:综合指南
前端·3d
珍宝商店7 小时前
前端老旧项目全面性能优化指南与面试攻略
前端·面试·性能优化
bitbitDown7 小时前
四年前端分享给你的高效开发工具库
前端·javascript·vue.js
YAY_tyy7 小时前
【JavaScript 性能优化实战】第六篇:性能监控与自动化优化
javascript·性能优化·自动化
gnip8 小时前
实现AI对话光标跟随效果
前端·javascript
脑花儿9 小时前
ABAP SMW0下载Excel模板并填充&&剪切板方式粘贴
java·前端·数据库
闭着眼睛学算法9 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
烛阴10 小时前
【TS 设计模式完全指南】构建你的专属“通知中心”:深入观察者模式
javascript·设计模式·typescript
lumi.10 小时前
Vue.js 从入门到实践1:环境搭建、数据绑定与条件渲染
前端·javascript·vue.js