microsoft / microsoft/TypeScript

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

Ouverte
#62,591 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Awaiting More Feedback Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

### 🔍 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)).

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

L’issue ne nomme aucun fichier source ni aucun test du dépôt. Commencez par reproduire le comportement de rootDir/outDir ainsi que de "imports" et "exports" de package.json avec la configuration montrée de tsconfig.src.json et tsconfig.test.json, puis suivez la gestion existante de moduleResolution. C’est terminé lorsqu’une option du compilateur documentée remappe le répertoire de sortie d’un autre projet vers ses fichiers d’entrée sans nécessiter d’entrées paths correspondantes.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
28/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.