利用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操纵Cookie实现购物车程序
Feb 15 Javascript
JS提交并解析后台返回的XML的代码
Nov 03 Javascript
js函数使用技巧之 setTimeout(function(){},0)
Feb 09 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
Mar 01 Javascript
node.js WEB开发中图片验证码的实现方法
Jun 03 Javascript
jQuery中animate()方法用法实例
Dec 24 Javascript
JS控制伪元素的方法汇总
Apr 06 Javascript
VS Code转换大小写、修改选中文字或代码颜色的方法
Dec 15 Javascript
JavaScript 跨域之POST实现方法
May 07 Javascript
VUE中使用MUI方法
Feb 12 Javascript
vue axios封装httpjs,接口公用配置拦截操作
Aug 11 Javascript
Vue OpenLayer 为地图绘制风场效果
Apr 24 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
模拟OICQ的实现思路和核心程序(三)
2006/10/09 PHP
PHP保存带BOM文件的方法
2015/02/12 PHP
js中的string.format函数代码
2020/08/11 Javascript
最常用的12种设计模式小结
2011/08/09 Javascript
jQuery表格插件ParamQuery简单使用方法示例
2013/12/05 Javascript
调试代码导致IE出错的避免方法
2014/04/04 Javascript
javascript实现的一个带下拉框功能的文本框
2014/05/08 Javascript
BootStrap实现文件上传并带有进度条效果
2017/09/11 Javascript
值得收藏的vuejs安装教程
2017/11/21 Javascript
JS+HTML5 Canvas实现简单的写字板功能示例
2018/08/30 Javascript
vue实现抖音时间转盘
2019/09/08 Javascript
ant design实现圈选功能
2019/12/17 Javascript
JavaScript canvas绘制折线图
2020/02/18 Javascript
Python显示进度条的方法
2014/09/20 Python
Python3中多线程编程的队列运作示例
2015/04/16 Python
python递归删除指定目录及其所有内容的方法
2017/01/13 Python
使用Scrapy爬取动态数据
2018/10/21 Python
Python 调用PIL库失败的解决方法
2019/01/08 Python
Python中按值来获取指定的键
2019/03/04 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
python 实现图片上传接口开发 并生成可以访问的图片url
2019/12/18 Python
Python爬虫实战案例之爬取喜马拉雅音频数据详解
2020/12/07 Python
css3的transform中scale缩放详解
2014/12/08 HTML / CSS
恒华伟业笔试面试题
2015/02/26 面试题
设计毕业生简历中的自我评价
2013/10/01 职场文书
校友会欢迎辞
2014/01/13 职场文书
酒鬼酒广告词
2014/03/21 职场文书
小学兴趣小组活动总结
2014/07/07 职场文书
科技工作者先进事迹
2014/08/16 职场文书
整顿机关作风心得体会
2014/09/10 职场文书
2014年初一班主任工作总结
2014/11/08 职场文书
个人事迹材料范文
2014/12/29 职场文书
雷锋观后感
2015/06/10 职场文书
经营场所使用证明
2015/06/19 职场文书
JavaScript 去重和重复次数统计
2021/03/31 Javascript
Anaconda安装pytorch和paddle的方法步骤
2022/04/03 Python