From f832bb60a45d5d26535a793b61bc663dfd3b9565 Mon Sep 17 00:00:00 2001 From: John Reilly Date: Tue, 17 Oct 2017 17:17:31 +0100 Subject: [PATCH] Fix allowJs import @types issue --- src/compilerSetup.ts | 4 +- src/interfaces.ts | 2 +- src/servicesHost.ts | 44 +++++++++++++------ src/utils.ts | 4 +- .../nolib/expectedOutput-2.5/output.txt | 28 ------------ 5 files changed, 35 insertions(+), 47 deletions(-) diff --git a/src/compilerSetup.ts b/src/compilerSetup.ts index 0211f3eb6..9f0b1486c 100644 --- a/src/compilerSetup.ts +++ b/src/compilerSetup.ts @@ -44,9 +44,9 @@ export function getCompilerOptions( configParseResult: typescript.ParsedCommandLine ) { const compilerOptions = Object.assign({}, configParseResult.options, { - skipDefaultLibCheck: true, + skipLibCheck: true, suppressOutputPathCheck: true, // This is why: https://github.com/Microsoft/TypeScript/issues/7363 - }); + } as typescript.CompilerOptions); // if `module` is not specified and not using ES6+ target, default to CJS module output if ((compilerOptions.module === undefined) && diff --git a/src/interfaces.ts b/src/interfaces.ts index 8ba7ddc8d..106b85ac3 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -211,7 +211,7 @@ export interface ResolveSync { export interface ModuleResolutionHost { fileExists(fileName: string): boolean; - readFile(fileName: string): string; + readFile(fileName: string, encoding?: string | undefined): string | undefined; } export interface TSInstance { diff --git a/src/servicesHost.ts b/src/servicesHost.ts index 354314877..c6f49f152 100644 --- a/src/servicesHost.ts +++ b/src/servicesHost.ts @@ -34,19 +34,27 @@ export function makeServicesHost( // make a (sync) resolver that follows webpack's rules const resolveSync = makeResolver(loader.options); + const readFileWithFallback = (path: string, encoding?: string | undefined): string | undefined => + compiler.sys.readFile(path, encoding) || readFile(path, encoding); + + const fileExists = (path: string) => compiler.sys.fileExists(path) || readFile(path) !== undefined; + const moduleResolutionHost: ModuleResolutionHost = { - fileExists: (fileName: string) => readFile(fileName) !== undefined, - readFile: (fileName: string) => readFile(fileName) || '', + fileExists, + readFile: readFileWithFallback }; - return { + const servicesHost: typescript.LanguageServiceHost = { getProjectVersion: () => `${instance.version}`, + getScriptFileNames: () => Object.keys(files).filter(filePath => filePath.match(scriptRegex)), + getScriptVersion: (fileName: string) => { fileName = path.normalize(fileName); const file = files[fileName]; return file === undefined ? '' : file.version.toString(); }, + getScriptSnapshot: (fileName: string) => { // This is called any time TypeScript needs a file's text // We either load from memory or from disk @@ -73,23 +81,33 @@ export function makeServicesHost( */ directoryExists: compiler.sys ? ( compiler.sys).directoryExists : undefined, + useCaseSensitiveFileNames: () => compiler.sys.useCaseSensitiveFileNames, + // The following three methods are necessary for @types resolution from TS 2.4.1 onwards see: https://github.com/Microsoft/TypeScript/issues/16772 fileExists: compiler.sys ? ( compiler.sys).fileExists : undefined, readFile: compiler.sys ? ( compiler.sys).readFile : undefined, readDirectory: compiler.sys ? ( compiler.sys).readDirectory : undefined, - getCurrentDirectory: () => process.cwd(), + getCurrentDirectory: () => loader.context, getCompilationSettings: () => compilerOptions, getDefaultLibFileName: (options: typescript.CompilerOptions) => compiler.getDefaultLibFilePath(options), getNewLine: () => newLine, log: log.log, + + resolveTypeReferenceDirectives: (typeDirectiveNames: string[], containingFile: string) => + typeDirectiveNames.map(directive => + compiler.resolveTypeReferenceDirective(directive, containingFile, compilerOptions, moduleResolutionHost).resolvedTypeReferenceDirective), + resolveModuleNames: (moduleNames: string[], containingFile: string) => resolveModuleNames( resolveSync, moduleResolutionHost, appendTsSuffixTo, appendTsxSuffixTo, scriptRegex, instance, moduleNames, containingFile), + getCustomTransformers: () => instance.transformers }; + + return servicesHost; } function resolveModuleNames( @@ -104,9 +122,8 @@ function resolveModuleNames( ) { const resolvedModules = moduleNames.map(moduleName => resolveModuleName(resolveSync, moduleResolutionHost, appendTsSuffixTo, appendTsxSuffixTo, scriptRegex, instance, - moduleName, containingFile) - ); - + moduleName, containingFile)); + populateDependencyGraphs(resolvedModules, instance, containingFile); return resolvedModules; @@ -159,12 +176,11 @@ function resolveModuleName( resolvedFileName, isExternalLibraryImport: tsResolution.resolvedModule.isExternalLibraryImport }; - if (resolutionResult!) { - if (resolutionResult!.resolvedFileName === tsResolutionResult.resolvedFileName || - isJsImplementationOfTypings(resolutionResult!, tsResolutionResult)) { - resolutionResult!.isExternalLibraryImport = tsResolutionResult.isExternalLibraryImport; - } - } else { + + if (resolutionResult! === undefined || + resolutionResult!.resolvedFileName === tsResolutionResult.resolvedFileName || + isJsImplementationOfTypings(resolutionResult!, tsResolutionResult) + ) { resolutionResult = tsResolutionResult; } } @@ -177,7 +193,7 @@ function populateDependencyGraphs( containingFile: string ) { resolvedModules = resolvedModules - .filter(m => m !== null && m !== undefined); + .filter(mod => mod !== null && mod !== undefined); instance.dependencyGraph[path.normalize(containingFile)] = resolvedModules; diff --git a/src/utils.ts b/src/utils.ts index b69f6e74f..2df127602 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -84,10 +84,10 @@ export function formatErrors( : []; } -export function readFile(fileName: string) { +export function readFile(fileName: string, encoding: string | undefined = 'utf8') { fileName = path.normalize(fileName); try { - return fs.readFileSync(fileName, 'utf8'); + return fs.readFileSync(fileName, encoding); } catch (e) { return undefined; } diff --git a/test/comparison-tests/nolib/expectedOutput-2.5/output.txt b/test/comparison-tests/nolib/expectedOutput-2.5/output.txt index 3c2cb2db2..edbf5767b 100644 --- a/test/comparison-tests/nolib/expectedOutput-2.5/output.txt +++ b/test/comparison-tests/nolib/expectedOutput-2.5/output.txt @@ -2,34 +2,6 @@ bundle.js 2.49 kB 0 [emitted] main [0] ./.test/nolib/app.ts 16 bytes {0} [built] [1 error] -ERROR in node_modules\@types\semver\index.d.ts -[tsl] ERROR in node_modules\@types\semver\index.d.ts(100,28) - TS2304: Cannot find name 'Array'. - -ERROR in node_modules\@types\semver\index.d.ts -[tsl] ERROR in node_modules\@types\semver\index.d.ts(100,70) - TS2304: Cannot find name 'Array'. - -ERROR in node_modules\@types\semver\index.d.ts -[tsl] ERROR in node_modules\@types\semver\index.d.ts(104,29) - TS2304: Cannot find name 'Array'. - -ERROR in node_modules\@types\semver\index.d.ts -[tsl] ERROR in node_modules\@types\semver\index.d.ts(104,71) - TS2304: Cannot find name 'Array'. - -ERROR in node_modules\@types\semver\index.d.ts -[tsl] ERROR in node_modules\@types\semver\index.d.ts(123,41) - TS2304: Cannot find name 'Array'. - -ERROR in node_modules\@types\semver\index.d.ts -[tsl] ERROR in node_modules\@types\semver\index.d.ts(127,41) - TS2304: Cannot find name 'Array'. - -ERROR in node_modules\@types\chalk\index.d.ts -[tsl] ERROR in node_modules\@types\chalk\index.d.ts(18,10) - TS2370: A rest parameter must be of an array type. - ERROR in ./.test/nolib/app.ts [tsl] ERROR in app.ts(1,1)  TS2304: Cannot find name 'parseInt'.