利用Node.js编写跨平台的spawn语句详解


Posted in Javascript onFebruary 12, 2017

前言

Node.js 是跨平台的,也就是说它能运行在 Windows、OSX 和 Linux 平台上。很多 Node.js 开发者都是在 OSX 上做开发的,然后再将代码部署到 Linux 服务器上。由于 OSX 和 Linux 都是基于 Unix 的,因此两者共性很多。Windows 也是 Node.js 官方支持的平台,只要你通过正确的方式写代码,就能在各个平台上毫无压力的跑起来。

Node.js 的子进程 (child_process) 模块下有一 spawn 函数,可以用于调用系统上的命令,如在 Linux, macOS 等系统上,我们可以执行

const spawn = require('child_process').spawn;

spawn('npm', {
 stdio: 'inherit'
});

来调用 npm 命令。

然而,同样的语句在 Windows 上执行则会报错。

Error: spawn npm ENOENT
 at exports._errnoException (util.js:855:11)
 at Process.ChildProcess._handle.onexit (internal/child_process.js:178:32)
 at onErrorNT (internal/child_process.js:344:16)
 at nextTickCallbackWith2Args (node.js:455:9)
 at process._tickCallback (node.js:369:17)
 at Function.Module.runMain (module.js:432:11)
 at startup (node.js:141:18)
 at node.js:980:3

因为在 Windows 上,当我们执行 npm 时,我们实际执行的是 npm.cmd 批处理,而在 Windows 上, .cmd,  .bat 批处理是无法脱离 cmd.exe 这一解释器而单独运行的。

因此,我们需要显式地调用 cmd

spawn('cmd', ['/c', 'npm'], {
 stdio: 'inherit'
});

或者使用在调用 spawn 函数时,设置 shell 选项为 true 以隐式地调用 cmd (该选项添加自 Node.js v6 版本)

spawn('npm', {
 stdio: 'inherit',
 shell: true
});

另外,虽然在 Linux, macOS 等系统上不需要设置 shell 选项,命令也能够正常执行;设置 shell true 也不会妨碍命令的执行,只是会额外的产生一个本不必要的 shell 进程,影响性能。

因此,如果想要编写跨平台的 spawn 命令,而又不想增加额外的开销的话,可以这样写

const process = require('process');
const { spawn } = require('child_process');

spawn('npm', {
 stdio: 'inherit',
 // 仅在当前运行环境为 Windows 时,才使用 shell
 shell: process.platform === 'win32'
});

第三方模块 cross-spawn

关于 spawn 函数的跨平台写法,除了自己编写代码的时候做处理,也有第三方模块封装好了相关细节,如 cross-spawn。

使用该模块,可以在调用 spawn 函数时,自动根据当前的运行平台,来决定是否生成一个 shell 来执行所给的命令。

而且,还能够

  • 支持低于 v6 的 Node.js 版本 (使用 shell 选项需要至少 Node.js v6);
  • 跨平台地支持 shebang;
  • 对命令和参数中的字符进行转义更为方便。

安装

npm install cross-spawn

用法

const spawn = require('cross-spawn');

spawn('npm', {
 stdio: 'inherit'
});

参考文档

在 Windows 上衍生 .bat 和 .cmd 文件

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
二行代码解决全部网页木马
Mar 28 Javascript
关于js datetime的那点事
Nov 15 Javascript
使用Post提交时须将空格转换成加号的解释
Jan 14 Javascript
JS去除数组重复值的五种不同方法
Sep 06 Javascript
jquery获取复选框被选中的值
Mar 22 Javascript
基于jQuery实现选取月份插件附源码下载
Dec 28 Javascript
JavaScript中闭包之浅析解读(必看篇)
Aug 25 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
Nov 07 Javascript
vue 弹框产生的滚动穿透问题的解决
Sep 21 Javascript
在Vant的基础上封装下拉日期控件的代码示例
Dec 05 Javascript
小程序使用分包的示例代码
Mar 23 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
Jun 22 Javascript
超全面的vue.js使用总结
Feb 12 #Javascript
Vue-Router实现页面正在加载特效方法示例
Feb 12 #Javascript
jquery使用EasyUI Tree异步加载JSON数据(生成树)
Feb 11 #Javascript
详解Jquery EasyUI tree 的异步加载(遍历指定文件夹,根据文件夹内的文件生成tree)
Feb 11 #Javascript
JavaScript实现瀑布流以及加载效果
Feb 11 #Javascript
JavaScript表单验证的两种实现方法
Feb 11 #Javascript
jQuery实现复制到粘贴板功能
Feb 11 #Javascript
You might like
PHP数据过滤的方法
2013/10/30 PHP
通过PHP自带的服务器来查看正则匹配结果的方法
2015/12/24 PHP
JQuery Tips(3) 关于$()包装集内元素的改变
2009/12/14 Javascript
JS Pro-深入面向对象的程序设计之继承的详解
2013/05/07 Javascript
21个JavaScript事件(Events)属性汇总
2014/12/02 Javascript
js实现数字每三位加逗号的方法
2015/02/05 Javascript
基于BootStrap Metronic开发框架经验小结【九】实现Web页面内容的打印预览和保存操作
2016/05/12 Javascript
详解JavaScript实现设计模式中的适配器模式的方法
2016/05/18 Javascript
全面解析Bootstrap表单样式的使用
2016/09/09 Javascript
ES6新特性二:Iterator(遍历器)和for-of循环详解
2017/04/20 Javascript
常用的9个JavaScript图表库详解
2017/12/19 Javascript
对layer弹出框中icon数字参数的说明介绍
2019/09/04 Javascript
vue实现手机号码的校验实例代码(防抖函数的应用场景)
2019/09/05 Javascript
新手入门js闭包学习过程解析
2019/10/08 Javascript
如何使用vue slot创建一个模态框的实例代码
2020/05/24 Javascript
微信小程序实现登录注册功能
2020/12/29 Javascript
Python实现树莓派WiFi断线自动重连的实例代码
2017/03/16 Python
python多线程共享变量的使用和效率方法
2019/07/16 Python
pandas read_excel()和to_excel()函数解析
2019/09/19 Python
Python json读写方式和字典相互转化
2020/04/18 Python
Python实现爬取并分析电商评论
2020/06/19 Python
纯CSS实现颜色渐变效果(包含环形渐变、线性渐变、彩虹效果等)
2014/05/07 HTML / CSS
CSS3自定义滚动条样式 ::webkit-scrollbar的示例代码详解
2020/06/01 HTML / CSS
StubHub智利:购买和出售您的门票
2016/11/23 全球购物
美国领先的水果篮送货公司和新鲜水果供应商:The Fruit Company
2018/02/13 全球购物
Silk Therapeutics官网:清洁、抗衰老护肤品
2020/08/12 全球购物
生产车间实习自我鉴定
2013/09/23 职场文书
管理站站长岗位职责
2013/11/27 职场文书
手机业务员岗位职责
2013/12/13 职场文书
学生自我评语大全
2014/04/18 职场文书
客户答谢会活动方案
2014/08/31 职场文书
会计求职自荐信范文
2015/03/04 职场文书
2015年感恩母亲节活动方案
2015/05/04 职场文书
《小小的船》教学反思
2016/02/18 职场文书
情侣餐厅的创业计划书范本!
2019/07/26 职场文书
MySQL的join buffer原理
2021/04/29 MySQL