Nicolas Dominguez
Nicolas Dominguez

Reputation: 1343

Is there a way to use npm scripts to run tsc -watch && nodemon --watch?

I'm looking for a way to use npm scripts to run tsc --watch && nodemon --watch at the same time. I can run these commands independently, but when I want run both of them, only the first one is executed. eg:

"scripts": {    
  "runDeb": "set NODE_ENV=development&& tsc --watch && nodemon --watch"
}

tsc --watch is executed but nodemon is never called, and vice versa.

Upvotes: 122

Views: 131983

Answers (12)

Ice Mann
Ice Mann

Reputation: 11

In case anyone is looking for a solution that involves no fancy stuff and no extra dependencies, and that just works, I got it. The solution is surprisingly simple: This is his original command:

tsc --watch && nodemon --watch

This is the solution:

tsc --watch & nodemon --watch

Instead of && use & and the processes will execute and exist simultaneously. Works like a charm!

Upvotes: 1

Jonathan Sanchez
Jonathan Sanchez

Reputation: 9444

Simple way to have nodemon watching the .ts files

Add this script to your package.json

"scripts": {
    "start": "nodemon --exec ts-node-esm ./src/*.ts",
},

Install ts-node to your devDependencies with npm i ts-node -D

Then you could run npm run start or with yarn start

enter image description here

here is a medium article in regards https://medium.com/@jonathans199/how-to-create-a-simple-node-api-with-typescript-4ab631b43503

Upvotes: 4

M. Emre Yalçın
M. Emre Yalçın

Reputation: 654

You can directly run .ts files with ts-node. Just install it globally and nodemon will use ts-node automatically.

Upvotes: 1

Borre Mosch
Borre Mosch

Reputation: 4564

I have been using AlterX's solution for a while now and it has worked perfectly, but I have found it to be rather slow. Instead, I am now using tsc-watch. It makes tsc use incremental compilation similar to the -w flag, making the restart of the application much faster.

It's as easy as putting something similar to this in your package.json:

"scripts": {
  "start": "tsc-watch --onSuccess \"node .\""
}

Upvotes: 154

Brad P.
Brad P.

Reputation: 308

TL;DR; Have nodemon watch for changes in tsc's output (i.e. .js files)

You want nodemon set up to monitor when tsc --watch is finished, as some have alluded to in other comments, so just ask it to watch the destination directory of tsc for changes in .js files.

For example, in package.json:

"scripts": {
  ...
  "watch": "tsc --build src/tsconfig.json --watch",
  "watch-tests": "nodemon --watch dist -e js --exec \"yarn run tests\"",
  "tests": "some script to run my tests",
  ...
}

and in src/tsconfig.json:

{
...
  "compilerOptions": {
    "outDir": "../dist",
    ...
  },
...
}

Where

  • --watch <folder> will point to the same place that you have defined in your compilerOptions->outDir from your tsconfig.json file,
  • -e js will only watch for changes in javascript files, and
  • --exec <some arbitrary thing to run> let's nodemon run more than just node.js scripts.

If the thing you want to have nodemon run is a node script, it can be further simplified to just nodemon --watch dist -e js my-node-script.js

Note: If you find nodemon kicking off it's script too soon, you can increase the throttle delay for checking for changes with --delay

Upvotes: 1

Sean Bradley
Sean Bradley

Reputation: 3577

Here is another way, use sleep in your concurrently command before starting nodemon.

eg,

"scripts": {
    "dev": "concurrently -k \"tsc -p ./src/server -w\" \"tsc -p ./src/client -w\" \"sleep 5 && nodemon ./dist/server/server.js\"",
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node ./dist/server/server.js"
  },

In my situation, I generate both client and server typescript projects at the same time, which causes nodemon to actually start 3 times when I execute npm run dev. But if I sleep 5 seconds before starting the nodemon process, then both tsc processes have already finished, and then continue watching.

You could also use the delay option of nodemon, but I only need it to delay the first time when I execute npm run dev. After that, every individual recompilation of which ever file in whichever project, correctly restarts nodemon only once.

caveat, If your server is slow, you may need to increase the sleep delay longer than 5.

Also, I did try the accepted answer, but my solution was faster for subsequent recompilations while nodemon and the tsc watch processes continued to run.

1 second for my solution, versus 5 seconds for the accepted. I couldn't get the accepted answer to actually run tsc in watch mode, so that's why it was slower, since both TypeScript projects were getting a full recompile on every change.

Upvotes: 3

Aidin
Aidin

Reputation: 30097

What's going on

The problem is there are two watchers here on all the files. One is tsc -w and one is nodemon.

When a change to a .ts file is made, tsc detects that, compiles it, and creates the .js version in your destination folder.

Now from the Nodemon's perspective, it detects two changes (at least) -- one for .ts and one for .js. On the first change it restarts itself, but on the second change it doesn't know that another "start" is going on already, so it tries to restart again and it fails. To me it's a nodemon bug -- see https://github.com/remy/nodemon/issues/763.

Solutions

1) Use tsc-watch --onSuccess

tsc-watch has --onSuccess which you can put node on there. This way you will have only one watcher.

2) Delay nodemon

You can easily delay nodemon restarts (See --delay). It requires the least set up change.

3) Have nodemon only monitor destination folder of TSC

I couldn't get it to set up, but this way nodemon will detect only one change hopefully. It might cause problems in future or when tsc generates multiple files.

Upvotes: 24

Coyolero
Coyolero

Reputation: 2433

The TypeScript-Node-Starter is fast

https://github.com/microsoft/TypeScript-Node-Starter/blob/master/package.json

"dev": "concurrently -k -n \"TypeScript,Node\" -c \"yellow.bold,cyan.bold\" \"npm run watch-ts\" \"nodemon ./dist/app.js\"",
"watch-ts": "tsc -w"

Here we are giving npm run watch-ts the TypeScript name (by using concurrently -n) and adding the color yellow.bold by using the concurrently -c.

So, I can recognize pretty easy the messages for each process.

Upvotes: 7

Kushal Kulle
Kushal Kulle

Reputation: 13

Normal compilation is: if file name is main.ts

step 1: tsc main.ts

step 2: node main.js

Simple and Onetime(loop) compilation:

tsc main --watch

Upvotes: -5

billyjov
billyjov

Reputation: 2970

My solution in october 2018 using newest versions of nodemon.

first:
install nodemon(npm install nodemon --save-dev) and ts-node(npm install ts-node --save-dev)

second:
create a nodemon.json . I like to keep my nodemon config in a seperat nodemon.json to make the npm scripts a tad easier to read. So create nodemon.json in the root of the project with the following content:

{
    "ignore": ["**/*.test.ts", "**/*.spec.ts", ".git", "node_modules"],
    "watch": ["src"], // your .ts src folder
    "exec": "npm start", // your npm script created in package.json
    "ext": "ts"
}

then create your npm start script e.g like this:

"scripts": {
    ...
    "start": "ts-node src/server.ts",
    "dev:ts": "nodemon",
    ...
  }

Then run npm run dev:ts or yarn dev:ts should run and watch your typescript server code.

For more configs like Jest units tests etc... you can take a look into this article

Upvotes: 11

AlterX
AlterX

Reputation: 2221

I think what you want is something like this (my current setup):

"scripts": {
    "compile": "tsc && node app.js",
    "dev": "./node_modules/nodemon/bin/nodemon.js -e ts  --exec \"npm run compile\""
}

I created two scripts "compile" and "dev". To start developing you simply run npm run dev which starts nodemon and makes it watch .ts files (using the -e flag). Then, every time a .ts file changes nodemon will exec the compile task which basically compiles and runs the node app.

While using concurrently is a good option, my setup guarantees that tsc's work is done before attempting to execute the resulting .js files.

Upvotes: 188

Alexander
Alexander

Reputation: 367

Try to add this to your package.json:

"scripts": {
  "start": "concurrently --kill-others \"tsc -w\" \"nodemon dist/app.js\"",
}

And also add this npm packages (concurrently, nodemon, typescript) to your package.json:

"devDependencies": {
  "concurrently": "^2.2.0",
  "typescript": "^1.8.10",
  "nodemon": "^1.9.2",
}

Upvotes: 34

Related Questions