Running script when ts-node-dev restarts server - node.js

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

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

NestJS prevent server reloading in development

I have a route which creates a new folder inside public directory which is a static content served with app.useStaticAssets.
The problem is that even if I added the public directory inside exclude array of both tsconfig.build.json and tsconfig.json, my server still reloads in development when a new folder is deleted or created inside public directory.
I'm missing something ?
UPDATE:
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"noImplicitAny": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"esModuleInterop": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
},
"exclude": ["node_modules", "dist", "public"]
}
I mention that public folder is outside of the src folder. They are on the same level.
I was able to reproduce this and found out that this seems to be a common issue -> https://github.com/nestjs/nest/issues/3510
As propsed in the github issue, adding include as a workaround seems to fix the problem:
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"noImplicitAny": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"esModuleInterop": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "public"]
}
If you want to completely disable hot reload temporarily, remove the --watch flag from your start:dev script.
Go into package.json
Find your "start:dev" script under "scripts"
Duplicate your "start:dev" script and rename it - I named it start:dev-noreload
Your script should look something like this:
"start:dev-noreload": "npm run prebuild && npm run kill:dev-process && npm run build:docker-postgres && env ENV=DEV nest start"
Run your app using
npm run start:dev-noreload
In order to get hot reload back, just run the way you normally do.
Either using npm start, or npm run start:dev.

How nestjs configures path aliases in a project

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.

How to debug node.js app running with TypeScript in WebStorm?

How to debug node.js app running with TypeScript in WebStorm?
Update tsconfig.json to add sourceMap=true property in compilerOptions
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"noImplicitReturns": true,
"outDir": "lib",
"target": "es6",
"preserveConstEnums": true,
"removeComments": false,
"sourceMap": true,
"inlineSources": true,
"typeRoots": [
"./node_modules/#types"
]
},
"exclude": [
"node_modules",
"lib"
]
}
In the Edit Run/Debug Configuration,
Write following line in Node parameters field. Don't forget to mention your port number! In my case it is 3000
--inspect=3000 --require ts-node/register
Mention your entry .ts file in Javascript file field. In my case it is bin/www.ts
Debug your newly created configuration

Resources