How nestjs configures path aliases in a project - nestjs

I configured the path alias in tsconfig.json of the nestjs project, but there was an error while running.
I tried to configure like Angular, but there was an error in nestjs
This is my tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"paths": {
"~auth/*": ["src/auth/*"]
}
},
"exclude": ["node_modules"]
}
Use it like this
import { userLoginJwt } from '~auth/jwt-names'
Startup error
$ npm run start:dev
[0] internal/modules/cjs/loader.js:584
[0] throw err;
[0] ^
[0]
[0] Error: Cannot find module 'src/auth/jwt-names'
Sorry, I emphasize here that running npm run start works fine, but running npm run start:dev can lead to unexpected situations.

This job, I work:
Modify my 'tsconfig.json'
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./src",
"incremental": true,
"paths": {
"~auth/*": ["auth/*"]
}
},
"exclude": ["node_modules"]
}
Add 'tsconfig-paths-bootstrap.js' file
// tsconfig-paths-bootstrap.js
const tsConfig = require('./tsconfig.json');
const tsConfigPaths = require('tsconfig-paths');
tsConfigPaths.register({
baseUrl: tsConfig.compilerOptions.outDir,
paths: tsConfig.compilerOptions.paths,
});
Modify the 'nodemon.json' file
{
"watch": ["dist"],
"ext": "js",
"exec": "node -r ./tsconfig-paths-bootstrap.js dist/main.js"
}
Use path alias
import { userLoginJwt } from '~auth/jwt-names';
Now executing the npm run start:dev error has disappeared.

src is not an available folder after compilation, as all the code is moved to the dist folder. Rather, what you should do in your tsconfig is set up a baseUrl to point to src and the outDir to point to dist then remove src from your paths. I'd also suggest reading up on Typescript path mapping to get a better understanding of what is happening.

TL;DR;
Update your package.json
"start:dev": "nest start --watch --exec 'node -r tsconfig-paths/register -r ts-node/register ./src/main.ts'"
Use npm run start:dev

Only needs:
"moduleResolution": "node",
"baseUrl": "src",
"paths": {
"#lib/*": ["lib/*"],
"#models/*": ["models/*"],
"#plugins/*": ["plugins/*"],
"#routes/*": ["routes/*"],
"#services/*": ["services/*"],
"#api": ["api/index"]
}
https://medium.com/zero-equals-false/how-to-use-module-path-aliases-in-visual-studio-typescript-and-javascript-e7851df8eeaa

How nestjs configures path aliases in a project
It doesn't you are showing us the tsconfig file - its TS that is declaring the paths
"paths": {
"~auth/*": ["src/auth/*"]
}
would be better if it followed what appears to be a convention of adding # instead of tilda
"paths": {
"#auth/*": ["src/auth/*"]
}
Or just all
"paths": {
"*": [
"./*"
]
},
So thats the path reference sorted... now onto tsconfig-paths for using short paths after compilation. So the above will be good for the TS, but after its been transpiled to JS the paths are no longer referenced as its JS now... which is why it fails with the start command.
You will need to create a bootstrap script like shown in the docs and calling that in your package.json just before the build command.

Related

NodeJS Typescript doesn't convert to relative path

I have Node project with Typescript.
I want to import this module in getToken.ts
import {apiRoot} from '#App/utils/apiRoot';
For absolute path I have a config like this.
tsconfig.json
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"baseUrl": "./",
"paths": {
"#App/*": [ "src/*"]
},
"typeRoots": ["./node_modules/#types", "./src/types"],
"outDir": "./dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
tsconfig.build.json
{
"extends": "./tsconfig.json",
"exclude": [
"__test__/**/*.spec.ts",
"__test__/**/*.test.ts"
]
}
In package.json
"scripts": {
"dev": "tsc --project tsconfig.build.json && concurrently \"tsc -w\" \"nodemon dist/index.js\"",
},
When I run npm run dev
I got an error
Error: Cannot find module '#App/utils/apiRoot'
I check to build file in dist folder (getToken.js) and I see
const apiRoot_1 = require("#App/utils/apiRoot");
I use same technic and same path for testing with Jest without a problem in same project. How can i solve this problem?

How do I fix "Cannot find module" when importing files from custom absolute path?

I tried to create a NodeJS from scratch with TypeScript and had a file structures below:
my-project
|
|--node_modules
|--src
| |--index.ts
| |--test.ts
|
|--package.json
|--tsconfig.json
|--...
Then in tsconfig.json, I added baseUrl and paths to allow absolute import
{
"compilerOptions": {
"target": "ES5",
"lib": ["es5", "es6", "ESNext"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"module": "CommonJS",
"moduleResolution": "Node",
"baseUrl": ".",
"paths": {
"#src/*": ["src/*"],
"#root/*": ["*"]
},
"resolveJsonModule": true,
"sourceMap": true,
"outDir": "./build",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"exclude": ["node_modules", "build"]
}
I created simple codes like this, VSCode still detects test.ts and passes linter check with strict mode.
// src/test.ts
export const a = 1;
// src/index.ts
import { a } from '#src/test'
console.log(a);
After that, I ran npx nodemon src/index.ts the terminal shows me an error:
Error: Cannot find module '#src/test'
Require stack:
- D:\self-project\typeorm-test\src\index.ts
Am I configuring path wrong? Anyone know how to fix this?
The only work around I could find to this was to install tsconfig-paths as a dev dependency:
npm install --save-dev tsconfig-paths
I also have ts-node installed as a dev dependency. Then in your scripts in package.json add this:
"dev": "nodemon --exec npx ts-node -r tsconfig-paths/register

Why isn't VS Code respecting TypeScript paths?

In my TypeScript project that's running tests via ts-node and jasmine I have defined some paths in tsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"target": "es5",
"module": "commonjs",
"lib": [
"es5",
"es2015",
"DOM"
],
"moduleResolution": "Node",
"outDir": "./dist/cjs",
"declaration": true,
"sourceMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"noImplicitAny": false,
"removeComments": true,
"strict": true,
"paths": {
"#common": ["common/index"],
"#crashes": ["crashes/index"]
}
},
"files": [
"./src/index.ts"
]
}
I am able to import via paths #common and #crashes in my production code, but for some reason VS Code gives me the error Cannot find module '#common' or its corresponding type declarations. in my spec.ts files.
How can I get VS Code to recognize TypeScript paths in my tests?
This is because VS Code's intellisense will follow the rules in tsconfig.json. In this instance, I was not including the spec.ts files in the TypeScript compilation. Additionally, I did not want to include the TypeScript files in my project's build output.
The solution was as follows:
Remove the files property from tsconfig.json
Introduce a new tsconfig.dist.json that extends tsconfig.json and add the files property here
{
"extends": "./tsconfig.json",
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "./dist/cjs",
},
"files": [
"./src/index.ts"
]
}
Use the new tsconfig.dist.json in the publish script
Additionally, once I did all this, I got the following error when I tried to run jasmine tests with ts-node:
> ts-node node_modules/jasmine/bin/jasmine --config=spec/support/jasmine.spec.json
Error: Cannot find module '#common'
The solution to this error was to install tsconfig-paths and update my test script in package.json
{
"scripts": {
"test": "ts-node -r tsconfig-paths/register node_modules/jasmine/bin/jasmine --config=spec/support/jasmine.spec.json"
}
}

How to do module resolution in typescript to output for node?

tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"allowJs": false,
"strict": true,
"target": "es6",
"module": "commonjs",
"lib": ["dom", "es6", "es5", "es2017", "esnext.asynciterable"],
"sourceMap": true,
"moduleResolution": "node",
"paths": {
"src/*": ["src/*"]
},
"declaration": true,
"rootDir": "./src",
"outDir": "dist"
},
"exclude": ["dist"],
"include": [ "src"]
}
Original Folder structure
src /
util/
getSomething.ts
index.ts
Output Folder structure
dist /
util/
getSomething.js
index.js
index.ts
import getSomething from 'src/util/getSomething';
package.json script
{
"build": "tsc && tspath -f",
"start": "node dist/index.js"
}
The build works but when I run start I get error.
Is there a way to have a root based module resolution?
I followed this example (just replacing ~ with src) and it is giving me this problem.
Unless there is an alternative solution to tspath.
https://haseebmajid.dev/blog/better-imports-with-babel-tspath
Note: I am using windows 10.
npm start
Error: Cannot find module './src\util\getSomething'
Require stack:
c:\apps\example-typescript-node\dist\index.js
Answered here:
https://github.com/duffman/tspath/issues/33
I have resolved my problem. I had to ensure my rootDir was ./ not src.
Then targeting index.js inside dist/src/ not dist/
tsconfig.json
{
"compilerOptions": {
"rootDir": "./"
}
}
package.json
{
"build": "tsc && tspath -f",
"start": "node dist/src/index.js"
}

Running script when ts-node-dev restarts server

I currently have ts-node-dev installed with my node js server and have it watching my .ts files with the --respawn flag. My server is getting successfully restarted, but I when a .ts file changes, I need to run a command like yarn build to compile the changed files (or all files) to make sure my changes are present in the restarted server.
I can't seem to find a way to run a script when the server restarts.
I have tried something like:
"start": "ts-node-dev --respawn --transpile-only yarn build && src/main.js"
In my package.json, but it tries to resolve my yarn build command as a file name.
How can I tie a script into my restarting process?
{
"compileOnSave": true,
"compilerOptions": {
"target": "es2017",
"lib": ["es2017", "esnext.asynciterable"],
"module": "commonjs",
"moduleResolution": "node",
"rootDir": ".",
"sourceMap": true,
"newLine": "LF",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"strict": true,
// For typeORM support
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strictPropertyInitialization": false,
"pretty": true,
"typeRoots": ["node_modules/#types"]
},
"include": ["src/**/*", "db/**/*", "swagger/**/*", "test/**/*"]
}
This is my tsconfig.json, how do I specify with the watch command to watch all the src files and folders?
According ts-node-dev documentation the command is:
ts-node-dev --respawn --transpileOnly <YOUR TS FILE>
You should try on your start script on package.json:
"dev": "ts-node-dev --respawn --transpileOnly --watch src,db,swagger,test src/main.ts"
"start": "node dist/src/main.js"
In your tsconfig.json file, you should have the outDir config, this config defines the folder that you compiled code will be placed, for instance, look at my tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "ES2017",
"moduleResolution": "node",
"outDir": "./dist",
"strict": true,
"strictPropertyInitialization": false,
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"exclude": ["node_modules"],
"include": [
"./src/**/*.tsx",
"./src/**/*.ts",
"src/__tests__",
"./src/**/*",
]
}
I have the outDir config, when I run tsc or npm run build, a dist folder will be created, and inside there's will be all my .js files

Resources