microsoft / microsoft/TypeScript

Compiler option to define output-to-input directory map for module resolution of package.json `"imports"`/`"exports"`

オープン
#62,591 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

### 🔍 Search Terms

"rootDir", "outDir", "paths", "map", "mapping", "imports", "exports", "moduleResolution", "module resolution"

### ✅ Viability Checklist

- [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [x] This wouldn't change the runtime behavior of existing JavaScript code
- [x] This could be implemented without emitting different JS based on the types of the expressions
- [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [x] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

### ⭐ Suggestion

A TS project with `moduleResolution: bundler` (and others) uses the `rootDir` and `outDir` options to map the project's package.json `"imports"` and `"exports"` entries from `outDir` to `rootDir` directory. However, this only works for files inside `rootDir`.

A new option could be introduced for programs to define/inform that another local project compiles `rootDir` into `outDir`. This would be similar (indeed, identical in intent) to the `paths` option, but with more convenient support for package.json's `"imports"`/`"exports"` resolution, since only output-to-input directory mappings are required; with `paths`, one mapping would be required for every `"imports"` and `"exports"` entry.

### 📃 Motivating Example

Consider a project with the following structure:
```
├──📁 src
├──📁 test
├──📄 package.json
├──📄 tsconfig.json // references the other config files
├──📄 tsconfig.src.json
└──📄 tsconfig.test.json
```
```jsonc
// tsconfig.src.json
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler",
"rootDir": "src",
"outDir": "dts",
},
"include": ["src"]
```
```jsonc
// package.json
"imports": {
"#foo": {
"types": "./dts/foo.d.ts"
}
}
```
With the previous configuration, tsc is able to resolve `#foo` imports inside `src/`, even if `dts/` has not yet been generated, because of `rootDir` and `outDir`.

The desired behavior is for `tsconfig.test.json` (for the `test/` directory) to also be able to resolve `#foo` imports before `dts/` is generated. That is, inform `tsconfig.test.json` that other program compiles `src` into `dts`. This could be achieved with a new compiler option:
```ts
// tsconfig.test.json
"": {
"dts": "src" // Inform tsc that other program compiles src into dts
}
```

### 💻 Use Cases

To resolve package.json's `"imports"` and `"exports"` output file paths by mapping them to corresponding input files. It may be seen in the previous example that this would be useful in the same way import specifier maps with `paths` is useful, but more convenient for `"imports"`/`"exports"` resolution.

### Alternatives

#### 1. `paths`

The desired behavior can be achieved with the `paths` option, but it is not as convenient since a map entry is required for every `"imports"` and `"exports"` entry, `paths` mappings are in a different file, and updating `"imports"`/`"exports"` requires a corresponding `paths` update.

```jsonc
// package.json
"imports": {
"#foo": {
"types": "./dts/foo.d.ts"
},
"#bar": {
"types": "./dts/bar.d.ts"
}
}
```
```jsonc
// tsconfig.json
"paths": {
"#foo": ["./src/foo.ts"],
"#bar": ["./src/bar.ts"]
}
```
Besides, it seems more appropriate for tsc to resolve "#" and self-reference import specifiers from paths defined by package.json `"imports"`/`"exports"` since that is, after all, their purpose.

#### 2. `customConditions`

A second alternative is using `customConditions`, but drawbacks are somewhat similar. Although with a custom condition, all map entries can be defined in package.json, more boilerplate is required:
```jsonc
// package.json
"imports": {
"#foo": {
"types": {
"dev": "./src/foo.ts",
"default": "./dts/foo.d.ts"
}
},
"#bar": {
"types": {
"dev": "./src/bar.ts",
"default": "./dts/bar.d.ts"
}
}
}
```
```jsonc
// tsconfig.json
"customConditions": ["dev"]
```
This, however, better mirrors the desired behavior; the resolution process with this configuration is very similar to the `outDir` to `rootDir` mapping tsc performs (see [package.json "imports" and self-name imports](https://www.typescriptlang.org/docs/handbook/modules/reference.html#packagejson-imports-and-self-name-imports)).

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

この issue では、リポジトリのソースファイルやテストが指定されていません。まず、示されている tsconfig.src.json と tsconfig.test.json の設定で、rootDir/outDir および package.json の "imports" と "exports" の動作を再現し、その後、既存の moduleResolution の処理を追跡してください。文書化された compiler option によって、別のプロジェクトの出力ディレクトリを対応する入力ファイルへ戻してマッピングでき、対応する paths エントリを要求しない状態になれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
28/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。