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

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

相关推荐
运维@小兵4 分钟前
vue访问后端接口,实现用户注册
前端·javascript·vue.js
雨汨7 分钟前
web:InfiniteScroll 无限滚动
前端·javascript·vue.js
小盐巴小严30 分钟前
正则表达式
javascript·正则表达式
Samuel-Gyx1 小时前
前端 CSS 样式书写与选择器 基础知识
前端·css
天天打码1 小时前
Rspack:字节跳动自研 Web 构建工具-基于 Rust打造高性能前端工具链
开发语言·前端·javascript·rust·开源
AA-代码批发V哥1 小时前
正则表达式: 从基础到进阶的语法指南
java·开发语言·javascript·python·正则表达式
字节高级特工1 小时前
【C++】”如虎添翼“:模板初阶
java·c语言·前端·javascript·c++·学习·算法
小冻梨!!!2 小时前
Spark,在shell中运行RDD程序
大数据·javascript·spark
大猫会长2 小时前
lenis滑动插件的笔记
javascript
db_lnn_20212 小时前
【vue】全局组件及组件模块抽离
前端·javascript·vue.js