JS 执行 shell 命令
背景
项目中需要使用 postinstall 脚本来完成执行 npm install
之后的任务,而如果需要在安装本身之后自动安装相关工具包,又不想作为依赖放在 package.json 中,就可以在 postinstall 脚本中执行 install 的命令,从而达到目的。
API
Node 提供了 child_process 的 API,可以新开一个子进程来执行 shell 命令,具体用法参考官方文档
exec() vs execSync()
exec()
方法最多可以接受两个参数,第一个参数是所要执行的 shell 命令,第二个参数是回调函数,该函数接受三个参数,分别是发生的错误、标准输出的显示结果、标准错误的显示结果。
1 | var exec = require('child_process').exec; |
子进程本身有 close 事件,可以设置回调函数。监听 data 事件以后,可以实时输出结果,否则只有等到子进程结束,才会输出结果。
execSync
是 exec
的同步执行版本。它可以接受两个参数,第一个参数是所要执行的命令,第二个参数用来配置执行环境。
1 | var execSync = require("child_process").execSync; |
上面代码中,execSync
方法的第二个参数是一个对象。该对象的 cwd
属性指定脚本的当前目录,env
属性指定环境变量。上面代码将 ./node_modules/.bin
目录,存入 $PATH
变量。这样就可以不加路径,引用项目内部的模块命令了,比如 eslint
命令实际执行的是 ./node_modules/.bin/eslint
。
而 execSync
的返回对象不为 ChildProcess,所以不能设置回调函数,也无法实时输出结果和监听报错。
ora & chalk
在涉及命令行交互操作时,有两个好用的 npm 库:ora、chalk,可以实现 loading 效果和改变命令行输出颜色等。