I'm currently running a backend application in Typescript 5.2, which can be build to run as a Debian service on production with node 18 or directly run in a Docker container through nodemon.
Everywhere in my app you can find relative imports, sometimes short, sometimes very long:
import { Shortcut } from './Shortcut';
import { formatQuery } from '../../../../../../helpers/formatQuery';
And I would like to get rid of these imports.
My package.json looks like:
{
"name": "toto",
"version": "1.4.9",
"description": "tata",
"scripts": {
"start:dev": "nodemon --config ./node_modules/@titi/config/nodemon.json",
"build": "tsc -p tsconfig.json"
},
"devDependencies": {
"jest": "29.6.1",
"ts-jest": "29.1.0",
"typescript": "5.2.2"
},
"dependencies": {
"nodemon": "3.0.1",
},
"volta": {
"node": "18.17.0",
"yarn": "1.22.17"
}
}
I use a custom nodemon.json which is:
{
"watch": ["src/", "*.json"],
"ignore": [
".git",
"public",
"node_modules/**/node_modules",
"src/**/*.test.*",
"src/**/*.spec.*"
],
"ext": "ts,js,json",
"exec": "tsc -p tsconfig.json --incremental && node --trace-warnings --trace-uncaught build || exit 1"
}
and finally, my tsconfig.json file look like this:
{
"compilerOptions": {
"lib": ["es2020"],
"module": "commonjs",
"target": "es2020",
"moduleResolution": "node",
"outDir": "../../../build",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"downlevelIteration": true,
"declaration": true,
"sourceMap": true,
"pretty": true,
"baseUrl": ".",
"paths": {
"@services/*": [
"src/services/*"
],
"@routes/*": [
"src/routes/*"
],
"@helpers/*": [
"src/helpers/*"
]
},
},
"files": ["../../../src/index.ts"],
}
I already know a lot of solutions do exists, I already tried a lot of them but none worked, like:
Setting the
baseUrlproperty
No matter if I set it to . or ./src in my tsconfig.json, I can't start my project and I keep getting this error:
import { formatQuery } from 'src/helpers';
src/services/toto.ts:5:29 - error TS2307: Cannot find module 'src/helpers' or its corresponding type declarations.
Adding
pathsproperties to thetsconfig.json
Whenever I set a paths property, it's being ignored. For example:
"@helpers/*": [ "src/helpers/*" ]
and import a function like this result to:
import { formatQuery } from '@helpers';
src/services/toto.ts:5:29 - error TS2307: Cannot find module '@helpers' or its corresponding type declarations.
(and that even if I put @helpers/formatQuery, and even with a BaseUrl to .)
using the
NODE_PATHenv variable
Since BaseUrl and paths properties change the compiled files (javascript), you can't expect JavaScript to know where is the BaseUrl, so I tried to use this env variable in my nodemon.json's "exec" like:
"exec": "tsc -p tsconfig.json --incremental && NODE_PATH=src node --trace-warnings --trace-uncaught build || exit 1"
Changing my IDE settings (for both JS and TS)
I'm currently using VSCode, and I read somewhere that I needed to edit the typescript.preferences.importModuleSpecifier variable to non-relative (even if I'm not fond of this way, because it globally means new developers that will works on my project won't be abble to make it works if they don't set this property in their VSCode ?)
Using new SubPath pattern
Adding a
jsconfig.json
I tried to add a jsconfig.json file with baseUrl and paths property as put in the tsconfig.json, but it didn't worked.
EDIT: I just forget to tell that the file src/helpers/index.ts do exists, and for clarity sake I'm adding here it's content:
export * from './parseString';
export * from './formatQuery';
...
So what am I doing wrong ? is my architecture too complex to use non-relative imports ?
You need to do some little changes on
baseUrlandpaths:On paths you don't need to add
srcbecausebaseUrlis making paths to start from this folder. If you add it thentswill search for/src/src/....and this is not the case. Read more here.After setting
pathsyou need to usetsc-aliasso@helpers/XXXwill be correctly converted to the actual path of file after typescript build. See this for more details.