Nodemon教程。用Nodemon自动重启Node.js应用程序

1,854 阅读12分钟

简介

在开发环境中,尤其是那些涉及大量迭代的环境,当我们对源代码进行修改时,我们不希望手动重启我们的服务器或后端应用程序。

这是Nodemon解决的一个问题。它作为一个实用程序库来跟踪服务器的变化,并自动为我们重新启动我们的应用程序。

根据文档,Nodemon是在基于Node.js的应用程序中开发的完美工具。事实上,它是在考虑到Node的CLI命令的属性后建立的,因为它是一个围绕node 命令的包装。

基本上,它的工作原理是检测我们源代码当前目录中的变化,并重新启动服务器以迎合这些新的变化。

回顾一下,为了运行一个Node.js应用程序,我们以node 命令开始,并附加上文件名。在使用Nodemon的开发中,我们需要做的就是运行Nodemonfilename ,Nodemon将为我们观察我们的文件。

然而,为了使用Nodemon,我们需要在我们的机器上全局安装它,或者在本地以每个项目为基础安装。

当以项目为单位安装时,我们需要做的就是更新我们项目的package.json 文件中的script 标签。要在开发模式下使用Nodemon,我们可以在同一文件中的script 标签中添加一个"dev": "nodemon app.js" 行。

全局安装后,Nodemon在我们的系统路径上是可用的,并且开箱即用。

在本教程中,我将通过探索Nodemon的功能以及如何使用它们来解释Nodemon是如何工作的。

我们将涵盖以下内容。

  • 什么是Nodemon?
  • 在本地和全球范围内安装Nodemon
  • Nodemon的配置和使用
  • Nodemon的功能

为了跟上本教程,读者应该对Node.js和Express有一个基本的了解。

什么是Nodemon?

正如我前面提到的,Nodemon是一个实用程序或辅助工具,它观察文件的变化,并自动重新启动我们的Node.js应用程序。它是开源的,维护良好,在社区中被很多人使用。

要查看可用的Nodemon命令的列表,我们可以使用-h 标志或下面显示的--help 标志。所以我们可以选择运行。

nodemon -h 
 //or 
nodemon --help

在开发基于Node.js的应用程序时,我们应该使用Nodemon,这有几个原因。

首先,它非常容易设置。其次,一旦它被安装,它就会自动运行,因为它不需要调用任何实例,最后,它有助于开发环境的快速迭代。

现在,让我们在下面探讨如何安装Nodemon。

安装Nodemon

正如我们前面提到的,Nodemon既可以全局安装在我们的系统路径上,也可以在本地作为一个开发依赖。

要在我们的路径上全局安装Nodemon,我们可以继续运行下面的命令,并加上全局-g 标志。

npm install -g nodemon

这意味着该软件包可以在我们的开发机器上从系统路径中使用和运行。

否则,我们可以运行。

npm install --save-dev nodemon

上述命令将在我们的机器上本地安装Nodemon,或者作为一个开发依赖项。请注意,我们是将Nodemon作为开发依赖项安装的,标志是--save-dev ,因为我们不希望它成为生产依赖项。

当Nodemon被全局安装后,我们不需要在本地环境中做任何其他设置,因为我们可以从系统中的任何路径运行Nodemon,它将为我们监视我们的源文件。

运行上述命令后,我们的package.json 文件将被修改,Nodemon库及其版本号将被保存在键"devDependencies" ,如下图所示。

{
  "name": "test-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
}
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }
{
  "author": "",
  "license": "ISC",
  "private": false,
  "devDependencies": {
    "nodemon": "^2.0.7"
  },
 }

作为一个开发依赖,我们需要做的就是在我们的package.json 文件中添加一个dev 脚本,以便能够在我们的本地设置中使用Nodemon。现在让我们通过展示一个简单的Node.js应用程序来了解Nodemon的所有功能和配置选项。

让我们从位于app.js 文件中的服务器设置开始。该文件的内容如下所示。

require('dotenv').config()
require('./mongoClient')

const express = require('express')
const config = require('./config')
const routes = require('./routes')
const app = express()

// add routes here
routes(app)

// catch 404 and forward to error handler
app.use((req, res, next) => {
    const err = new Error('Not Found')
    console.log(err)
    err.status = 404
    res.send('Route not found')
    next(err)
})

app.listen(process.env.PORT || config.port, () => {
    console.log(`${config.appName} listening on port ${config.port}!`)
})

module.exports = app

让我们也来看看如何使用Nodemon来运行这个服务器文件。在我们的项目中使用Nodemon的非常基本和最小的设置,在位于根目录的package.json 文件中显示如下。

{
  "name": "nodemon_tutorial",
  "version": "1.0.0",
  "description": "A Tutorial for Understanding Nodemon",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "directories": {
    "model": "model",
    "controllers": "controllers"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "keywords": [
    "Node.js",
    "JavaScript"
  ],
  "author": "Alexander Nnakwue",
  "license": "MIT",
  "devDependencies": {
    "nodemon": "^2.0.4"
  },
  "dependencies": {
    "bcrypt": "^5.0.1",
    "debug": "^4.1.1",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "express-async-handler": "^1.1.4",
    "mongoose": "^5.9.25",
    "mongoose-paginate": "^5.0.3",
    "path": "^0.12.7",
    "uuidv4": "^6.2.0"
  },
  "engines": {
    "node": "13.7.0",
    "npm": "6.13.6"
  }
}

正如我们可以从下面的脚本标签中看到的设置。

"scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },

因此,当我们运行npm run dev ,它运行Nodemon并为我们观察我们的文件。

当我们用Nodemon运行该文件时,其内容如下所示。

[nodemon] clean exit - waiting for changes before restart
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
(node:97775) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
Nodemon_tutorial listening on port 5000!
mongodb connected
Mongoose: users.createIndex({ email: 1 }, { unique: true, background: true })
Mongoose: users.createIndex({ phoneNumber: 1 }, { unique: true, background: true })

这个脚本的任何输出都以[nodemon] 为前缀,否则所有来自你的应用程序的输出,包括错误,都会按预期回显出来。

package.json 文件中加入--inspect 标志(对监听调试器的Node.js进程很有用),当我们运行npm run dev ,输出结果如下。

retina@alexander backend-server % npm run dev

> nodemon_tutorial@1.0.0 dev /Users/retina/Dropbox/My Mac (alexander)/Desktop/nodemon_tutorial/nodemon_tutorial
> nodemon --inspect app.js

[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node --inspect app.js`
Debugger listening on ws://127.0.0.1:9229/8618d563-210c-4070-bed5-b077016abae2
For help, see: https://nodejs.org/en/docs/inspector
(node:98970) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
Nodemon_tutorial listening on port 5000!

1.1.x 版本开始,Nodemon会在当前工作目录下的package.json 文件中搜索到scripts.start 属性或main 属性,并为我们启动应用程序。

让我们来试试这个。

(aba) retina@alexander backend-server % nodemon
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
(node:99661) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
Nodemon_tutorial listening on port 5000!
mongodb connected
Mongoose: users.createIndex({ email: 1 }, { unique: true, background: true })
Mongoose: users.createIndex({ phoneNumber: 1 }, { unique: true, background: true }) 

正如我们从上面看到的,我们的应用程序仍然可以正常工作。注意,在这里,我删除了package.json 文件中的scripts 属性,只用nodemon 命令重新运行应用程序。

// delete the script tag and run nodemon afresh
"scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  }

为了使其工作,我们需要在我们的系统路径中全局安装nodemon 。当我们运行命令npm i nodemon -g ,全局安装Nodemon时,输出结果如下。

retina@alexander ~ % npm i nodemon -g
/usr/local/bin/nodemon -> /usr/local/lib/node_modules/nodemon/bin/nodemon.js

> nodemon@2.0.7 postinstall /usr/local/lib/node_modules/nodemon
> node bin/postinstall || exit 0

+ nodemon@2.0.7
added 120 packages from 57 contributors in 13.404s

Nodemon的配置和使用

Nodemon支持本地和全局配置,就像我们可以在全局或每个项目上配置系统一样。

对于本地设置,我们可以在项目的当前工作目录下设置一个nodemon.json 文件,对于全局设置,我们可以在系统的主路径下设置同样的文件。

此外,我们还可以在项目的package.json 文件中设置一个nodemonConfig ,以方便那些喜欢把所有软件包配置放在一个地方的人。

请注意,当涉及到执行哪些配置时,这些配置会有一个注意事项。如果我们指定一个--config 文件或提供一个本地nodemon.json 文件,任何package.json 配置都会被忽略。

正如你可能已经注意到的,有三种方式来配置Nodemon的开发--本地、全局和通过Node CLI。当我们输入nodemon --help options ,我们就可以看到所有可用的CLI选项供我们使用。

关于配置Nodemon的可用方式的更多信息,我们也可以在我们的终端上输入*nodemon --help config*

通常情况下,控制Nodemon的选项是通过CLI传入的,当我们运行nodemon --help option ,就可以列出。

现在,让我们来看看一些配置,我们可以通过向配置(--config)文件或我们的nodemon.json 文件传递更多的参数来增加这些配置。在开发我们的项目时,这些配置中的一些可能是有用的。让我们看一下下面的一些配置。

监控多个目录

Nodemon默认监控当前的工作目录,但这可以通过使用--watch 选项添加特定的路径来改变。

例如,我们可以通过运行下面的命令,指示Nodemon只监视我们的services 目录或nodemon_tutorial 目录中的app.js 文件的变化。

nodemon --watch nodemon_tutorial/app.js --watch services 

总是为我们打算监视的每个目录添加一个--watch 标志。这通常是在传递多个目录时才需要的。

忽略文件

由于Nodemon在默认情况下会在文件发生变化时重新启动网络服务器,我们可以通过配置Nodemon来有效地改变这一默认设置,即通过命令行忽略一些特定文件、目录或文件模式中的变化。

请看下面的一个例子,我们忽略了tests 文件夹。

nodemon --ignore tests/ 

上述命令,当运行时,将自动忽略在tests 文件夹中所作的任何更改。另外,请注意,默认情况下,Nodemon会忽略node_modules.git 文件夹中的文件。很神奇吧?让我们继续前进。

推迟重启

检查新文件变化的默认超时时间通常是一秒左右。然而,在有些情况下,我们打算将Nodemon检查文件变化的时间延迟更长。

我们可以通过使用--delay 命令来做到这一点。见下面的代码示例。

nodemon --delay 3000ms index.js  

3000ms 是我们的应用程序重新启动前的延迟值,单位是毫秒(这也可以是秒)。因此,Nodemon只有在这个时间过后才会重新启动网络服务器。

要监视的扩展

当目录或子目录中的文件发生变化时,我们可以指定要监视的扩展。

例如,我们可以用-e (或--ext )命令行参数指定我们自己的列表。见下面的代码示例。

nodemon -e njk

默认情况下,Nodemon寻找具有.js,.mjs,.coffee,.litcoffee, 和.json 扩展名的文件。

运行非Node代码

除了Node程序之外,Nodemon还可以用来监视其他程序。根据文件的扩展名,Nodemon会去执行该命令。

关于运行非Node代码的更多细节,读者可以查看文档

当Nodemon运行时,我们可以手动重新启动我们的应用程序。因此,我们不必停止和重启Nodemon,只需输入rs ,然后按回车键,Nodemon就会为我们重启服务器或运行的进程。

Nodemon的特点

管道输出到一个文件(或其他任何地方)

我们可以通过指定一组规则来告诉Nodemon不要写到stdout 。更多的细节可以在文档中找到

添加默认的可执行文件

Nodemon,在nodemon.json 配置文件的帮助下,可以有一个默认的可执行文件声明。这将反过来让我们观察不属于node.js 的变化。

要做到这一点,我们可以利用execMap 属性。请注意,通常建议使用全局的nodemon.json ,以在我们的配置中添加一个execMap 选项。你可以在文档中阅读更多细节

在状态变化时触发事件

我们可以在Nodemon重新启动时添加一个通知。另外,当一个事件发生时,可以触发一个动作。关于这个的更多细节可以在文档中找到

可作为一个模块使用

从1.0.0版本开始,Nodemon可以作为Node.js中的一个必要模块工作。通过这样做,我们就可以扩展它的功能,使之适合我们的其他需求。

更多细节可以在这里的文档中找到。

总结

在Node.js中,Nodemon可以被比喻为一个魔杖,因为它能够在文件变化时自动重启网络应用。换句话说,Nodemon简单地消除了程序员在开发过程中每次修改后都要反复手动停止和重启应用源代码的需要。

它是一个实用的工具,使快速开发不再繁琐。作为一个工具,它持续监控你的Node.js应用程序,并在自动重启服务器之前安静地等待文件变化。为了增加一些额外的配置,我们可以利用一个nodemon.json 文件。

该文件可用于向我们的应用程序添加一些额外的配置,以允许我们监控多个目录,忽略文件,以及延迟重启等。关于Nodemon如何工作的更多细节和 "故障",以及可能的解决问题的方法,读者也可以参考FAQ

FAQ文档还包含一些我们可以参考的其他技巧和窍门,包括本教程中没有提到或涉及的Nodemon的其他使用情况。

例如,重启时清除控制台,在.env 文件变化时重启Nodemon,覆盖默认的忽略规则,等等。GitHub上有一个文档的链接。

再次感谢您的阅读。如果你有任何意见或问题,请在下面的评论区提出,或者在Twitter上联系我。

The postNodemon tutorial:使用Nodemon自动重启Node.js应用程序,首先出现在LogRocket博客上。