-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Allow 'paths' without 'baseUrl' #40101
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
Changes from all commits
82ca6d6
45fad77
87af596
008c217
5cb69bc
36f3780
7b74658
f3f82e2
7fcd9e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2508,6 +2508,13 @@ namespace ts { | |
parseOwnConfigOfJson(json, host, basePath, configFileName, errors) : | ||
parseOwnConfigOfJsonSourceFile(sourceFile!, host, basePath, configFileName, errors); | ||
|
||
if (ownConfig.options?.paths) { | ||
// If we end up needing to resolve relative paths from 'paths' relative to | ||
// the config file location, we'll need to know where that config file was. | ||
// Since 'paths' can be inherited from an extended config in another directory, | ||
// we wouldn't know which directory to use unless we store it here. | ||
ownConfig.options.pathsBasePath = basePath; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure if this should be non enumerable and should be in tsconfig build info or not. You would also want test case with incremental set. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a baseline that shows it in the .tsbuildinfo. It seems like it would be necessary if an incremental build doesn’t re-resolve everything in tsconfig, but I’m not sure how that works. Exactly what would you want to see in a test case? |
||
} | ||
if (ownConfig.extendedConfigPath) { | ||
// copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios. | ||
resolutionStack = resolutionStack.concat([resolvedPath]); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -788,13 +788,16 @@ namespace ts { | |
} | ||
|
||
function tryLoadModuleUsingPathsIfEligible(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState) { | ||
const { baseUrl, paths } = state.compilerOptions; | ||
if (baseUrl && paths && !pathIsRelative(moduleName)) { | ||
const { baseUrl, paths, pathsBasePath } = state.compilerOptions; | ||
if (paths && !pathIsRelative(moduleName)) { | ||
if (state.traceEnabled) { | ||
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName); | ||
if (baseUrl) { | ||
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName); | ||
} | ||
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName); | ||
} | ||
return tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state); | ||
const baseDirectory = baseUrl ?? Debug.checkDefined(pathsBasePath || state.host.getCurrentDirectory?.(), "Encountered 'paths' without a 'baseUrl', config file, or host 'getCurrentDirectory'."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks sketchy, but I manually verified that the assertion should hold in all cases we currently have; it’s just hard to encode it into the types. The only times
Changing |
||
return tryLoadModuleUsingPaths(extensions, moduleName, baseDirectory, paths, loader, /*onlyRecordFailures*/ false, state); | ||
} | ||
} | ||
|
||
|
@@ -1368,6 +1371,7 @@ namespace ts { | |
} | ||
const resolved = forEach(paths[matchedPatternText], subst => { | ||
const path = matchedStar ? subst.replace("*", matchedStar) : subst; | ||
// When baseUrl is not specified, the command line parser resolves relative paths to the config file location. | ||
const candidate = normalizePath(combinePaths(baseDirectory, path)); | ||
if (state.traceEnabled) { | ||
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
c:/root/tsconfig.json(5,17): error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
c:/root/tsconfig.json(6,17): error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
|
||
|
||
==== c:/root/tsconfig.json (2 errors) ==== | ||
{ | ||
"compilerOptions": { | ||
"paths": { | ||
"*": [ | ||
"*", | ||
~~~ | ||
!!! error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
"generated/*" | ||
~~~~~~~~~~~~~ | ||
!!! error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
] | ||
} | ||
} | ||
} | ||
|
||
==== c:/root/f1.ts (0 errors) ==== | ||
export var x = 1; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
//// [f1.ts] | ||
export var x = 1; | ||
|
||
|
||
//// [f1.js] | ||
define(["require", "exports"], function (require, exports) { | ||
"use strict"; | ||
exports.__esModule = true; | ||
exports.x = void 0; | ||
exports.x = 1; | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
=== c:/root/f1.ts === | ||
export var x = 1; | ||
>x : Symbol(x, Decl(f1.ts, 0, 10)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
=== c:/root/f1.ts === | ||
export var x = 1; | ||
>x : number | ||
>1 : 1 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//// [tests/cases/compiler/pathMappingInheritedBaseUrl.ts] //// | ||
|
||
//// [tsconfig.base.json] | ||
{ | ||
"compilerOptions": { | ||
"baseUrl": "." | ||
} | ||
} | ||
|
||
//// [index.ts] | ||
export const p1 = 0; | ||
|
||
//// [index.ts] | ||
import { p1 } from "p1"; | ||
|
||
|
||
//// [index.js] | ||
"use strict"; | ||
exports.__esModule = true; | ||
exports.p1 = void 0; | ||
exports.p1 = 0; | ||
//// [index.js] | ||
"use strict"; | ||
exports.__esModule = true; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//// [tests/cases/compiler/pathMappingWithoutBaseUrl1.ts] //// | ||
|
||
//// [index.ts] | ||
export const p1 = 0; | ||
|
||
//// [index.ts] | ||
import { p1 } from "p1"; | ||
|
||
|
||
//// [index.js] | ||
"use strict"; | ||
exports.__esModule = true; | ||
exports.p1 = void 0; | ||
exports.p1 = 0; | ||
//// [index.js] | ||
"use strict"; | ||
exports.__esModule = true; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
//// [tests/cases/compiler/pathMappingWithoutBaseUrl2.ts] //// | ||
|
||
//// [tsconfig.base.json] | ||
{ | ||
"compilerOptions": { | ||
"paths": { | ||
"p1": ["./lib/p1"] | ||
} | ||
} | ||
} | ||
|
||
//// [index.ts] | ||
export const p1 = 0; | ||
|
||
//// [index.ts] | ||
import { p1 } from "p1"; | ||
|
||
|
||
//// [index.js] | ||
"use strict"; | ||
exports.__esModule = true; | ||
exports.p1 = void 0; | ||
exports.p1 = 0; | ||
//// [index.js] | ||
"use strict"; | ||
exports.__esModule = true; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
tests/cases/compiler/tsconfig.json(5,26): error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
tests/cases/compiler/tsconfig.json(6,19): error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
tests/cases/compiler/tsconfig.json(7,23): error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
|
||
|
||
==== tests/cases/compiler/tsconfig.json (3 errors) ==== | ||
{ | ||
"compilerOptions": { | ||
"traceResolution": true, | ||
"paths": { | ||
"@interface/*": ["src/interface/*"], | ||
~~~~~~~~~~~~~~~~~ | ||
!!! error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
"@blah": ["blah"], | ||
~~~~~~ | ||
!!! error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
"@humbug/*": ["*/generated"] | ||
~~~~~~~~~~~~~ | ||
!!! error TS5090: Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'? | ||
} | ||
} | ||
} | ||
|
||
==== tests/cases/compiler/src/main.ts (0 errors) ==== | ||
import 'someModule'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//// [main.ts] | ||
import 'someModule'; | ||
|
||
//// [main.js] | ||
"use strict"; | ||
exports.__esModule = true; | ||
require("someModule"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[ | ||
"======== Resolving module 'someModule' from 'tests/cases/compiler/src/main.ts'. ========", | ||
"Module resolution kind is not specified, using 'NodeJs'.", | ||
"'paths' option is specified, looking for a pattern to match module name 'someModule'.", | ||
"Loading module 'someModule' from 'node_modules' folder, target file type 'TypeScript'.", | ||
"Directory 'tests/cases/compiler/src/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'tests/cases/compiler/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'tests/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'node_modules' does not exist, skipping all lookups in it.", | ||
"Directory '/node_modules' does not exist, skipping all lookups in it.", | ||
"'paths' option is specified, looking for a pattern to match module name 'someModule'.", | ||
"Loading module 'someModule' from 'node_modules' folder, target file type 'JavaScript'.", | ||
"Directory 'tests/cases/compiler/src/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'tests/cases/compiler/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'tests/cases/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'tests/node_modules' does not exist, skipping all lookups in it.", | ||
"Directory 'node_modules' does not exist, skipping all lookups in it.", | ||
"Directory '/node_modules' does not exist, skipping all lookups in it.", | ||
"======== Module name 'someModule' was not resolved. ========" | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// @noTypesAndSymbols: true | ||
|
||
// @Filename: /other/tsconfig.base.json | ||
{ | ||
"compilerOptions": { | ||
"baseUrl": "." | ||
} | ||
} | ||
|
||
// @Filename: /project/tsconfig.json | ||
{ | ||
"extends": "../other/tsconfig.base.json", | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"paths": { | ||
"p1": ["./lib/p1"] | ||
} | ||
} | ||
} | ||
|
||
// @Filename: /other/lib/p1/index.ts | ||
export const p1 = 0; | ||
|
||
// @Filename: /project/index.ts | ||
import { p1 } from "p1"; |
Uh oh!
There was an error while loading. Please reload this page.