大家好,我是若川。持續組織了5個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。
今天來討論一個牛逼的項目 ——zx ,1個月增長15000 star, 成為了2021年度明星項目排行榜第一。
zx 到底是什么呢?
我們可以從官網的介紹看到,一個能更方便地寫腳本的工具。(A tool for writing better scripts)
Bash is great, but when it comes to writing scripts, people usually choose a more convenient programming language. JavaScript is a perfect choice, but standard Node.js library requires additional hassle before using. The
zx
package provides useful wrappers aroundchild_process
, escapes arguments and gives sensible defaults.
翻譯:
Bash 用來寫腳本非常棒,但是大家通常還是會去選擇一種更方便方式去編寫腳本,例如使用像 JavaScript 這種編程語言。但是 Node.js 在使用之前需要很多額外的操作,比如裝包、引庫等。但是zx 提供更多便捷的功能并且還對 child_process 進行了簡化封裝,從而能夠直接調用一些命令。
通過閱讀摘要和描述,我們可以知道雖然 Bash 很棒,但是沒有 Node.js 簡單。雖然 Node.js 編寫起來簡單,但是在使用前還是有一些麻煩的操作。而zx 沒有以上兩種方式的缺點,能夠化繁為簡,提供簡單又方便操作。
在繼續深入了解 zx 前,我們先來屢清楚目前提到的一些概念,了解這些概念有助于我們更好地去寫腳本。
Shell、Shell腳本、Bash、zx、Node
首先來說說什么是Shell,Shell的中文意思是貝殼,是指與操作內核連接的外殼。
狹義的Shell指的是命令行方面的軟件,大多指Bash(Bash全稱為 Bourne Again SHell ,是linux標準的默認Shell,它基于Bourne Shell,吸收了C Shell和Korn Shell );廣義的Shell則包括圖形界面。
因此 Shell 是一個大概念,包含了 Bash 等這些命令行工具,而利用這些工具寫的腳本叫做Shell 腳本;而 Node 屬于編程語言,可以編寫 js 文件來執行一些命令, zx 是基于 Node 開發的工具,因此也能通過編寫腳本來執行命令。
他們之間的關系我用一張圖進行了描述,標題的概念用紅色字樣進行了加重。
腳本可以做那些事情?
最為簡單的就是重復的事情、處理數據格式,數據導入導出以及各種簡單常用小工具的制作,環境配置等等。
舉一些具體的例子就是:
下載視頻
https://www.jianshu.com/p/0a013fa5a250
下載音樂
https://binaryify.github.io/NeteaseCloudMusicApi/#/
統計字數
https://geek-docs.com/shell/shell-examples/the-shell-counts-the-number-of-lines-words-and-characters-in-the-file.html
自動簽到
https://github.com/RWoxiN/Qiandao
...
功能太多了列舉不過來,反正你會的操作能幫你簡化,你不會的操作能幫你實現。
哪些人可以使用?
腳本不僅僅可以幫助開發人員還能幫助非開發人員。
例如很多人都喜歡在個人博客上面寫文章,這時就可以用WordPress 快速搭建一個博客,然后我們就用腳本一鍵來安裝WordPress,下面以 Shell 腳本為例:
https://gist.github.com/dessibelle/2666478
zx、Node、Shell(Bash) 功能評測
上面聊了腳本的一些概念以及腳本能幫助我們做什么。那么既然腳本這么強大,且腳本種類也非常多,為什么 zx 一經推出就這么收歡迎呢?
我們就以實際的功能為例來體驗一下,分別使用了zx、Node、Shell(Bash,以下都稱作Bash )三種腳本寫一個批量壓縮音視頻的腳本。
實現一個音頻功能主要分成四個步驟
1.遍歷當前目錄
2.判斷當前文件類型
3.執行壓縮音頻視腳本
首先我們先來看遍歷當前目錄三種腳本的寫法:
Bash
#!bin/bash
for?file?in?`(ls)`;
do...
done
Node
import?fs?from?'fs';const?dirs?=?fs.readdirSync('./'));
for?(let?i?in?dirs)?{...?
}
zx
const?dirs?=?(await?$`ls`).stdout.split('\n')for?(let?i?in?dirs)?{...
}
可以看到 Bash 和 zx 差不多,但是 zx 比Node 省去了引包的代碼。
優勢:zx = Bash > Node
其次我們再來看判斷當前文件類型三種腳本的寫法:
Bash
if?test?-f?$file
thenfilename=$(basename?$file);if?[?"${file##*.}"x?=?"mp4"x?];thenfiif?[?"${file##*.}"x?=?"mp3"x?];?thenfi
fi
Node、zx
if?(dirs[i]?&&?!fs.statSync(source).isDirectory())?{?if?(source.endsWith(".mp4"))?{}if?(source.endsWith(".mp3"))?{}
}
用Shell 來寫整體上代碼都非常的精煉,但是對于不經常使用的人來說,常常會遇到一些問題,例如 if 語句格式非常嚴格、判斷比較的方式比較特殊、字符串操作都比較麻煩。
優勢 Node = zx > Bash
最后再來執行壓縮音頻視腳本:
Bash
...
ffmpeg?-i?$file?-r?30?-c?copy?-c:v?libx264?-vf?scale=720:-2?"${filename%%.*}-30-720".mp4;
...
Node
const?{?spawn?}?=?require('child_process');function?run(command)?{return?new?Promise((rev,?rej)?=>?{console.log(command);const?cmd?=?spawn(command.slice(0,?1)[0],?command.slice(1));cmd.stdout.on('data',?(data)?=>?{console.log(`stdout:?${data}`);});cmd.stderr.on('data',?(data)?=>?{console.error(`stderr:?${data}`);});cmd.on('close',?(code)?=>?{console.log(`child?process?exited?with?code?${code}`);rev();});})
}...
await?run(["ffmpeg",?"-i",?source?,"-r","30","-c",?"copy","-c:v",?"libx264",??"-vf",?"scale=720:-2",?`${dirs[i].replace('.mp4',?'')}-30-720.mp4`]);
...
zx
$`ffmpeg?-i?${file}?-r?30?-c?copy?-c:v?libx264?-vf?scale=720:-2?${file.replace(".mp4","")}-30-720.mp4;`;
用 zx 可以做到和 Shell 一樣的精簡,利用內置的一些 Node 包使得整體的代碼量大大下降。Node需要寫一些額外的代碼,例如執行命令run等等。
優勢 Bash?= zx > Node
上手程度 | 代碼復雜度 | |
---|---|---|
Shell | 難 | 簡潔 |
Node | 簡單 | 繁瑣 |
zx | 簡單 | 簡潔 |
zx 上手體驗非常好,可以說用四個字來概括, “簡潔易用”,至此你是否對 zx 心動了呢?
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。分享、收藏、點贊、在看我的文章就是對我最大的支持~