利用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 相关文章推荐
juqery 学习之五 文档处理 包裹、替换、删除、复制
Feb 11 Javascript
Fixie.js 自动填充内容的插件
Jun 28 Javascript
javascript淘宝主图放大镜功能
Oct 20 Javascript
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
Oct 26 Javascript
AngularJS表单提交实例详解
Feb 18 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
May 03 Javascript
封装运动框架实战左右与上下滑动的焦点轮播图(实例)
Oct 17 Javascript
使用axios实现上传图片进度条功能
Dec 21 Javascript
vue this.reload 方法 配置
Sep 12 Javascript
新版小程序登录授权的方法
Dec 12 Javascript
微信小程序 授权登录详解(附完整源码)
Aug 23 Javascript
vue基于v-charts封装双向条形图的实现代码
Dec 09 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访问数据库集群的方法小结
2016/03/14 PHP
深入浅析yii2-gii自定义模板的方法
2016/04/26 PHP
PHP在线打包下载功能示例
2016/10/15 PHP
PHP 序列化和反序列化函数实例详解
2020/07/18 PHP
PHP共享内存使用与信号控制实例分析
2018/05/09 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
2020/02/27 PHP
js和jquery批量绑定事件传参数一(新猪猪原创)
2010/06/23 Javascript
原来Jquery.load的方法可以一直load下去
2011/03/28 Javascript
jQuery实战之品牌展示列表效果
2011/04/10 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
2013/06/27 Javascript
简单的ajax连接库分享(不用jquery的ajax)
2014/01/19 Javascript
jQuery点缩略图弹出层显示大图片
2015/02/13 Javascript
jQuery实现鼠标单击网页文字后在文本框显示的方法
2015/05/06 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
2016/06/06 Javascript
jQuery实现简单的网页换肤效果示例
2016/09/18 Javascript
判断数组的最佳方法(推荐)
2016/10/11 Javascript
javascript创建对象的3种方法
2016/11/02 Javascript
JavaScript中三种常见的排序方法
2017/02/24 Javascript
js canvas实现擦除效果示例代码
2017/04/26 Javascript
vue组件初学_弹射小球(实例讲解)
2017/09/06 Javascript
Bootstrap Table中的多选框删除功能
2018/07/15 Javascript
Vue表单及表单绑定方法
2018/09/04 Javascript
原生JS实现前端本地文件上传
2018/09/08 Javascript
在windows下Python打印彩色字体的方法
2018/05/15 Python
Python闭包执行时值的传递方式实例分析
2018/06/04 Python
python调用c++传递数组的实例
2019/02/13 Python
Python Pandas 获取列匹配特定值的行的索引问题
2019/07/01 Python
python正则表达式 匹配反斜杠的操作方法
2020/08/07 Python
新西兰最大的天然保健及护肤品网站:HealthPost(直邮中国)
2021/02/13 全球购物
请解释一下webService? 如何用.net实现webService
2014/06/09 面试题
学前教育毕业生自荐信
2013/10/29 职场文书
个人自荐信
2013/12/05 职场文书
综合实践教学反思
2014/01/31 职场文书
幼儿教师小班个人总结
2015/02/05 职场文书
JavaScript实现简单计时器
2021/06/22 Javascript
Golang流模式之grpc的四种数据流
2022/04/13 Golang