諸如React、Angular、Vue等現代前端框架嚴重依賴於終端。如果你還不習慣使用命令列介面,你將很難執行本地開發伺服器或構建你的應用程式。
諷刺的是,我們的整個工作都建立在圖形化使用者介面上,但我們在開發中使用的工具卻大多是基於命令列的。
除非你有電腦科學背景,或者在上世紀80年代使用計算機長大,否則你大概率不會擁有豐富的終端經驗。然而,大部分線上資源都假定你已經對此十分熟練了。
要成為一個終端大佬需要多年的練習,但好訊息是:我們可以走捷徑。我們並不真的需要知道可以用終端做的絕大多數的事情。如果我們專注於最重要的關鍵基礎知識,我們應該能夠在很短的時間內適應命令列。✨
這也是這篇文章想要介紹的內容。它是使用現代JS框架(如React)所需的,終端基礎知識的一門手冊,有了它你就可以轉到有趣的事情上:構建使用者介面。
我還將分享我從終端中獲得的技巧和竅門,這些東西我多希望在我剛開始工作時就有人能告訴我。
好了,在開始之前,我們還需要做兩件事情。
首先,我們需要一些終端軟體。終端軟體是執行命令列環境的應用程式。
幾乎每個作業系統都會有一個內建的終端,比如MacOS的Terminal.app
,或者Windows的Command Prompt
,這些應用程式都可以工作,但都不太讓人滿意。大多數開發者會選擇使用其他軟體。
只要你使用的是現代技術,那麼選擇使用哪款終端應用就沒那麼重要。因此,這裡我有兩個主要建議:
在這篇文章中,我將使用Hyper來展示所有的例子。
到這裡,選擇好了終端應用才完成了一半。我們還需要確保執行正確的shell
語言。
當我們在終端輸入命令並回車時,命令會通過shell
語言進行解釋執行。它本質上是在終端應用程式中執行的環境。
最流行的shell
語言是Bash。當你在網上看到命令列說明時,這些說明很有可能是基於Bash的。這是大多數Linux發行版使用的預設shell
語言。
現代的MacOS版本自帶的Zsh,而不是Bash。但Zsh與Bash十分類似:它們屬於同一家族,幾乎共用所有相同的命令。從目的角度出發,它們是可以互換使用的。
如果你使用的是Linux或者MacOS,那就可以正式開始了。你的計算機已經在使用一種"行業標準"的shell
語言。然而,如果你使用的是Windows,我們還有一點工作要做。
你是否曾經在你的瀏覽器中開啟開發者控制檯,來執行一些任意的JavaScript程式碼?
在這種情況下,應用程式是Chrome,而語言是JavaScript。Chrome提供了命令列介面,但當我們執行命令時,這些命令是用JavaScript解釋的。
當涉及到終端時,它也是同樣的道理。像Hyper這樣的終端應用可能正在執行Bash shell
語言。與瀏覽器不同的是,終端應用可以在多種shell
語言之間進行切換。
首先,我需要承認的是,當涉及到Windows開發時,我並不是專業人士。請對我接下來說的每一句話持保留態度。
Bash是基於Linux的shell
語言,它不會在Windows上原生執行。幸運的是,較新版本的Windows具有安裝和執行Linux的能力,就像Linux是一種應用程式一樣。這被稱為Windows Subsystem for Linux,通常縮寫為WSL。
這裡有一個教學,介紹了所需的步驟:在Windows中,如何安裝並使用Zsh。
我自己執行了這些步驟,雖然這有點乏味,但它確實起作用了!
一旦設定好之後,你就可以設定終端來使用Bash或者Zsh。這裡有一些關於設定Hyper來使用Zsh的介紹。
如果你在這些步驟中遇到了麻煩,這裡有些其他的解決方案你可以試一試。一個流行的方法是Git Bash,它允許你在Windows內使用模擬技術執行Bash。
歸根結底,你如何做到並不重要。重要的是,你能夠在Windows中使用Bash或Zsh。
當你第一次開啟終端應用時,你會遇到這個相當無助的介面:
你的終端看起來可能會有些不同,這取決於你使用的作業系統、終端應用、shell
語言。總的來說,你可能會看到一行文字,和一堆空白空間。
這一行文字被稱為提示。它之所以被稱為"提示",是因為它在等待你提供某種指令。
我們的第一個命令,輸入文字echo "hello world"
並回車:
語法有一點不同,但你可以認為命令就是內建的JavaScript函數。echo
命令與JavaScript中的console.log
函數非常相似。
跟函數一樣,命令也可以接收引數。在本例中,echo
接收了一個引數,並輸出了字串。
當我們按下回車時,命令就會立即執行,值也會被列印。下一行會呈現一個新的提示,讓我們知道它已經準備好接收下一個指令。
就像這樣,你已經成功執行了第一條終端命令。
在閱讀NPM包的安裝說明時,你會經常看到這樣的內容:
$ npm install some-package
如果你試圖執行這一段文字,你會得到一個錯誤。這是因為美元符號($)不應該被包括在內。你應該在美元符號之後輸入所有內容。
為什麼安裝說明會包含一個隨機的符號,而這個符號實際上並不是命令的一部分?好吧,在Bash shell
語言中,$是提示符,顯示在提示的末尾。
它本質上是一個符號,並說道:嘿,這裡的東西要在終端執行!
儘管在許多現代shell
語言(如Zsh)中,$實際上並不作為提示字元使用,但其象徵意義仍然存在,比如儲存的圖示是一個軟碟形狀,儘管我們已經幾十年沒有使用軟碟了。
終端的主要目的是能夠讓你在檔案系統中移動檔案,並開啟/執行東西。它本質上是我們每天使用的GUI檔案資源管理器(如Finder、Windows Explorer)的基於文字的版本。
為了幫助我們全方位導航,有很多終端命令可以使用。讓我們來探索其中的一些。
pwd命令代表著 Print Working Directory ,它有點像購物中心地圖上的「你在這裡」箭頭。它會告訴你當前所處的位置:
當你開啟終端應用時,你通常會被扔進 」home」 目錄,該目錄包含了 Documents 和 Desktop 目錄。在我的機器上,這個目錄位於/Users/joshu
。
使用ls
(List的簡寫)命令,你可以檢視當前目錄下的內容:
在我的終端上,目錄是加粗的,並以淺水色展示。而單個檔案是普通文字粗細,以白色展示。
我們可以使用cd
(Change Directory)命令來移動檔案系統:
這相當於在GUI檔案資源管理器中雙擊 "stuff" 目錄。
需要注意的是,提示從波浪字元(~)變成了 "stuff" 。在Zsh
shell
語言中,預設的提示由一個箭頭和當前目錄的名稱組成,比如說"→ Documents"。 等一下,為什麼之前是一個波浪字元,而不是父目錄的名稱?在MacOS和Linux上,波浪字元是使用者home
目錄的縮寫。在我的機器上,"~"相當於"/Users/joshu
"。 很容易誤以為"~"是一個提示字元,就像Bash中的"$"一樣。
如果我想返回上一級,返回到home
目錄該怎麼辦?我也可以使用cd命令來達到目的,但是要帶有兩個點(..
) 。
在大多數shell
語言中,點字元(.
)具有著特殊的含義:
.
)表示當前目錄。..
)表示父級目錄。如果你在JavaScript中使用過模組系統,你可能已經熟悉了這個慣例。它使用同樣的符號,用兩個點來表示父級目錄:
import { COLORS } from '../../constants';
import Button from '../Button';
關於cd
命令,有件很重要的事情需要知道。那就是cd
可以接收復雜的路徑。終端的初學者往往會像在GUI檔案資源管理器中那樣,一步一步地走:
這樣做是沒問題的,但是需要花費大量額外的工作。我們可以像這樣一步到位地完成同樣的路徑跳轉:
終端最令人生畏的事情之一是,它不會給你任何線索或提示。使用GUI檔案資源管理器,你可以看到檔案和資料夾的完整列表,以重新整理你的記憶並幫助你找到你要找的東西。
如果你想按照我的建議使用cd
,從一個地方一下子跳到另一個地方,看起來你可能需要一個照相式的記憶。除非你記住路徑鏈中每個目錄的確切名稱,否則你無法做到這一點,對不對?
幸運的是,一個非常方便的技巧使這一切變得更加容易:tab自動補全。
在有效使用終端時,Tab鍵是至關重要的。除了這裡展示的導航技巧外,我們還可以用Tab鍵來自動完成Git分支,或者補全命令的剩餘部分。
試試在不同情況下按下Tab鍵,看看會發生什麼吧。
如果你發現很難掌握Tab的自動補全,你可能會對Fig感興趣。Fig是一個終端外掛,它增加了編輯器風格的自動補全。
我也剛剛開始嘗試使用Warp,一個為速度和使用者體驗而建立的現代終端。在寫這篇文章的時候,它是MacOS獨有的,但他們確實計劃在測試版之後將其移植到Windows和Linux。
我們正生活在一個終端復興的時代,有很多工具的目的是使它不那麼令人生畏。
早些時候,我提到過Bash/Zsh裡的命令,就像JavaScript裡的函數。當涉及到標誌時,這個類比就不太適用了。
標誌是修飾符,以預先定義的方式調整命令的行為。
舉例來說,讓我們來看一看rm
命令。該命令允許我們刪除單個檔案:
我們沒有得到任何形式的確認,但如果我們再次檢視,會發現theme-song.mp3
檔案確實已被刪除。
再繼續之前,我應該警告你:終端可能相當不寬容。
rm
命令沒有 "你確定嗎?"的確認提示。也沒有任何復原操作。當你使用rm
刪除檔案,它不會進入回收站/垃圾桶。它被永久地、不可逆轉地刪除。 這是終端的一個共同主題。沒有太多的安全機制。因此,在使用rm
這樣的命令時,請務必小心。
如果你嘗試在目錄上使用rm
命令,你會得到一個錯誤:
預設情況下,rm
只可以刪除單個檔案,但我們可以使用r
標誌來改變規則:
r
標誌代表著遞迴(recursive)。它將刪除stuff
目錄在內的任何東西,stuff
目錄內的目錄內的任何東西,stuff
目錄內的目錄內的任何東西,以此類推。
你也可能遇到一些檔案許可權問題。由於這個原因,f
標誌(Force)也是很常用的。我們可以用一個破折號將多個標誌分組,就像這樣:
標誌有很多形狀和大小。按照慣例,標誌通常有一個簡短的形式(例如:-f)和一個完整的形式(--force)。完整形式通常使用兩個破折號,並使用整個單詞而不是單個字母。
讓我們看個其他的例子。早前我們看到過的ls
命令,通常使用兩個標誌呼叫:
l
標誌,也就是long
。它將目錄內容列印成一個帶有後設資料的詳細列表。a
標誌,也就是all
。它將包含隱藏檔案和目錄。這很大程度上改變了輸出格式:
這裡有很多煩人的資料,包括令人琢磨不透的許可權字元。但是一些後設資料,比如顯示檔案最後一次更新日期,可是很有用的。
為了瞭解更多有關命令的內容,你可以使用man
命令(manual的縮寫)調取它的內建檔案。
我要告訴你的是,man
檔案密密麻麻,而且經常難以解析。但它對於瞭解某些命令有哪些標誌還是很有用的。
在某些情況下,檔案會在你的預設文字編輯器中開啟,但通常會在終端中開啟,如圖所示。這裡使用了一個被稱為less
的程式。
要在less
中捲動檔案,請使用上/下方向鍵。在現代版本的MacOS上,你也可以使用滑鼠滾輪來捲動,儘管這在其他平臺上可能會導致錯誤的行為。
當你完成手冊檢視後,按q
退出。它應該會恢復到典型的終端檢視中。
有些程序是長時間不間斷執行,如果要停止執行,就需要進行中斷。
舉例來說,開啟終端並嘗試執行接下來的命令:ping 8.8.8.8
。
ping
命令將檢查給定IP地址的延遲情況。它對於檢查一個給定的伺服器是否線上很有用。8.8.8.8
是谷歌DNS伺服器的IP地址。
與我們到目前為止看到過的命令不同,ping
是一個長期執行的程序,它永不停歇。預設情況下,它將一直ping
Google的DNS伺服器,直到時間結束。
當我們對結果感到滿意時,我們可以通過按下ctrl
和c
來中斷該命令。即使在MacOS上,大多數的快捷鍵都使用的⌘修飾符,這裡我們也使用ctrl
。
另一個很有用的命令是ctrl
+ d
。這會終止當前的對談。如果ctrl
+ c
在某些情況下不起作用,ctrl
+ d
可能會起作用。
最後,如果上面的方法都失敗了,可以直接關閉當前的tab頁或者視窗。該方式的快捷鍵取決於你使用的作業系統以及終端程式。如果是在MacOS上使用的Hyper,關閉當前視窗的快捷鍵組合是⌘
+ w
。
有的時候,會使用Vi
或者Vim
來編輯檔案。這些編輯器是出了名的難以退出;ctrl
+ c
在這裡可幫不了你。
要在不儲存的情況下退出,請遵循以下步驟:
Escape
。:
,這應該會在終端的底部新增一個提示。q!
,並按下回車。到目前為止,我們已經看到了很多關於如何使用終端做事情的例子。接下來讓我們來看看,如何通過終端完成一些典型的開發任務。
下面的範例假設你已經在本地安裝了Node.js。如果你還沒有安裝,你可以從Node主頁下載安裝包進行安裝。
假設今天是你上班的第一天。你的團隊已經允許你存取專案的原始碼,你已經把原始碼下載到了你的電腦上。然後呢?
第一步就是下載專案的第三方依賴。
以下是需要遵循的步驟:
cd path/to/project
npm install
npm
代表著Node Package Manager。當你安裝Node.js時,npm
會自動被安裝。
執行該命令會從NPM倉庫下載專案所依賴的所有第三方程式碼。這些程式碼將存在於原生的node_modules
目錄中。
此時,你已經下載好了第三方的程式碼,然後呢?
如果你檢視專案的package.json
,你可能會看到這樣的一部分設定:
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
這些scripts
是可以用NPM工具執行的任務。它們可以通過執行npm run [name]
來執行。舉個例子,為了啟動一個本地開發伺服器,我們會執行:
cd path/to/project
npm run start
執行該命令會啟動一個長期執行的程序。它啟動了一個Node伺服器,允許我們在應用程式上進行開發,監聽檔案的變動,當我們編輯檔案時,重新進行打包。
當我們結束開發時,我們可以使用ctrl
+ c
來關閉該服務。
NPM指令碼的美妙之處在於它們將事情標準化。start
,build
,和 test
是這些標準任務的常見名稱。因此,我們不必記住每個專案客製化的命令,即使這些專案使用完全不同的工具。
我們也可以建立屬於自己的NPM指令碼。關於此,我會在後面的文章進行詳細說明。
當我想在一個專案上開始工作時,首先我會在終端導航到專案的根目錄。然後執行以下命令:
cd path/to/project
code .
我們在前面提到過,.
指的是當前工作目錄。code
是我的程式碼編輯器VS Code新增的一個命令。執行這個命令可以在我的程式碼編輯器中開啟整個專案,讓我可以隨心所欲地在不同的檔案之間輕鬆跳轉。
需要注意的是,該命令的執行取決於你的編輯器。而且,對於在MacOS上使用VS Code的人,你需要做一些工作來啟用code
命令。
你知道對任何電腦問題的標準建議是重啟嗎?
該問題的JavaScript版本是重新安裝NPM依賴。有時候,只需要徹底刪除並重新安裝就可以解決問題。尤其是你會編輯node_modules
檔案並進行偵錯時。
我們可以這麼做:
cd path/to/project
rm -rf node_modules
npm install
我們進入到正確的目錄後,使用rm
命令刪除所有的第三方程式碼,然後使用npm install
重新安裝依賴。
雖然有GUI應用程式可以使用Git,但許多開發者更願意使用命令列來完成與Git相關的任務。
完整的 Git 命令列教學遠遠超出了本文的範圍,但這裡有一份我常用的命令的快速小抄:
// 下載Git倉庫到本地
git clone [URL]
// 檢查哪些檔案被修改
git status -s
// 檢視更改
git diff
// 新增所有檔案到暫存區
git add .
// 提交暫存的檔案
git commit -m "Short descriptive message"
// 建立新的本地分支
git switch -c [new branch name]
// 切換分支
git switch [branch name]
// 推播程式碼
git push origin [branch name]
// 開啟可互動的變基
git rebase -i [branch name or commit hash]
多年來,我掌握了一些終端小技巧。它們並不重要,但它們有助於改善開發者使用終端的體驗。
許多終端程式會記錄下你在一個特定對談中所執行的每一條命令。你可以使用上鍵迴圈檢視先前的命令。
如果我明確知道最近執行過某條命令,通常按幾次上鍵會比從頭開始輸入更快。
這裡還有一個不久前學到的神奇小技巧: -
字元。
假設我們想用cd
在兩個目錄之間來回跳動。我們可以通過輸入整個路徑來做到這一點。亦或者使用cd -
來快速切換到上一個cd
的目錄下。
就像清空桌面那樣,清空終端可以讓人頭腦清晰。
有好幾種辦法可以做到這一點。先來看看clear
命令,它可以清除所有先前輸入的命令,並使它看起來像你剛剛開啟一個新的終端對談。
還有一個通用的快捷鍵,ctrl
+ L
。它與clear
命令的效果相同。它應該能在MacOS、Windows和Linux中工作。
這個命令/快捷鍵是在Bash/Zsh中實現的。它是shell
環境的一部分。這意味著它只在shell
空閒時起作用。
某些終端程式也實現了它們自己的快捷鍵,這些快捷鍵甚至可以在shell
繁忙時工作。下面是我所知道的快捷鍵的清單:
shell
(Terminal.app、iTerm2、Hyper),快捷鍵是⌘ + k。ctrl
+ shift
+ k
。這些應用程式級的快捷鍵要好用得多。即使在shell
繁忙的時候也可以使用它們。
比如說,假設你正在執行一個開發伺服器,這是一個長期執行的程序,所以ctrl
+ L
的快捷鍵是不起作用的。當你開發專案時,大量的資訊會被記錄在終端視窗中。應用程式的快捷鍵允許你清除舊的紀錄檔,就像歸檔舊的電子郵件一樣。這真的非常有用,也是現代終端程式如何使我們更加輕鬆的絕佳範例。
每隔一段時間,我就會發現自己會重複敲一些命令。如果這個命令又長又複雜,每次都要完整的敲出來,而且要逐字逐句地記住,這就非常煩人。
Bash和Zsh都支援別名,這是一種建立自定義快捷鍵的方法。比如說,我可以把它設定成每當我輸入hi
時,它就自動執行echo "Hello World!"
。
設定別名有點超出了本教學的範圍,而且根據你的shell
語言,說明也有點不同。這裡有一些更深入的有用教學:
除非你已經達到了使用終端的黑帶段位,否則有時你會想在GUI檔案資源管理器中開啟工作目錄。
在MacOS中,open .
命令可以做到這一點。
open
命令一般用於開啟一個檔案,就像在GUI檔案資源管理器中雙擊一個檔案開啟它一樣。
然而,當我們試圖開啟一個目錄時,它會選擇彈出一個新的Finder視窗,同時顯示該目錄的內容。
由於點字元(.
)代表的是當前目錄,所以開啟.
允許我們從終端切換到Finder,以繼續我們在終端之外的工作。
在Windows上,你可以使用explorer .
來達到同樣的目的。
在Linux上,只要Linux發行版實現了FreeDesktop標準,xdg-open
就可以用來開啟檔案,或當前目錄。
每當我從Github上克隆一個新專案時,我一般要做兩件事:
npm install
,來拉取第三方依賴。npm run start
,來啟動本地開發伺服器。npm install
命令通常需要花費幾分鐘時間。我沒有足夠的注意力坐在那裡盯著依賴是否下載完成,所以我經常會用Twitter來分散自己的注意力。接下來我知道的是,20分鐘過去了,我完全忘記了我要啟動一個開發伺服器。
我們可以使用鏈式命令來解決該問題。以下是它的工作原理:
&&
操作符允許我們將多個命令連結在一起。第一條命令將被執行,即npm install
。當它完成的同時,第二個命令將自動執行。
這是一個特別巧妙的技巧,因為npm run start
通常會開啟一個瀏覽器視窗,吸引我的注意力,讓我知道一切都準備好了。相比之下,npm install
是靜默完成的。
一旦我掌握了鏈式命令的竅門,我就開始到處使用它。我經常會把一堆Git命令排列在一起:
git add . && git commit -m "Stuff" && git push origin main
我們在這篇文章中涵蓋了很多內容。希望你不會感覺到太大的壓力。
終端有一個很好的名聲,對初學者來說是令人生畏和棘手的。如果你對它感到費勁,那也是完全正常的。
希望這篇文章至少能縮小你需要學習的範圍。可以使用終端做很多事情,但我們可以專注某一部分功能。
如果你覺得這篇文章對你有所幫助,歡迎收藏關注轉發~
原文連結:https://www.joshwcomeau.com/javascript/terminal-for-js-devs/
作者:Joshua Comeau