Node.js 最強大的一點就是「跨平台」。只要在編碼時稍微注意一下,你的程式碼就通吃 Windows、Linux 和 OSX 平台。以下這篇文章主要介紹如何利用Node.js寫跨平台的spawn語句,需要的朋友可以參考借鏡。
前言
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
第三方模組cross-spawn
關於spawn 函數的跨平台寫法,除了自己寫程式碼的時候做處理,也有第三方模組封裝好了相關細節,如cross-spawn。
跨平台地支援shebang;
的字元進行轉義更為方便。
安裝npm install cross-spawn
const spawn = require('cross-spawn'); spawn('npm', { stdio: 'inherit' });