Merge pull request #12103 from Microsoft/path_mapping_exact_extension

Allow a path mapping to provide a file extension
This commit is contained in:
Andy
2016-11-11 14:22:05 -08:00
committed by GitHub
11 changed files with 179 additions and 8 deletions

View File

@@ -2210,6 +2210,13 @@ namespace ts {
* Path must have a valid extension.
*/
export function extensionFromPath(path: string): Extension {
const ext = tryGetExtensionFromPath(path);
if (ext !== undefined) {
return ext;
}
Debug.fail(`File ${path} has unknown extension.`);
}
export function tryGetExtensionFromPath(path: string): Extension | undefined {
if (fileExtensionIs(path, ".d.ts")) {
return Extension.Dts;
}
@@ -2225,7 +2232,5 @@ namespace ts {
if (fileExtensionIs(path, ".jsx")) {
return Extension.Jsx;
}
Debug.fail(`File ${path} has unknown extension.`);
return Extension.Js;
}
}

View File

@@ -515,18 +515,21 @@ namespace ts {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
}
for (const subst of state.compilerOptions.paths[matchedPatternText]) {
return forEach(state.compilerOptions.paths[matchedPatternText], subst => {
const path = matchedStar ? subst.replace("*", matchedStar) : subst;
const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl, path));
if (state.traceEnabled) {
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
}
const resolved = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
if (resolved) {
return resolved;
// A path mapping may have a ".ts" extension; in contrast to an import, which should omit it.
const tsExtension = tryGetExtensionFromPath(candidate);
if (tsExtension !== undefined) {
const path = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/false, state);
return path && { path, extension: tsExtension };
}
}
return undefined;
return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
});
}
else {
const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl, moduleName));

View File

@@ -0,0 +1,24 @@
//// [tests/cases/compiler/pathMappingBasedModuleResolution_withExtension.ts] ////
//// [foo.ts]
export function foo() {}
//// [bar.js]
export function bar() {}
//// [a.ts]
import { foo } from "foo";
import { bar } from "bar";
//// [foo.js]
"use strict";
function foo() { }
exports.foo = foo;
//// [bar.js]
"use strict";
function bar() { }
exports.bar = bar;
//// [a.js]
"use strict";

View File

@@ -0,0 +1,16 @@
=== /a.ts ===
import { foo } from "foo";
>foo : Symbol(foo, Decl(a.ts, 0, 8))
import { bar } from "bar";
>bar : Symbol(bar, Decl(a.ts, 1, 8))
=== /foo/foo.ts ===
export function foo() {}
>foo : Symbol(foo, Decl(foo.ts, 0, 0))
=== /bar/bar.js ===
export function bar() {}
>bar : Symbol(bar, Decl(bar.js, 0, 0))

View File

@@ -0,0 +1,18 @@
[
"======== Resolving module 'foo' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo'",
"'paths' option is specified, looking for a pattern to match module name 'foo'.",
"Module name 'foo', matched pattern 'foo'.",
"Trying substitution 'foo/foo.ts', candidate module location: 'foo/foo.ts'.",
"File '/foo/foo.ts' exist - use it as a name resolution result.",
"======== Module name 'foo' was successfully resolved to '/foo/foo.ts'. ========",
"======== Resolving module 'bar' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'bar'",
"'paths' option is specified, looking for a pattern to match module name 'bar'.",
"Module name 'bar', matched pattern 'bar'.",
"Trying substitution 'bar/bar.js', candidate module location: 'bar/bar.js'.",
"File '/bar/bar.js' exist - use it as a name resolution result.",
"======== Module name 'bar' was successfully resolved to '/bar/bar.js'. ========"
]

View File

@@ -0,0 +1,16 @@
=== /a.ts ===
import { foo } from "foo";
>foo : () => void
import { bar } from "bar";
>bar : () => void
=== /foo/foo.ts ===
export function foo() {}
>foo : () => void
=== /bar/bar.js ===
export function bar() {}
>bar : () => void

View File

@@ -0,0 +1,9 @@
/a.ts(2,21): error TS2307: Cannot find module 'foo'.
==== /a.ts (1 errors) ====
import { foo } from "foo";
~~~~~
!!! error TS2307: Cannot find module 'foo'.

View File

@@ -0,0 +1,7 @@
//// [a.ts]
import { foo } from "foo";
//// [a.js]
"use strict";

View File

@@ -0,0 +1,32 @@
[
"======== Resolving module 'foo' from '/a.ts'. ========",
"Module resolution kind is not specified, using 'NodeJs'.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo'",
"'paths' option is specified, looking for a pattern to match module name 'foo'.",
"Module name 'foo', matched pattern 'foo'.",
"Trying substitution 'foo/foo.ts', candidate module location: 'foo/foo.ts'.",
"File '/foo/foo.ts' does not exist.",
"Loading module 'foo' from 'node_modules' folder.",
"File '/node_modules/foo.ts' does not exist.",
"File '/node_modules/foo.tsx' does not exist.",
"File '/node_modules/foo.d.ts' does not exist.",
"File '/node_modules/foo/package.json' does not exist.",
"File '/node_modules/foo/index.ts' does not exist.",
"File '/node_modules/foo/index.tsx' does not exist.",
"File '/node_modules/foo/index.d.ts' does not exist.",
"File '/node_modules/@types/foo.d.ts' does not exist.",
"File '/node_modules/@types/foo/package.json' does not exist.",
"File '/node_modules/@types/foo/index.d.ts' does not exist.",
"'baseUrl' option is set to '/', using this value to resolve non-relative module name 'foo'",
"'paths' option is specified, looking for a pattern to match module name 'foo'.",
"Module name 'foo', matched pattern 'foo'.",
"Trying substitution 'foo/foo.ts', candidate module location: 'foo/foo.ts'.",
"File '/foo/foo.ts' does not exist.",
"Loading module 'foo' from 'node_modules' folder.",
"File '/node_modules/foo.js' does not exist.",
"File '/node_modules/foo.jsx' does not exist.",
"File '/node_modules/foo/package.json' does not exist.",
"File '/node_modules/foo/index.js' does not exist.",
"File '/node_modules/foo/index.jsx' does not exist.",
"======== Module name 'foo' was not resolved. ========"
]

View File

@@ -0,0 +1,26 @@
// @noImplicitReferences: true
// @traceResolution: true
// @allowJs: true
// @Filename: /foo/foo.ts
export function foo() {}
// @Filename: /bar/bar.js
export function bar() {}
// @Filename: /a.ts
import { foo } from "foo";
import { bar } from "bar";
// @Filename: /tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"foo": ["foo/foo.ts"],
"bar": ["bar/bar.js"]
},
"allowJs": true,
"outDir": "bin"
}
}

View File

@@ -0,0 +1,15 @@
// @noImplicitReferences: true
// @traceResolution: true
// @Filename: /a.ts
import { foo } from "foo";
// @Filename: /tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"foo": ["foo/foo.ts"]
}
}
}