跨项目引用的别名解析(三)

72 阅读1分钟

上一篇 抽离eslint+stylelint+prettier+ts+lint-staged+release-it的配置(二) - 掘金 (juejin.cn)

在一个monorepo项目中如果某个项目用到了另一个项目的代码。但是存在别名解析的问题。 比方说前端react项目中使用到了后台项目的中的某些方法。然后两个项目都把src当做别名解析。当你只在vite的别名解析中匹配src的是不行的。需要在vite插件中配置别名解析。

import { log } from 'console'
import fs from 'fs'
import * as path from 'node:path'

// 获取当前请求文件所在app路径的函数
const getAppPath = async (dir, appPath) => {
  const testPath = path.join(dir, 'tsconfig.json')
  const hasTsConfig = fs.existsSync(testPath)
  if (hasTsConfig) {
    return dir
  } else if (dir === path.parse(dir).root) {
    return appPath ?? ''
  } else {
    const pDir = path.resolve(dir, '..')
    return getAppPath(pDir, appPath)
  }
}

// 检查文件是否存在并支持多个扩展名
const checkFileExists = (basePath) => {
  const extensions = ['.ts', '.js', '.tsx', '.jsx']
  for (const ext of extensions) {
    const fullPath = `${basePath}${ext}`
    if (fs.existsSync(fullPath)) {
      return fullPath
    }
  }
  return null
}

// Vite 插件
const resolveSrcAliasPlugin = ({ appPath }) => {
  return {
    name: 'vite-plugin-resolve-src-alias',
    async resolveId(source, importer) {
      // console.log(source,importer)
      if (!source || !importer) {
        return null
      }
      try {
        // 请求的路径
        const requestPath = path.normalize(source)

        // if(requestPath.endsWith('.vanilla.js')){
        //
        //   return  requestPath
        //
        // }
        console.log('requestPath', requestPath)
        const requestDir = path.dirname(importer)
        // 解析请求路径
        const requestPathParts = requestPath.split(path.sep)
        const srcIndex = requestPathParts.indexOf('src')

        if (srcIndex !== -1) {
          const relativeRequestPath = requestPathParts.slice(srcIndex).join(path.sep)

          const appDir = await getAppPath(requestDir, appPath)

          const newPath = path.join(appDir, relativeRequestPath)
          console.log(newPath, 'newPath')

          // if (newPath.endsWith(".vanilla.js")) {
          //   return newPath;
          // }

          const resolvedPath = checkFileExists(newPath)
          if (resolvedPath) {
            return resolvedPath
          }
        }
      } catch (error) {
        console.error('Error in resolveSrcAliasPlugin:', error)
      }

      return null // 继续使用默认的解析
    },
  }
}

export default resolveSrcAliasPlugin

这个插件的作用是如果不同的项目都用到了src这个别名解析,那么非vite项目会找到他自己项目本身的tsconfig配置文件所在的目录,这样不会导致别名解析错误。具体代码位置

liuchengjin-monorepo/config/vite-config/src/react/plugins/resolveSrcAliasPlugin.ts at main · badlym/liuchengjin-monorepo (github.com)