有没有一种使用npm脚本运行tsc -watch && nodemon --watch的方法?

112

我希望找到一种使用npm脚本同时运行tsc --watch && nodemon --watch的方法。我可以单独运行这些命令,但是当我想同时运行它们时,只有第一个被执行。

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

tsc --watch被执行了,但是nodemon从来没有被调用,反过来亦然。


这里还有很多其他实现方法:https://dev59.com/T1oT5IYBdhLWcg3w8jJm - bmaupin
在UNIX系统中,您可以执行tsc --watch&nodemon --watch命令。注意这是单个&符号。 - Guilherme Ferreira
11个回答

183

我认为你想要的是类似于这样的东西(我的当前设置):

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

我创建了两个脚本"compile"和"dev"。要开始开发,只需运行npm run dev,它会启动nodemon并让其监视.ts文件(使用-e标志)。然后,每当一个.ts文件更改时,nodemon将exec编译任务,基本上编译并运行node应用程序。

虽然同时使用是一个不错的选择,但我的设置保证在尝试执行结果为.js文件之前完成了tsc的工作。


11
tsc -w使用增量编译和缓存已解析的文件,因此编译速度应该更快。这就是为什么我喜欢同时运行tsc -w和nodemon的原因。 - Andzej Maciusovic
5
如果同时使用,它将同时运行两个任务。如其他回答所述,这样做的问题是nodemon在tsc编译完成之前就启动了,因此它无法提供最新的更改。请参阅Nicolas Dominguez的评论。 - AlterX
3
太棒了!感谢@AlterX。对于所有读者,如果您的TypeScript文件在子文件夹中(例如“src”),则需要运行以下命令:nodemon --watch src/ --exec \"npm run compile\" --verbose -e ts - Benny Code
1
更好的写法: "start": "nodemon -w src --exec 'npm run compile'"
  1. nodemon 的路径不是必需的。
  2. 我必须添加一个监视路径 (-w src),否则它会一直重建,因为目标(这里是 dist)也被监视了。
首先将 nodemon 添加到 devDependencies 中: npm i -D nodemon
- Marc Wäckerlin
1
  1. 不需要指定nodemon的路径
  2. 您可以连接多个命令
  3. 为什么不使用tsc --incremental来提高速度?将其组合起来看起来是这样的:"dev": "nodemon -e ts --watch src --exec \"tsc --incremental && node app.js\"",
- bmaupin
显示剩余8条评论

143

我已经使用AlterX的解决方案有一段时间了,它一直运行得非常完美,但我发现速度有点慢。因此,我现在使用tsc-watch。它使tsc使用增量编译类似于-w标志,可以使应用程序重新启动得更快。

像这样在你的package.json中添加类似的代码即可:

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

3
这是一个很棒的解决方案!我能够像这样在回调中链接多个命令:--onSuccess "sh -c 'babel && uglifyjs'" - Adam Mazzarella
3
如果速度很重要,比被认可的答案更好。 - jugglingcats
这篇文章终结了我长达3.5天的寻找解决gulp-typescript和gulp-sourcemap管道问题的历程。如果早些时候发现就好了...对于下一个读者:如果您执行node --inspect .,并添加一个简单的任务来附加,那么vscode调试器可以附加到此处。另外,安装apt上的notify-send可能会很方便,并在--onFailure事件上使用它来发送系统通知。 - MagicLegend
11
最佳答案,另外在npm脚本中不需要指定模块路径,下面这个命令就可以正常工作 - "tsc-watch --onSuccess \"node dist/index.js\"" - Dominic
1
我们发现tsc-watch存在很多问题,包括重启次数过多和无法正确终止正在运行的进程。因此,我不能推荐使用tsc-watch - dimiguel
显示剩余10条评论

33

尝试将以下内容添加到您的 package.json 文件中:

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

同时将这些npm包(concurrently、nodemon、typescript)添加到你的package.json中:

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

10
唯一的问题是nodemon在typescript完成工作前就开始了,一个可行的hack解决方案可能是给nodemon设置延时,例如nodemon --delay x,这将给tsc留出一些时间。 - Nicolas Dominguez
@AlterX 是的,但是tsc --watch不是更高效吗? - Alex Booker
@AlexBooker 可能是这样,但对于这个特定的用例不起作用,因为我们无法保证在运行之前tsc已经完成。 实际上,这意味着您无法保证nodemon正在运行的代码包括最新的更改,这也是首先观察更改的全部意义所在。 明确一点,如果您同时使用concurrently,那么两个任务将同时运行,这意味着您将同时运行tscnodemon,由于tsc需要一些时间来编译,因此nodemon可能不会选择最新的更改,因为它将在tsc完成之前启动。 - AlterX
11
我的解决方案是使用tsc-watchtsc-watch --onSuccess \"node ./bin\"。你觉得怎么样? - Alex Booker
1
tsc-watch非常好用;在我的package.json文件中的dev脚本中:"tsc-watch --onSuccess \"nodemon\"" - Leo
显示剩余3条评论

22

发生了什么

问题在于有两个文件的监视器。一个是tsc -w,另一个是nodemon

当对.ts文件进行更改时,tsc会检测到并编译它,并在目标文件夹中创建.js版本。

现在从Nodemon的角度来看,它检测到两个变化(至少)——一个是.ts,一个是.js。在第一次变化时,它会重新启动自己,但在第二次变化时,它不知道已经有另一个“启动”正在进行中,因此尝试再次重启,但失败了。对我来说,这是一个nodemon的bug,参见https://github.com/remy/nodemon/issues/763

解决方案

1)使用tsc-watch --onSuccess

tsc-watch具有--onSuccess,您可以在其中放置node。这样你就只有一个监听器。

2)延迟nodemon重新启动

您可以轻松延迟nodemon重新启动(请参见--delay)。这需要最少的设置更改。

3)只监视TSC的目标文件夹

我无法将其设置好,但这种方式nodemon希望只检测到一个更改。这可能会在未来或当tsc生成多个文件时引起问题。


2
谢谢,我使用了tsc-watch,它完美地工作了。我只是在package.json中添加了"start": "node_modules/.bin/tsc-watch --onSuccess 'node ./src/app.js'",现在可以通过npm start很好地运行了 :) - Blingers
1
"tsc-watch" 对于我的使用情况非常有效。 - Matthew

10

我的解决方案是在2018年10月使用最新版本的nodemon

第一步:
安装nodemon(npm install nodemon --save-dev)和ts-node(npm install ts-node --save-dev)

第二步:
创建nodemon.json。我喜欢将我的nodemon配置文件保持在一个单独的nodemon.json文件中,以使npm脚本更容易阅读。因此,在项目根目录中创建nodemon.json并添加以下内容:

{
    "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"
}
然后创建您的npm start脚本,例如像这样:
"scripts": {
    ...
    "start": "ts-node src/server.ts",
    "dev:ts": "nodemon",
    ...
  }

然后运行 npm run dev:ts 或者 yarn dev:ts 就可以运行并监视你的TypeScript服务器代码。

要获取其他配置,例如Jest单元测试等,请参阅此文章


如果 nodemon.json 不在与 package.json 相同的目录中怎么办? - CodyBugstein
1
同时,使用nodemon和ts-node存在一些严重的问题。请参见https://github.com/remy/nodemon/issues/1025 - CodyBugstein
是的,你说得对。但大多数问题都与Unix和OSX相关的操作系统有关。我在Windows下使用vscode和powershell/git bash从未遇到过这个问题。我会在其他系统上检查一下。 - billyjov
对于你的第一个问题,你也可以在 package.json 中使用 nodemonConfig 键来配置 nodemon。这里有一个相关的工作流程:https://alligator.io/workflow/nodemon/ - billyjov

7
TypeScript-Node-Starter 很快。 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"

这里我们使用concurrently -nnpm run watch-ts命名为TypeScript,并通过使用concurrently -c添加颜色yellow.bold。这样我就可以很容易地识别每个进程的消息了。

4

3
这里还有另一种方法,可以在启动nodemon之前,在你的concurrently命令中使用sleep
例如:
"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"
  },

在我的情况下,我同时生成客户端和服务器 TypeScript 项目,这导致在执行 npm run dev 时 nodemon 实际上启动了三次。但如果我在启动 nodemon 进程之前等待5秒钟,那么两个 tsc 进程都已经完成,然后继续监视。
您也可以使用 nodemon 的延迟选项,但我只需要在第一次执行npm run dev时延迟。之后,每个文件重新编译都会正确地重新启动 nodemon。
警告,如果您的服务器很慢,您可能需要将等待时间增加到5秒以上。
此外,我确实尝试了被接受的答案,但我的解决方案在 nodemon 和 tsc 监听进程继续运行时更快。 对于我的解决方案,每次重新编译只需要1秒,而对于被接受的答案,则需要5秒。由于每个 TypeScript 项目都在每次更改时进行完整的重新编译,因此我无法让被接受的答案实际上运行 tsc 在 watch 模式下,这就是为什么它更慢的原因。

1
您可以直接使用ts-node运行.ts文件。只需全局安装它,nodemon会自动使用ts-node

1

简单来说;nodemon监听tsc的输出(即.js文件)的变化。

你想要设置nodemon监视tsc --watch何时完成,正如其他评论中所暗示的那样,所以只需要求它监视tsc的目标目录中.js文件的更改。

例如,在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",
  ...
}

同时在 src/tsconfig.json 文件中:

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

在哪里?

  • --watch <folder> 将指向您在 tsconfig.json 文件的 compilerOptions->outDir 中定义的相同位置,
  • -e js 仅会监视 JavaScript 文件的更改,并且
  • --exec <some arbitrary thing to run> 让 nodemon 运行不止 node.js 脚本。

如果您想让 nodemon 运行的东西是一个 node 脚本,它可以进一步简化为只有 nodemon --watch dist -e js my-node-script.js

注意:如果您发现 nodemon 启动其脚本太快,您可以通过 --delay 增加检查更改的节流延迟


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接