'How to watch and reload ts-node when TypeScript files change
I'm trying to run a dev server with TypeScript and an Angular application without transpiling ts files every time.
What I found is that I can run .ts
files with ts-node
but I want also to watch .ts
files and reload my app/server. An example of this is the command gulp watch
.
Thank you in advance!!
Solution 1:[1]
You can now simply npm install --save-dev ts-node nodemon
and then run nodemon
with a .ts
file and it will Just Work:
nodemon app.ts
Previous versions:
I was struggling with the same thing for my development environment until I noticed that nodemon
's API allows us to change its default behaviour in order to execute a custom command.
For example, for the most recent version of nodemon
:
nodemon --watch "src/**" --ext "ts,json" --ignore "src/**/*.spec.ts" --exec "ts-node src/index.ts"
Or create a nodemon.json
file with the following content:
{
"watch": ["src"],
"ext": "ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node ./src/index.ts" // or "npx ts-node src/index.ts"
}
and then run nodemon
with no arguments.
By virtue of doing this, you'll be able to live-reload a ts-node
process without having to worry about the underlying implementation.
Cheers!
And with even older versions of nodemon
:
nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec 'ts-node' src/index.ts
Or even better: externalize nodemon's config to a nodemon.json
file with the following content, and then just run nodemon
, as Sandokan suggested:
{
"watch": ["src/**/*.ts"],
"ignore": ["src/**/*.spec.ts"],
"exec": "ts-node ./index.ts"
}
Solution 2:[2]
I've dumped nodemon
and ts-node
in favor of a much better alternative, ts-node-dev
https://github.com/whitecolor/ts-node-dev
Just run ts-node-dev src/index.ts
Solution 3:[3]
Here's an alternative to the HeberLZ's answer, using npm scripts.
My package.json
:
"scripts": {
"watch": "nodemon -e ts -w ./src -x npm run watch:serve",
"watch:serve": "ts-node --inspect src/index.ts"
},
-e
flag sets the extenstions to look for,-w
sets the watched directory,-x
executes the script.
--inspect
in the watch:serve
script is actually a node.js flag, it just enables debugging protocol.
Solution 4:[4]
This works for me:
nodemon src/index.ts
Apparently thanks to since this pull request: https://github.com/remy/nodemon/pull/1552
Solution 5:[5]
Specifically for this issue I've created the tsc-watch
library. you can find it on npm.
Obvious use case would be:
tsc-watch server.ts --outDir ./dist --onSuccess "node ./dist/server.js"
Solution 6:[6]
you could use ts-node-dev
It restarts target node process when any of required files changes (as standard node-dev) but shares Typescript compilation process between restarts.
Install
yarn add ts-node-dev --dev
and your package.json could be like this
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"tsc": "tsc",
"dev": "ts-node-dev --respawn --transpileOnly ./src/index.ts",
"prod": "tsc && node ./build/index.js"
}
Solution 7:[7]
Summary of options from other answers
- nodemon plus ts-node is pretty stable but needs to be explicitly configured and is somewhat slow
- node-dev plus ts-node requires much less configuration than nodemon but is still slow
- ts-node-dev is fast but unreliable
Alternative 1: nodemon/node-dev + ts-node + swc
? TL;DR: fastest
An alternative option that combines the reliability of nodemon/node-dev with the speed of ts-node-dev is to use ts-node with swc
, a TypeScript-compatible transpiler implemented in Rust which is an "order of magnitude faster" than the TypeScript transpiler.
Note that swc
does not do type checking, which should be acceptable since most editors have type checking built-in, and type checking should still be part of your build process.
Install nodemon or node-dev (whichever you prefer)
nodemon
npm install --save-dev nodemon
node-dev
npm install --save-dev node-dev
Set up ts-node with swc integration
https://github.com/TypeStrong/ts-node#swc-1
Install necessary packages
npm install --save-dev ts-node @swc/core @swc/helpers regenerator-runtime
Add this to tsconfig.json
"ts-node": { "swc": true }
Run nodemon or node-dev, e.g
nodemon --watch src src/index.ts
or:
node-dev src/index.ts
Alternative 2: nodemon/node-dev + ts-node transpileOnly
? TL;DR: fast, reliable
Here's an alternative that's slower than the previous option because it uses the standard TypeScript transpiler, but in my testing it's still faster than nodemon/node-dev + ts-node.
Basically it's the same as the previous option but without swc
. It's faster than out-of-the-box ts-node by disabling type checking (see notes above regarding why this should be acceptable).
Install nodemon/node-dev as above
Install ts-node
npm install --save-dev ts-node
Modify your tsconfig.json to enable
transpileOnly
for ts-node"ts-node": { "transpileOnly": true }
Call nodemon/node-dev as above
Alternative 3: nodemon + tsc --incremental
? TL;DR: fast, reliable, fewest dependencies, more finicky
This is nearly the same speed as the previous alternative. Out of the three options, this requires the least dependencies (just nodemon, plus the TypeScript compiler, which you already have installed if you're using TypeScript).
(It's possible that this may work with node-dev as well, but I didn't see an exec
option for node-dev)
In terms of downsides, it can be a bit more finicky; in my testing, I'm using dotenv
to pick up my .env
file for local development. But depending how your tsc
build is configured in tsconfig.json, you may have to do some acrobatics to get it working.
But it's good to have options, so here it is:
Install nodemon as above
Configure tsconfig.json to transpile your TypeScript to JavaScript
In particular,
noEmit
should not be set totrue
Configure nodemon to run the TypeScript compiler to do an incremental transpilation any time a TypeScript file is changed, e.g.
"dev": "nodemon -e ts --watch src .env --exec \"tsc --incremental && node src/index.js\"",
You can even remove
--incremental
to further simplify it, but it will end up being much slower, comparable to nodemon/node-dev + ts-node.
Solution 8:[8]
Add "watch": "nodemon --exec ts-node -- ./src/index.ts"
to scripts
section of your package.json
.
Solution 9:[9]
i did with
"start": "nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec ts-node src/index.ts"
and yarn start.. ts-node not like 'ts-node'
Solution 10:[10]
I would prefer to not use ts-node and always run from dist folder.
To do that, just setup your package.json with default config:
....
"main": "dist/server.js",
"scripts": {
"build": "tsc",
"prestart": "npm run build",
"start": "node .",
"dev": "nodemon"
},
....
and then add nodemon.json config file:
{
"watch": ["src"],
"ext": "ts",
"ignore": ["src/**/*.spec.ts"],
"exec": "npm restart"
}
Here, i use "exec": "npm restart"
so all ts file will re-compile to js file and then restart the server.
To run while in dev environment,
npm run dev
Using this setup I will always run from the distributed files and no need for ts-node.
Solution 11:[11]
add this to your package.json file
scripts {
"dev": "nodemon --watch '**/*.ts' --exec 'ts-node' index.ts"
}
and to make this work you also need to install ts-node as dev-dependency
yarn add ts-node -D
run yarn dev
to start the dev server
Solution 12:[12]
Another way could be to compile the code first in watch mode with tsc -w
and then use nodemon over javascript. This method is similar in speed to ts-node-dev and has the advantage of being more production-like.
"scripts": {
"watch": "tsc -w",
"dev": "nodemon dist/index.js"
},
Solution 13:[13]
STEP 1: You can simple install nodemon
and ts-node
(skip if you already done)
npm install --save-dev nodemon ts-node
STEP 2: You can configure the start script in package.json
"start": "nodemon ./src/app.ts"
As now nodemon automatically identify the typescript from the project now and use ts-node
command by itself. Use npm start
and it will automatically compile/watch and reload.
If you get any errors like typescript module not found in the project. simple use this command in the project folder.
npm link typescript
Solution 14:[14]
Just update these 3 packages
nodemon, ts-node, typescript
yarn global add nodemon ts-node typescript
or
npm install -g nodemon ts-node typescript
and now you can run this, problem solved
nodemon <filename>.ts
Solution 15:[15]
Clear logs of the console after changing
Javascript:
"start": "nodemon -x \"cls && node\" index.js",
Typescript:
"start": "nodemon -x \"cls && ts-node\" index.ts",
Solution 16:[16]
If you are having issues when using "type": "module"
in package.json
(described in https://github.com/TypeStrong/ts-node/issues/1007) use the following config:
{
"watch": ["src"],
"ext": "ts,json",
"ignore": ["src/**/*.spec.ts"],
"exec": "node --loader ts-node/esm --experimental-specifier-resolution ./src/index.ts"
}
or in the command line
nodemon --watch "src/**" --ext "ts,json" --ignore "src/**/*.spec.ts" --exec "node --loader ts-node/esm --experimental-specifier-resolution src/index.ts"
Solution 17:[17]
nodemon --watch source --ext ts,json --exec "node --loader ts-node/esm ./source/index.ts"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow