利用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 相关文章推荐
JavaScript 对象成员的可见性说明
Oct 16 Javascript
纯CSS打造的导航菜单(附jquery版)
Aug 07 Javascript
JavaScript常用脚本汇总(二)
Mar 04 Javascript
JavaScript实现简单图片翻转的方法
Apr 17 Javascript
JavaScript调用传递变量参数的相关问题及解决办法
Nov 01 Javascript
jquery实现触发时更新下拉列表内容的方法
Dec 02 Javascript
uploader秒传图片到服务器完整代码
Apr 22 Javascript
PHP实现记录代码运行时间封装类实例教程
May 08 Javascript
jQuery中复合选择器简单用法示例
Mar 31 jQuery
通过封装scroll.js 获取滚动条的值
Jul 13 Javascript
jQuery实时统计输入框字数及限制
Jun 24 jQuery
Vue封装全局过滤器Filters的步骤
Sep 16 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 Socket配置以及实例的详细介绍
2013/06/13 PHP
php通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
ThinkPHP实现分页功能
2017/04/28 PHP
Thinkphp结合AJAX长轮询实现PC与APP推送详解
2017/07/31 PHP
php post json参数的传递和接收处理方法
2018/05/31 PHP
Laravel 创建可以传递参数 Console服务的例子
2019/10/14 PHP
PHP二维数组分页2种实现方法解析
2020/07/09 PHP
WordPress伪静态规则设置代码实例
2020/12/10 PHP
在子窗口中关闭父窗口的一句代码
2013/10/21 Javascript
jQuery中appendTo()方法用法实例
2015/01/08 Javascript
JavaScript实现相册弹窗功能(zepto.js)
2016/06/21 Javascript
JS中作用域和变量提升(hoisting)的深入理解
2016/10/31 Javascript
关于Iframe父页面与子页面之间的相互调用
2016/11/22 Javascript
浅谈javascript的闭包
2017/01/23 Javascript
深入理解 webpack 文件打包机制(小结)
2018/01/08 Javascript
完美解决mui框架off-canvas侧滑超出部分隐藏无法滚动的问题
2018/01/25 Javascript
详解基于webpack&gettext的前端多语言方案
2019/01/29 Javascript
为什么Vue3.0使用Proxy实现数据监听(defineProperty表示不背这个锅)
2019/10/14 Javascript
vue setInterval 定时器失效的解决方式
2020/07/30 Javascript
Python实现冒泡,插入,选择排序简单实例
2014/08/18 Python
python自动化测试之setUp与tearDown实例
2014/09/28 Python
Python+Pyqt实现简单GUI电子时钟
2021/02/22 Python
浅谈django2.0 ForeignKey参数的变化
2019/08/06 Python
pytorch-RNN进行回归曲线预测方式
2020/01/14 Python
解决使用Pandas 读取超过65536行的Excel文件问题
2020/11/10 Python
日本乐天官方海外转运服务:Rakuten Global Express
2018/11/30 全球购物
台湾东南旅游社网站:东南旅游
2019/02/11 全球购物
科室工作个人总结的自我评价
2013/10/29 职场文书
大学毕业生文采飞扬的自我鉴定
2013/12/03 职场文书
优秀电子工程系毕业生求职信
2014/05/24 职场文书
社区端午节活动总结
2015/02/11 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
青年干部培训班学习心得体会
2016/01/06 职场文书
JS如何使用剪贴板操作Clipboard API
2021/05/17 Javascript
你知道Java Spring的两种事务吗
2022/03/16 Java/Android
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python