用 Nest.js 框架的命令行工具(nest)在本地创建了一个项目,在终端进入到这个项目所在的目录,然后运行了 npm run start:dev
命令,创建的应用就运行起来了,在编辑器里编辑项目文件,保存文件以后,应用的服务会自动重启。
命令是在哪里定义的?
Node.js 项目里面都会包含一个 package.json 文件,在这个文件里描述了项目的相关信息,比如项目的名字、作者、版本等等,这个文件还列出了项目依赖的包(Package)。Node.js 自带的 npm
这个工具可以帮我们管理项目依赖的这些包。
在 package.json 文件里面,还有一个 scripts
属性,它里面定义的就是项目里的一些命令,这些命令都有自己的名字,还有它真正要执行的是什么。
start:dev
比如在 Nest.js 项目的 package.json 里面,定义了一条命令是 start:dev
:
"scripts": { "start:dev": "concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\" ", },
在 scripts
里面定义的命令,运行它的时候可以使用 npm run
,后面再加上要运行的命令的名字,比如 npm run start:dev
。运行了这个命令,真正执行的是定义这个命令的时候冒号右边的东西,这里就是:
concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\"
也就是,如果我们不在 scripts
里面添加一个 start:dev
,想要运行 Nest.js 应用的开发服务,就要执行上面这么大长串的命令。
concurrently
start:dev
的一开始用了一个 concurrently 命令,它的作用就是同时运行多条命令,如果不用它的话,想同时运行多个命令大概像这样:npm run watch-js & npm run watch-css
,不同的命令之间用 &
连接。
使用它的时候加了一个 --handle-input
选项。这个选项的意思是:Whether input should be forwarded to the child processes(输入是否要转到子进程)。比如执行 nodemon
的时候,想手工重启可以输入一个 rs
然后执行一下, 执行 concurrently
加了 --handle-input
选项以后就会支持你这样做,比如输入的 rs
指令会转给 nodemon
。
wait-on
wait-on
这个命令就是等待指定的资源可用,这个资源指的是文件、端口、sockets、http(s)资源。wait-on dist/main.js
,意思应该就是等待一下 dist
目录下有了 main.js 这个文件。
nodemon
修改了 Node.js 应用以后,想看到修改之后的结果必须要重新启动应用服务,nodemon 可以监视特定文件的变化,有变化就会自动重新启动服务,所以我们就不用每次手动重启服务了。
wait-on dist/main.js
,等项目的 dist
目录里有了 main.js 以后,接着又会执行 nodemon
这个命令。执行这个命令用的相关配置可以放在一个 nodemon.json 配置文件里,打开项目里的这个文件,内容如下:
{ "watch": ["dist"], "ext": "js", "exec": "node dist/main" }
watch
(监视) 的是 dist
目录里的东西,ext
文件扩展后缀应该是 js
,exec
要执行的命令是 node dist/main
。意思应该就是如果 dist
目录里的 js
文件发生变化,就执行 node dist/main
这个命令。
tsc
tsc 是一个 TypeScript 编译工具,它的作用就是把 TypeScript 代码编译成普通的 JavaScript 代码。创建 Nest.js 应用我们写的是 TypeScript 代码,Node.js 并不认识 TypeScript,所以需要先把 TypeScript 编译成普通的 JavaScript 再交给 Node.js 去运行。
tsc -w -p tsconfig.build.json
-w
是 --watch
,表示监视。-p
是 --project
,用了这个选项会用到一个配置文件叫 tsconfig.json,比如 Nest.js 项目里的这个文件像下面这样:
tsconfig.json
{ "compilerOptions": { "module": "commonjs", "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es6", "sourceMap": true, "outDir": "./dist", "baseUrl": "./", "incremental": true }, "exclude": ["node_modules"] }
但在 Nest.js 框架里执行的这个 tsc
命令里面,手工指定了一个配置文件:tsconfig.build.json。
tsconfig.build.json
{ "extends": "./tsconfig.json", "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] }
它就是 extends
(扩展、继承)了一下 tsconfig.json
文件里的内容,它又加了一个 exclude
,设置了一下要排除的,不需要编译的目录还有文件。
总结
concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\"
按照 tsconfig.build.json 文件里的配置,用 tsc
会监视一些文件的变化,它会把项目里面需要编译的文件编译好放在 dist
目录的下面。当 dist
里面有了编译好的 main.js
以后,执行 nodemon
监视 dist
目录里的文件的变化,有变化就会重启服务。这样我们就可以立即使用编辑之后的项目了。上面这些命令,用 concurrently
同时运行。