-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
Suggestion
Add a resolveImportPaths option that resolves import paths configured in paths options,
While transpiling code into the outDir using tsc -p ./tsconfig.json
✅ Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This feature would agree with the rest of TypeScript's Design Goals
- Align with current and future ECMAScript proposals.
- Be a cross-platform development tool.
📃 Example
- Project structure
- Steps to reproduce
- Actual result
- Expected result
Project structure
dist
src
|- common
| |- value-objects.ts
|- some
|- extra
|- nested
|- folder
|- greeting.builder.ts
package.json
package-lock.json
tsconfig.json
Source of the package.json file:
{
"name": "demo-for-typescript",
"version": "1.0.0",
"scripts": {
"build": "tsc -p ./tsconfig.json",
"start": "node ./dist/some/extra/nested/folder/greeting.builder.js",
},
"dependencies": {
"typescript": "^4.4.3"
},
"devDependencies": {
"@types/node": "^16.9.1"
}
}Source of the tsconfig.json file:
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"outDir": "dist",
"baseUrl": "src",
"paths": {
"@common/*": ["common/*"]
},
}
}Source of the src/common/value-objects.ts file:
export class DescriptionValueObject {
constructor(value: any) {
if (typeof value !== 'string') {
throw new Error('Description value has to be of type string');
}
}
}Source of the src/some/extra/nested/folder/greeting.builder.ts file:
import { GreetingValueObject } from "@common/value-objects";
// using paths instead of: import { GreetingValueObject } from "../../../../common/value-objects";
// not only for esthetic purposes, but it helps to resolve conflicts after move files and helps to maintain the large codebase
class GreetingBuilder {
private name: string;
withName(name: string) {
this.name = name;
return this;
}
build(): GreetingValueObject {
if (!this.name) {
throw new Error('Set name first!')
}
return new GreetingValueObject(`Greetings, ${ this.name }!`);
}
}Steps to reproduce
- Run
npm install(tested onnpm@7.6.0andnode@15.11.0) - Run
npm run build(it runstsc -p ./tsconfig.jsonscript) - Run
npm start(it runsnode ./dist/some/extra/nested/folder/greeting.builder.jsfile and simulates server-side run)
Actual results
Node returns an error because tsc didn't resolve paths configured in the tsconfig.json for server-side script:
Error: Cannot find module '@common/value-objects'
Source of the ./dist/some/extra/nested/folder/greeting.builder.js:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const value_objects_1 = require("@common/value-objects"); // <-- server side script does not understand it
// ... other transpiled codeExpected result
tsc should provide the resolveImportPaths option for developers to choose if transpiler should resolve paths using the provided paths configuration
-
When the
resolveImportPathsoption was set astrue,tscshould emit code with relative paths.For this example the require statement should look like:
require("../../../../common/value-objects")"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const value_objects_1 = require("../../../../common/value-objects"); // ... other transpiled code
-
When the
resolveImportPathsoption was set asfalse(by default),tscshould emit code as it does now
💻 Use Cases
Before you decline this request, you have to differentiate two different scenarios of using typescript:
-
For transpiling client-side apps (like react, angular):
Understandably, you won't support such an option for this case because paths are mainly used for combining external libraries.In this scenario, other tools (like webpack or babel), which are already used in the project, could resolve such mappings and serve correct modules.
-
For transpiling server-side node apps:
It is needed to have such an option because developers (as many of them showed you in other Issues) don't want to use other heavy tools only for resolving paths in the imports. That's overkill for the thing that should be handled by the transpiler.The worst thing after you declined many of previous requests for such options, is that the developers started to use scripts for resolving imports in node.js, that override the private API of the built-in node packages.
Here is an example of this script: https://github.com/ilearnio/module-alias/blob/dev/index.js
Check the weekly downloads (464 428) on NPM website https://www.npmjs.com/package/module-aliasWasn't typescript developed to introduce good practices into the code?
Aliasing paths is needed especially for large codebase and helps to solve GIT conflicts after moving/refactoring the modules. Maybe it's time to change the assumptions from this comment and adjust typescript to community needs? You may see that it's needed by developers by reading related issues and checking sh***y workarounds usage statistics.
Related issues
Notice that it's not a duplication of those issues but the continuation.