From ef85a62856c777f085f6a54282b0e81bd4778807 Mon Sep 17 00:00:00 2001 From: Titian Cernicova-Dragomir Date: Tue, 26 Apr 2022 17:16:00 +0300 Subject: [PATCH] fix: cater for change in resolveTypeReferenceDirective API in 4.7 (#1446) * compile against 4.6.3 * any * prettier * fix: cater for change in resolveTypeReferenceDirective API in TypeScript 4.7 Signed-off-by: Titian Cernicova-Dragomir * Update CHANGELOG.md * Update package.json Co-authored-by: johnnyreilly --- .github/workflows/push.yml | 4 +-- CHANGELOG.md | 5 ++++ package.json | 4 +-- src/instances.ts | 4 ++- src/interfaces.ts | 42 +++++++++++++++++++---------- src/servicesHost.ts | 54 ++++++++++++++++++++++++++++---------- yarn.lock | 8 +++--- 7 files changed, 84 insertions(+), 37 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 2e2714222..236a059bc 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -49,7 +49,7 @@ jobs: strategy: matrix: node: [12, 14] - ts: [3.8.3, 3.9.3, 4.0.3, 4.1.5, next] + ts: [3.8.3, 3.9.3, 4.0.3, 4.1.5, 4.2.4, 4.3.2, 4.4.2, 4.5.2, next] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -76,7 +76,7 @@ jobs: strategy: matrix: node: [12, 14] - ts: [3.8.3, 3.9.3, 4.0.3, 4.1.5, next] + ts: [3.8.3, 3.9.3, 4.0.3, 4.1.5, 4.2.4, 4.3.2, 4.4.2, 4.5.2, next] runs-on: windows-latest steps: - uses: actions/checkout@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 810283ee5..9423097f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v8.4.0 + +* [fix: cater for change in resolveTypeReferenceDirective API in 4.7](https://github.com/TypeStrong/ts-loader/pull/1446) - thanks @dragomirtitian +* This is a backport from v9.2.7 for webpack 4 compatibility + ## v8.3.0 * [Fixed impossibility to have several instances of ts-loader with different compiler options](https://github.com/TypeStrong/ts-loader/issues/1316) - thanks @timocov diff --git a/package.json b/package.json index 4b00904bf..316d4c966 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ts-loader", - "version": "8.3.0", + "version": "8.4.0", "description": "TypeScript loader for webpack", "main": "index.js", "types": "dist", @@ -96,7 +96,7 @@ "mocha": "^6.0.0", "prettier": "^2.0.5", "rimraf": "^2.6.2", - "typescript": "^4.0.0", + "typescript": "^4.6.3", "webpack": "^4.5.0", "webpack-cli": "^3.1.1" }, diff --git a/src/instances.ts b/src/instances.ts index aaa36b792..914888edb 100644 --- a/src/instances.ts +++ b/src/instances.ts @@ -380,7 +380,9 @@ export function initializeInstance( customerTransformers = require(customerTransformers); } catch (err) { throw new Error( - `Failed to load customTransformers from "${instance.loaderOptions.getCustomTransformers}": ${err.message}` + `Failed to load customTransformers from "${ + instance.loaderOptions.getCustomTransformers + }": ${err instanceof Error ? err.message : ''}` ); } diff --git a/src/interfaces.ts b/src/interfaces.ts index 6fec20479..fa92ff2ce 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -198,6 +198,7 @@ interface PerModuleNameCache { result: typescript.ResolvedModuleWithFailedLookupLocations ): void; } + export interface ModuleResolutionCache extends typescript.ModuleResolutionCache { directoryToModuleNameMap: CacheWithRedirects< @@ -206,20 +207,8 @@ export interface ModuleResolutionCache moduleNameToDirectoryMap: CacheWithRedirects; clear(): void; update(compilerOptions: typescript.CompilerOptions): void; - getPackageJsonInfoCache?(): any; -} -// Until the API has been released and ts-loader is built against a version of TypeScript that contains it - see https://github.com/microsoft/TypeScript/blob/74993a2a64bb2e423b40204bb54ff749cdd4ef54/src/compiler/moduleNameResolver.ts#L458 -export interface TypeReferenceDirectiveResolutionCache { - getOrCreateCacheForDirectory( - directoryName: string, - redirectedReference?: typescript.ResolvedProjectReference - ): Map< - string, - typescript.ResolvedTypeReferenceDirectiveWithFailedLookupLocations - >; - clear(): void; - update(compilerOptions: typescript.CompilerOptions): void; } + export interface TSInstance { compiler: typeof typescript; compilerOptions: typescript.CompilerOptions; @@ -228,7 +217,7 @@ export interface TSInstance { loaderOptions: LoaderOptions; rootFileNames: Set; moduleResolutionCache?: ModuleResolutionCache; - typeReferenceResolutionCache?: TypeReferenceDirectiveResolutionCache; + typeReferenceResolutionCache?: typescript.TypeReferenceDirectiveResolutionCache; /** * a cache of all the files */ @@ -361,4 +350,29 @@ export interface ResolvedModule { isExternalLibraryImport?: boolean; } +export interface TSCommon { + // Changed in TS 4.7 + resolveTypeReferenceDirective( + typeReferenceDirectiveName: string, + containingFile: string | undefined, + options: typescript.CompilerOptions, + host: typescript.ModuleResolutionHost, + redirectedReference?: typescript.ResolvedProjectReference, + cache?: typescript.TypeReferenceDirectiveResolutionCache, + resolutionMode?: typescript.SourceFile['impliedNodeFormat'] + ): typescript.ResolvedTypeReferenceDirectiveWithFailedLookupLocations; +} + +/** + * Compiler APIs we use that are marked internal and not included in TypeScript's public API declarations + * @internal + */ +export interface TSInternal { + // Added in TS 4.7 + getModeForFileReference?: ( + ref: typescript.FileReference | string, + containingFileMode: typescript.SourceFile['impliedNodeFormat'] + ) => typescript.SourceFile['impliedNodeFormat']; +} + export type Severity = 'error' | 'warning'; diff --git a/src/servicesHost.ts b/src/servicesHost.ts index 3125bc7a0..7bf012b68 100644 --- a/src/servicesHost.ts +++ b/src/servicesHost.ts @@ -17,7 +17,9 @@ import { ServiceHostWhichMayBeCacheable, SolutionBuilderWithWatchHost, SolutionDiagnostics, + TSCommon, TSInstance, + TSInternal, WatchCallbacks, WatchFactory, WatchHost, @@ -289,16 +291,20 @@ function makeResolvers( ); const resolveTypeReferenceDirectives = ( - typeDirectiveNames: string[], + typeDirectiveNames: string[] | readonly typescript.FileReference[], containingFile: string, - redirectedReference?: typescript.ResolvedProjectReference + redirectedReference: typescript.ResolvedProjectReference | undefined, + options: typescript.CompilerOptions, + containingFileMode?: typescript.SourceFile['impliedNodeFormat'] | undefined // new impliedNodeFormat is accepted by compilerHost ): (typescript.ResolvedTypeReferenceDirective | undefined)[] => typeDirectiveNames.map( directive => resolveTypeReferenceDirective( directive, containingFile, - redirectedReference + options, + redirectedReference, + containingFileMode ).resolvedTypeReferenceDirective ); @@ -1156,9 +1162,11 @@ export function getSolutionErrors(instance: TSInstance, context: string) { } type ResolveTypeReferenceDirective = ( - directive: string, + directive: string | typescript.FileReference, containingFile: string, - redirectedReference?: typescript.ResolvedProjectReference + options: typescript.CompilerOptions, + redirectedReference?: typescript.ResolvedProjectReference, + containingFileMode?: typescript.SourceFile['impliedNodeFormat'] | undefined // new impliedNodeFormat is accepted by compilerHost ) => typescript.ResolvedTypeReferenceDirectiveWithFailedLookupLocations; function makeResolveTypeReferenceDirective( @@ -1173,31 +1181,49 @@ function makeResolveTypeReferenceDirective( if (customResolveTypeReferenceDirective === undefined) { // Until the api is published if ( - (compiler as any).createTypeReferenceDirectiveResolutionCache && + compiler.createTypeReferenceDirectiveResolutionCache !== undefined && !instance.typeReferenceResolutionCache ) { - instance.typeReferenceResolutionCache = (compiler as any).createTypeReferenceDirectiveResolutionCache( + instance.typeReferenceResolutionCache = compiler.createTypeReferenceDirectiveResolutionCache( moduleResolutionHost.getCurrentDirectory!(), createGetCanonicalFileName(instance), instance.compilerOptions, instance.moduleResolutionCache?.getPackageJsonInfoCache?.() ); } - return (directive, containingFile, redirectedReference) => - // Until the api is published - (compiler.resolveTypeReferenceDirective as any)( - directive, + return ( + typeDirectiveName, + containingFile, + options, + redirectedReference, + containingFileMode + ) => { + // Copy-pasted from https://github.com/TypeStrong/ts-node/blob/9f789d0d91c6eba30ac7f7aad45194a23b44f159/src/resolver-functions.ts#L139 + const nameIsString = typeof typeDirectiveName === 'string'; + const mode = nameIsString + ? undefined + : ((compiler as any) as TSInternal).getModeForFileReference!( + typeDirectiveName, + containingFileMode + ); + const strName = nameIsString + ? typeDirectiveName + : typeDirectiveName.fileName.toLowerCase(); + return ((compiler as any) as TSCommon).resolveTypeReferenceDirective( + strName, containingFile, - compilerOptions, + options, moduleResolutionHost, redirectedReference, - instance.typeReferenceResolutionCache + undefined, + mode ); + }; } return (directive, containingFile) => customResolveTypeReferenceDirective( - directive, + directive as string, // unsure whether we should evolve this further containingFile, compilerOptions, moduleResolutionHost, diff --git a/yarn.lock b/yarn.lock index ea6e337a9..f078dd007 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6267,10 +6267,10 @@ typedarray@^0.0.6: resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.2.tgz#6369ef22516fe5e10304aae5a5c4862db55380e9" - integrity sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ== +typescript@^4.6.3: + version "4.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" + integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== uglify-js@3.3.x: version "3.3.9"