相信每位有工作經驗的工程師都對 Composer 這個工具有所耳聞。除了知道要執行 composer install
指令之外,你是否了解它的運作背景與流程?當需要調整依賴版本時,你又該如何進行呢?
眾所周知,大多數專案在開發過程中會使用一些開源的庫,例如 Predis、GuzzleHttp 等。
這些開源項目會因為舊功能的調整、新功能的開發、程式漏洞的修補等原因而不斷更新。然而,這些更新有時候並不是我們所期望的,甚至可能導致專案功能出現問題,因此過去的做法是將所需的版本內容直接複製到自己的專案中以避免更動。
這樣做會造成兩個依賴管理的問題。一方面,隨著開源項目的日益龐大,將這些項目納入 Git 管理會導致每次 Git 操作都耗費大量時間[註1];另一方面,由於現今的項目往往彼此依賴,因此當我們因為某些原因(例如 PHP 版本升級)需要更新開源項目的版本時,不論是調整或是新增開源項目都必須逐一確認所需的最低版本,這又是一大工程。
在這種情況下,Composer 這個依賴管理工具便成為你不可或缺的助手。
使用 Composer 進行依賴管理時,專案中會包含 composer.json
、composer.lock
和 vendor
資料夾這三個項目。一般來說,當我們執行 git clone
將專案下載下來後,專案內應該只會有 composer.json
和 composer.lock
,而不會有 vendor
資料夾,這是非常正常的,因為 vendor
的內容是透過 Composer 下載所需的套件版本後統一放置的。
composer.json
是一個 JSON 格式的檔案,裡面記載了專案所需的依賴項目及其指定的版本號,以及下載依賴時的相關設定。主要包含以下三個區塊:
-dev
參數時才會被確認。composer.json
範本(僅列出重點):
{
"name": "XXX",
"description": "OOO",
//...
"require": {
"php": ">=7.1.0",
"yiisoft/yii2": "~2.0.6",
"moonlandsoft/yii2-phpexcel": "*",
"yiisoft/yii2-redis": "^2.0",
},
"require-dev": {
"yiisoft/yii2-debug": "~2.0.0",
},
"config": {
"process-timeout": 1800,
//...
},
}
composer.lock
是在實際執行下載依賴套件時生成的檔案,裡面詳細記錄了要下載的所有依賴項目的各種資訊,包括名稱、版本號、下載路徑、該依賴項目的依賴項目,以及其許可證等。此外,檔案的最上方還有內容的 hash 值(content-hash
)。
由於 composer.lock
的內容比 composer.json
更為詳細,因此也會納入 Git 版控之中。原則上,這個檔案的內容一般不會被手動修改。簡單來說,可以將 composer.json
視為是給工程師看的,而 composer.lock
則是給電腦處理的。
當所有依賴項目完全下載完成後,vendor
資料夾底下會生成一個 autoload.php
檔案,內容主要是這次下載的 hash 值。當我們在程式碼中引用依賴套件時,會根據這個 hash 值找到 vendor/composer
裡的相關設定,並接著找到所需的依賴項目內容。
簡單來說,如果沒有 autoload.php
,則表示你的依賴項目下載不完整,這樣程式碼將無法運行。
如上所述,當你 git clone
專案後,第一件事是確認 composer.json
和 composer.lock
這兩個檔案是否存在。如果都存在,基本上可以放心執行 composer install
來進行下載[註2]。如果只有 composer.lock
,那麼在下載依賴時基本上沒有問題,但在未來的更新和維護上會相對麻煩。如果只有 composer.json
,那…你可能需要祈禱之前的同事們都已更新這個檔案,讓你能下載到正確的依賴版本。
確認檔案後,就可以直接執行 composer install
了!下載完成後,請務必確認是否產生了 autoload.php
檔案。因為有時候依賴項的內容龐大,可能會導致超時失敗,此時可以調整 composer.json
中的超時設定,以避免這個問題。
原則上,只要有 autoload.php
,就表示依賴下載完成,專案可以正常使用了。
升級(包括更新依賴項目版本)的細節有很多,之後我會額外撰寫一篇文章詳述,這裡僅大致描述步驟。
首先,你需要確認要調整的依賴項目以及希望更新到的版本。一般建議盡量直接指定詳細的版本號碼,而非僅指定大版本號碼,這樣可以避免因更新時間過長而導致依賴項目有額外的更新內容,進而造成本地開發正常使用但正式環境出現問題的情況。
接下來,你需要更新 lock 檔,主要有兩種方法(請注意指令不同):
composer update 依賴項目
讓程式自動抓取並更新 lock 檔內容,並一併更新相關依賴項目。需要注意的是,這個指令必須指定要更新的項目,否則會將所有可更新的依賴項目全部進行更新。composer install
來重新產生 lock 檔案並下載依賴項目。這種方法非常危險,因此不太推薦。但有時候,lock 檔裡面有一些前人留下的奇怪內容,此舉可以重整整個 lock 檔。按照上述方法執行後,檔案內容應該會有所更新,包括檔案內容的 hash 值。接下來,你需要測試更新後的功能是否正常,確認是否有意料之外的錯誤,以及單元測試是否通過等。
要注意的是,composer.lock
也應該納入版控,以造福下一位接手的工程師!!!
[註1] 筆者曾經遇過一個極端的專案,由於大量引用開源功能,整個專案的90%內容都依賴於開源項目。在這種情況下,將其納入 Git 版控顯然不是一個明智的選擇。
[註2] 筆者曾遇過兩個檔案中的套件版本不相符的情況,最終不論使用 composer.json
還是 composer.lock
下載依賴都無法成功執行專案。那時候只能請前輩將整個 vendor
資料夾的內容轉給我,但顯然這樣的專案未來也非常難以進行套件更新。