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

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

相关推荐
霍理迪2 小时前
CSS——背景样式以及雪碧图、渐变
前端·css
火星牛3 小时前
AI IDE试用(一)
javascript·ide
jump_jump5 小时前
基于 Squoosh WASM 的浏览器端图片转换库
前端·javascript·性能优化
小二·8 小时前
前端监控体系完全指南:从错误捕获到用户行为分析(Vue 3 + Sentry + Web Vitals)
前端·vue.js·sentry
阿珊和她的猫9 小时前
IIFE:JavaScript 中的立即调用函数表达式
开发语言·javascript·状态模式
阿珊和她的猫9 小时前
`require` 与 `import` 的区别剖析
前端·webpack
+VX:Fegn089510 小时前
计算机毕业设计|基于springboot + vue在线音乐播放系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
智商偏低10 小时前
JSEncrypt
javascript
谎言西西里10 小时前
零基础 Coze + 前端 Vue3 边玩边开发:宠物冰球运动员生成器
前端·coze
+VX:Fegn089510 小时前
计算机毕业设计|基于springboot + vue律师咨询系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计