Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: cater for change in resolveTypeReferenceDirective API in 4.7 #1446

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/push.yml
Expand Up @@ -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
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions 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
Expand Down
4 changes: 2 additions & 2 deletions 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",
Expand Down Expand Up @@ -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"
},
Expand Down
4 changes: 3 additions & 1 deletion src/instances.ts
Expand Up @@ -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 : ''}`
);
}

Expand Down
42 changes: 28 additions & 14 deletions src/interfaces.ts
Expand Up @@ -198,6 +198,7 @@ interface PerModuleNameCache {
result: typescript.ResolvedModuleWithFailedLookupLocations
): void;
}

export interface ModuleResolutionCache
extends typescript.ModuleResolutionCache {
directoryToModuleNameMap: CacheWithRedirects<
Expand All @@ -206,20 +207,8 @@ export interface ModuleResolutionCache
moduleNameToDirectoryMap: CacheWithRedirects<PerModuleNameCache>;
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;
Expand All @@ -228,7 +217,7 @@ export interface TSInstance {
loaderOptions: LoaderOptions;
rootFileNames: Set<string>;
moduleResolutionCache?: ModuleResolutionCache;
typeReferenceResolutionCache?: TypeReferenceDirectiveResolutionCache;
typeReferenceResolutionCache?: typescript.TypeReferenceDirectiveResolutionCache;
/**
* a cache of all the files
*/
Expand Down Expand Up @@ -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';
54 changes: 40 additions & 14 deletions src/servicesHost.ts
Expand Up @@ -17,7 +17,9 @@ import {
ServiceHostWhichMayBeCacheable,
SolutionBuilderWithWatchHost,
SolutionDiagnostics,
TSCommon,
TSInstance,
TSInternal,
WatchCallbacks,
WatchFactory,
WatchHost,
Expand Down Expand Up @@ -289,16 +291,20 @@ function makeResolvers<T extends typescript.ModuleResolutionHost>(
);

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
);

Expand Down Expand Up @@ -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(
Expand All @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -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"
Expand Down