]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): normalize windows paths when resolving types
authorEvan You <yyx990803@gmail.com>
Mon, 17 Apr 2023 12:59:03 +0000 (20:59 +0800)
committerEvan You <yyx990803@gmail.com>
Mon, 17 Apr 2023 13:11:22 +0000 (21:11 +0800)
packages/compiler-sfc/src/script/resolveType.ts
packages/compiler-sfc/src/script/utils.ts

index 8efa04579f8b7730449bec4b8046fe6422a0b930..247bac3a3be9ff50c27b43793e4ae1f9aa0def08 100644 (file)
@@ -25,7 +25,8 @@ import {
   UNKNOWN_TYPE,
   createGetCanonicalFileName,
   getId,
-  getImportedName
+  getImportedName,
+  normalizePath
 } from './utils'
 import { ScriptCompileContext, resolveParserPlugins } from './context'
 import { ImportBinding, SFCScriptCompileOptions } from '../compileScript'
@@ -34,7 +35,7 @@ import { parse as babelParse } from '@babel/parser'
 import { parse } from '../parse'
 import { createCache } from '../cache'
 import type TS from 'typescript'
-import { join, extname, dirname } from 'path'
+import path from 'path'
 
 /**
  * TypeResolveContext is compatible with ScriptCompileContext
@@ -577,8 +578,7 @@ function resolveGlobalScope(ctx: TypeResolveContext): TypeScope[] | undefined {
       throw new Error('[vue/compiler-sfc] globalTypeFiles requires fs access.')
     }
     return ctx.options.globalTypeFiles.map(file =>
-      // TODO: differentiate ambient vs non-ambient module
-      fileToScope(file, fs, ctx.options.babelParserPlugins, true)
+      fileToScope(normalizePath(file), fs, ctx.options.babelParserPlugins, true)
     )
   }
 }
@@ -616,7 +616,7 @@ function resolveTypeFromImport(
 
   if (source.startsWith('.')) {
     // relative import - fast path
-    const filename = join(containingFile, '..', source)
+    const filename = path.join(containingFile, '..', source)
     resolved = resolveExt(filename, fs)
   } else {
     // module or aliased import - use full TS resolution, only supported in Node
@@ -642,6 +642,8 @@ function resolveTypeFromImport(
   }
 
   if (resolved) {
+    resolved = normalizePath(resolved)
+
     // (hmr) register dependency file on ctx
     ;(ctx.deps || (ctx.deps = new Set())).add(resolved)
 
@@ -694,7 +696,8 @@ function resolveWithTS(
   let options: TS.CompilerOptions
   let cache: TS.ModuleResolutionCache | undefined
   if (configPath) {
-    const cached = tsConfigCache.get(configPath)
+    const normalizedConfigPath = normalizePath(configPath)
+    const cached = tsConfigCache.get(normalizedConfigPath)
     if (!cached) {
       // The only case where `fs` is NOT `ts.sys` is during tests.
       // parse config host requires an extra `readDirectory` method
@@ -709,7 +712,7 @@ function resolveWithTS(
       const parsed = ts.parseJsonConfigFileContent(
         ts.readConfigFile(configPath, fs.readFile).config,
         parseConfigHost,
-        dirname(configPath),
+        path.dirname(configPath),
         undefined,
         configPath
       )
@@ -719,7 +722,7 @@ function resolveWithTS(
         createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames),
         options
       )
-      tsConfigCache.set(configPath, { options, cache })
+      tsConfigCache.set(normalizedConfigPath, { options, cache })
     } else {
       ;({ options, cache } = cached)
     }
@@ -777,7 +780,7 @@ function parseFile(
   content: string,
   parserPlugins?: SFCScriptCompileOptions['babelParserPlugins']
 ): Statement[] {
-  const ext = extname(filename)
+  const ext = path.extname(filename)
   if (ext === '.ts' || ext === '.tsx') {
     return babelParse(content, {
       plugins: resolveParserPlugins(ext.slice(1), parserPlugins),
index 6d874f8a6db484d7ce604a8130ffa07b62c860c9..04df22a2b6456471ea40667880136aa67418fbcd 100644 (file)
@@ -8,6 +8,7 @@ import {
   Node,
   StringLiteral
 } from '@babel/types'
+import path from 'path'
 import { TS_NODE_TYPES } from '@vue/compiler-dom'
 
 export const UNKNOWN_TYPE = 'Unknown'
@@ -97,3 +98,10 @@ function toFileNameLowerCase(x: string) {
 export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean) {
   return useCaseSensitiveFileNames ? identity : toFileNameLowerCase
 }
+
+const windowsSlashRE = /\\/g
+export function normalizePath(p: string) {
+  // in the browser build, the polyfill doesn't expose posix, but defualts to
+  // posix behavior.
+  return (path.posix || path).normalize(p.replace(windowsSlashRE, '/'))
+}