microsoft / microsoft/TypeScript

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

Abierto
#62,591 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Awaiting More Feedback Suggestion
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

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

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

El issue no menciona archivos fuente ni pruebas del repositorio. Empieza reproduciendo el comportamiento de rootDir/outDir y de "imports" y "exports" de package.json con la configuración mostrada de tsconfig.src.json y tsconfig.test.json; después, sigue el manejo existente de moduleResolution. Se considera terminado cuando una opción del compilador documentada asigna el directorio de salida de otro proyecto de vuelta a sus archivos de entrada sin requerir entradas de paths coincidentes.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
28/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.