UNPKG

vite-jsconfig-paths

Version:

Vite resolver for JavaScript compilerOptions.paths

8 lines (7 loc) 12.6 kB
{ "version": 3, "sources": ["../src/path.ts", "../src/index.ts", "../src/config.ts"], "sourcesContent": ["import * as os from 'os'\nimport * as path from 'path'\nimport { normalizePath } from 'vite'\n\nconst isWindows = os.platform() === 'win32'\n\nexport const resolve = isWindows\n ? (...paths: string[]) => normalizePath(path.win32.resolve(...paths))\n : path.posix.resolve\n\nexport const isAbsolute = isWindows\n ? path.win32.isAbsolute\n : path.posix.isAbsolute\n\n/** Only call this on normalized paths */\nexport const join = path.posix.join\n\n/** Only call this on normalized paths */\nexport const relative = path.posix.relative\n\nexport { dirname } from 'path'\n", "import { dirname, isAbsolute, join, relative, resolve } from './path'\nimport { normalizePath, Plugin } from 'vite'\nimport { createMatchPathAsync } from 'tsconfig-paths'\nimport { crawl } from 'recrawl-sync'\nimport globRex from 'globrex'\nimport { PluginOptions } from './types'\nimport { loadConfig } from './config'\n\nimport _debug from 'debug'\nconst debug = _debug('vite-jsconfig-paths')\n\ntype ViteResolve = (id: string, importer: string) => Promise<string | undefined>\n\ntype Resolver = (\n viteResolve: ViteResolve,\n id: string,\n importer: string\n) => Promise<string | undefined>\n\nexport default (opts: PluginOptions = {}): Plugin => {\n let resolvers: Resolver[]\n\n return {\n name: 'vite:tsconfig-paths',\n enforce: 'pre',\n configResolved(config) {\n const projects = findProjects(config.root, opts)\n const extensions = getFileExtensions(opts.extensions)\n\n debug('options:', { projects, extensions })\n\n resolvers = projects\n .map((project) => createResolver(project, extensions))\n .filter(Boolean) as Resolver[]\n },\n async resolveId(id, importer) {\n if (importer && !relativeImportRE.test(id) && !isAbsolute(id)) {\n const viteResolve: ViteResolve = async (id, importer) =>\n (await this.resolve(id, importer, { skipSelf: true }))?.id\n\n for (const resolve of resolvers) {\n const resolved = await resolve(viteResolve, id, importer)\n if (resolved) {\n return resolved\n }\n }\n }\n },\n }\n\n function createResolver(root: string, extensions: string[]): Resolver | null {\n const configPath = root.endsWith('.json') ? root : null\n if (configPath) root = dirname(root)\n root += '/'\n\n const config = loadConfig(configPath || root)\n if (!config) {\n debug(`[!] config not found: \"${configPath || root}\"`)\n return null\n }\n const { baseUrl, paths } = config\n if (!baseUrl && !paths) {\n debug(`[!] missing baseUrl and paths: \"${config.configPath}\"`)\n return null\n }\n\n debug('config loaded:', config)\n\n const resolveWithBaseUrl: Resolver | undefined = baseUrl\n ? (viteResolve, id, importer) => viteResolve(join(baseUrl, id), importer)\n : undefined\n\n let resolveId: Resolver\n if (paths) {\n const matchPath = createMatchPathAsync(baseUrl ?? root, paths, mainFields)\n const resolveWithPaths: Resolver = (viteResolve, id, importer) =>\n new Promise((done) => {\n matchPath(id, void 0, void 0, extensions, (error, path) => {\n if (path) {\n path = normalizePath(path)\n done(viteResolve(path, importer))\n } else {\n error && debug(error.message)\n done(void 0)\n }\n })\n })\n\n if (resolveWithBaseUrl) {\n resolveId = (viteResolve, id, importer) =>\n resolveWithPaths(viteResolve, id, importer).then((resolved) => {\n return resolved ?? resolveWithBaseUrl(viteResolve, id, importer)\n })\n } else {\n resolveId = resolveWithPaths\n }\n } else {\n resolveId = resolveWithBaseUrl!\n }\n\n const isIncluded = getIncluder(config)\n\n const resolved = new Map<string, string>()\n return async (viteResolve, id, importer) => {\n // Skip virtual modules.\n if (id.includes('\\0')) return\n\n importer = normalizePath(importer)\n const importerFile = importer.replace(/[#?].+$/, '')\n\n // Respect the include/exclude properties.\n if (!isIncluded(relative(root, importerFile))) return\n\n // Find and remove Vite's suffix (e.g. \"?url\") if present.\n // If the path is resolved, the suffix will be added back.\n const suffix = /\\?.+$/.exec(id)?.[0]\n if (suffix) {\n id = id.slice(0, -suffix.length)\n }\n\n let path = resolved.get(id)\n if (!path) {\n path = await resolveId(viteResolve, id, importer)\n if (path) {\n resolved.set(id, path)\n debug(`resolved:`, {\n id,\n importer,\n resolvedId: path,\n configPath: config.configPath,\n })\n }\n }\n return path && suffix ? path + suffix : path\n }\n }\n}\n\nconst relativeImportRE = /^\\.\\.?(\\/|$)/\nconst mainFields = ['module', 'jsnext', 'jsnext:main', 'browser', 'main']\nconst defaultInclude = ['**/*']\nconst defaultExclude = ['node_modules', 'bower_components', 'jspm_packages']\n\nfunction compileGlob(glob: string) {\n if (!relativeImportRE.test(glob)) {\n glob = './' + glob\n }\n if (!glob.split('/').pop()!.includes('*')) {\n glob += '/**'\n }\n return globRex(glob, {\n extended: true,\n globstar: true,\n }).regex\n}\n\n/**\n * The returned function does not support absolute paths.\n * Be sure to call `path.relative` on your path first.\n */\nfunction getIncluder({\n include = defaultInclude,\n exclude = defaultExclude,\n outDir,\n}: {\n include?: string[]\n exclude?: string[]\n outDir?: string\n}) {\n if (outDir) {\n exclude = exclude.concat(outDir)\n }\n if (include.length || exclude.length) {\n const included = include.map(compileGlob)\n const excluded = exclude.map(compileGlob)\n debug(`compiled globs:`, { included, excluded })\n return (path: string) => {\n path = path.replace(/\\?.+$/, '')\n if (!relativeImportRE.test(path)) {\n path = './' + path\n }\n const test = (glob: RegExp) => glob.test(path)\n return included.some(test) && !excluded.some(test)\n }\n }\n return () => true\n}\n\nfunction findProjects(viteRoot: string, opts: PluginOptions) {\n const root = opts.root\n ? resolve(viteRoot, normalizePath(opts.root))\n : viteRoot\n\n let { projects } = opts\n if (!projects) {\n debug(`crawling \"${root}\"`)\n projects = crawl(root, {\n only: ['jsconfig.json'],\n skip: ['node_modules', '.git'],\n })\n }\n\n // Calculate the depth of each project path.\n const depthMap: { [path: string]: number } = {}\n projects = projects.map((projectPath) => {\n projectPath = resolve(root, normalizePath(projectPath))\n depthMap[projectPath] =\n projectPath.split('/').length - (projectPath.endsWith('.json') ? 1 : 0)\n return projectPath\n })\n\n // Ensure deeper projects take precedence.\n return projects.sort((a, b) => depthMap[b] - depthMap[a])\n}\n\nfunction getFileExtensions(exts?: string[]) {\n const requiredExts = ['.ts', '.tsx', '.js', '.jsx', '.mjs']\n return exts ? exts.concat(requiredExts) : requiredExts\n}\n", "import {\n loadTsconfig,\n walkForTsConfig,\n} from 'tsconfig-paths/lib/tsconfig-loader.js'\nimport { normalizePath } from 'vite'\nimport { resolve } from 'path'\nimport { statSync } from 'fs'\nimport { TSConfig } from './types'\n\nexport interface Config {\n configPath: string\n include?: string[]\n exclude?: string[]\n allowJs?: boolean\n baseUrl?: string\n paths?: { [path: string]: string[] }\n outDir?: string\n}\n\nexport function loadConfig(cwd: string): Config | undefined {\n const configPath = resolveConfigPath(cwd)\n if (configPath) {\n const config = loadTsconfig(configPath) as TSConfig\n const {\n compilerOptions: { baseUrl, paths, outDir } = {},\n } = config\n\n return {\n configPath: normalizePath(configPath),\n include: config.include,\n exclude: config.exclude,\n baseUrl: baseUrl && normalizePath(resolve(configPath, '..', baseUrl)),\n paths,\n outDir,\n }\n }\n}\n\n// Adapted from https://github.com/dividab/tsconfig-paths/blob/0b259d4cf6cffbc03ad362cfc6bb129d040375b7/src/tsconfig-loader.ts#L65\nfunction resolveConfigPath(cwd: string) {\n if (statSync(cwd).isFile()) {\n return cwd\n }\n const configPath = walkForTsConfig(cwd)\n if (configPath) {\n return configPath\n }\n}\n"], "mappings": "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", "names": [] }