利用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 相关文章推荐
云网广告中的代码,提示出错,大家找找
Nov 21 Javascript
Array栈方法和队列方法的特点说明
Jan 24 Javascript
javascript动态控制服务器控件实例
Sep 05 Javascript
JavaScript设计模式之外观模式实例
Oct 10 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
May 25 Javascript
JS+CSS3实现超炫的散列画廊特效
Jul 16 Javascript
JavaScript仿微博发布信息案例
Nov 16 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
Jan 19 Javascript
mescroll.js上拉加载下拉刷新组件使用详解
Nov 13 Javascript
在Vue组件上动态添加和删除属性方法
Feb 23 Javascript
微信小程序实现张图片合成为一张并下载
Jul 16 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 Vue.js
超全面的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中使用DOM类读取XML文件的实现代码
2011/12/14 PHP
ThinkPHP模板替换与系统常量及应用实例教程
2014/08/22 PHP
PHP如何实现Unicode和Utf-8编码相互转换
2015/07/29 PHP
onmouseover和onmouseout的一些问题思考
2013/08/14 Javascript
jQuery 三击事件实现代码
2013/09/11 Javascript
详解JavaScript中shift()方法的使用
2015/06/09 Javascript
延时加载JavaScript代码提高速度
2015/12/27 Javascript
Ajax分页插件Pagination从前台jQuery到后端java总结
2016/07/22 Javascript
javascript 利用arguments实现可变长参数
2016/11/21 Javascript
Angular4实现动态添加删除表单输入框功能
2017/08/11 Javascript
浅谈react 同构之样式直出
2017/11/07 Javascript
JavaScript判断日期时间差的实例代码
2018/03/01 Javascript
详解javascript中的babel到底是什么
2018/06/21 Javascript
vue2路由基本用法实例分析
2020/03/06 Javascript
详解JSON.stringify()的5个秘密特性
2020/05/26 Javascript
[01:08]DOTA2“血战之命”预告片
2017/08/12 DOTA
用Python实现通过哈希算法检测图片重复的教程
2015/04/02 Python
Python中使用OpenCV库来进行简单的气象学遥感影像计算
2016/02/19 Python
Python读写/追加excel文件Demo分享
2018/05/03 Python
python实现停车管理系统
2018/11/30 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
使用Python来做一个屏幕录制工具的操作代码
2020/01/18 Python
浅谈python输出列表元素的所有排列形式
2020/02/26 Python
解决keras GAN训练是loss不发生变化,accuracy一直为0.5的问题
2020/07/02 Python
Python with语句用法原理详解
2020/07/03 Python
python中upper是做什么用的
2020/07/20 Python
html5播放视频且动态截图实现步骤与代码(支持safari其他未测试)
2013/01/06 HTML / CSS
电大学习个人自我评价范文
2013/10/04 职场文书
运动会广播稿100字
2014/01/11 职场文书
社区关爱留守儿童活动方案
2014/08/22 职场文书
2014年个人师德工作总结
2014/12/04 职场文书
乡镇科协工作总结2015
2015/05/19 职场文书
小学班主任工作随笔
2015/08/15 职场文书
资产移交协议书
2016/03/24 职场文书
某学校的2019年度工作报告范本
2019/10/11 职场文书
Python序列化与反序列化相关知识总结
2021/06/08 Python