Dart 包管理工具 pub 常用命令解析
Dart采用pub管理包,介紹幾個常用的pub命令。
1、pub get
獲取包依賴。具體是指獲取在pubspec.yaml文件中dependencies目錄下指定的依賴的包。在實際運行時,pub會先到pub cache目錄下該依賴項是否存在,不存在才會去獲取。默認情況下,Pub 會創建一個 .packages 文件用于映射 Package 名到位置 URI。在創建 .packages 文件之前,Pub 常常還會創建一個 packages 目錄。
pub get 命令獲取新依賴項后會寫入一個 lockfile 文件以確保下次執行該命令時會使用相同的依賴項版本。應用型的 Package(即Application package) 應該總是簽入該 lockfile 文件以控制來源,從而確保在將 Package 部署到生產環境時所有的依賴項對于所有開發者而言都是相同的版本。庫類型的 Package(即Libraries package) 則不需要簽入 lockfile 文件,因為它們可能需要使用到不同的依賴項版本。
獲取完畢后,就可以在代碼中通過import命令導入并使用這些包了。
當更新pubspce文件中的包依賴時(包括更新、增加、刪除等),運行pub get命令,會自動更新相關內容。現在的IDE一般都不需要手動運行該命令了,比如VS CODE的dart插件,每次更新并保存pubspec文件時,會自動運行該命令。
如果沒有網絡、或者你不想 Pub 去線上檢查,可以使用 --offline 命令參數讓該命令在離線模式下執行。在離線模式下,Pub 只會從本地緩存區查找已經下載到的可用 Package。
2、pub run
使用該命令可以從命令行運行一個位于你 Package 中或 Package 依賴項中的腳本。注意,該命令只能運行位于你當前package或其依賴項中的腳步。如果需要運行其它package中的腳步,需要使用 global參數。比如我自己寫了一個計算器,入口位于bin\calculate.dart,則在命令行可以通過如下命令運行:
d:\workspace\dart\calculate>pub run calculate
若有指定目錄,可以加上指定目錄,如
pub run example\calculate
若要運行依賴項中的腳本,前面加上包名即可,比如我運行項目中依賴的表達式解析包(exp_parse)的例子parse.dart,其位于exp_parse/bin/parse.dart:
pub run exp_parse:parse
說重點:你只能運行位于其它 Package bin 目錄下的腳本,其它目錄下的腳本則不可運行。
3、pub global
Pub 的 global 選項允許你在任意位置下從命令行運行 Dart 腳本。在 激活 Package 后,你可以 運行 該 Package bin 目錄下的腳本。停用 Package 后你可以從全局可用的 Package 列表中將其移除。該命令的用處比較多,下面詳細介紹。
3.1 激活腳本(activate)
在使用全局命令之前,首先需要用activate參數激活package。該 Package 可以是在 pub.dev 網站、Git 倉庫或者你當前的電腦上。一旦你激活了 Package,就可以運行位于 該Package bin 目錄下的腳本。
3.1.1 激活 pub.dev 網站上的 Package
激活 pub.dev 網站上的一個 Package。例如激活markdown包:
pub global activate markdown
3.1.2 激活 Git倉庫中的 Package
可以使用 --source git(或 -sgit 簡寫)命令參數可以激活位于 Git 倉庫中的 Package。示例如下:
pub global activate --source git https://github.com/dart-lang/async_await.git pub global activate -sgit https://github.com/dart-lang/async_await.git
3.1.3 激活本地的package
更多的時候,我們是需要激活本地的包,比如我們自己開發的一些工具,激活為全局可用,可以通過使用 activate --source path <path> 命令參數來實現。這塊在實操時,有好幾個坑,目前官方文檔上沒有說明。我的項目pubspec文件如下:
name: data_intel environment: sdk: ^2.10.4 dependencies: hello_image: path: ../hello_image
3.1.3.1 路徑(文件夾)與包名
path可以使用絕對路徑,也可以使用相對路徑。但包名是個坑。注意,這里要使用文件夾名,而不是包名(尤其是二者不一致時),否則會提示找不到pubspec文件。比如我的文件夾名是 data_intelligence,但包名是 data_intel,第一次激活時,命令如下(相對路徑):
pub global activate --source path data_intel
系統提示:Could not find a file named "pubspec.yaml" in "D:\Compute\Develop\Workspace\Dart\data_intel" 這說明pub 是按照文件夾名來找的。解決辦法,要么將包名更改為與文件夾名一致,要么采用文件夾名作為path參數。采用文件夾名,繼續運行:
D:\Compute\Develop\Workspace\Dart> pub global activate --source path data_intelligence
輸出如下:
Resolving dependencies... Got dependencies! Activated data_intel 0.0.0 at path "D:\Compute\Develop\Workspace\Dart\data_intelligence".
發現沒有,因為pubspec中定義的包名為data_intel,pub global activate激活的包名仍為data_intel。
3.1.3.2 文件位置:
pub global activate命令運行后,實際上做了什么動作?其實是在PUB_CACHE變量(參考我另一篇博文,pub環境變量配置)指定的文件夾下,創建了一個global_packages的文件夾(我是首次激活,否則該文件夾會存在且可復用),其中有一個data_intel的文件夾,注意,這里是按包名來命名的。該文件夾中又有一個pubspec.lock的文件。
3.1.3.3 運行
激活以后,理論上可以運行了。這里要注意,需要先將%PUB_CACHE%\bin加入環境變量path中。bin目錄下文件名為main.dart,現在在命令行輸入main,提示錯誤(powershell):
無法將“main”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫,如果包括路徑,請確保 路徑正確,然后重試。 所在位置 行:1 字符: 5 + main <<<< + CategoryInfo : ObjectNotFound: (main:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
更換命令如下,仍提示錯誤:
PS C:\> pub global run main No active package main. PS C:\> pub global run data_intel Could not find bin\data_intel.dart.
這里的坑在于沒有在pubspec.yaml文件中指定可運行的腳本。修改pubspec,增加如下代碼:
executables:
main:
然后重新激活,即重新運行命令:
pub global activate --source path data_intelligence
輸出如下:
Resolving dependencies... Got dependencies! Package data_intel is currently active at path "D:\Compute\Develop\Workspace\Dart\data_intelligence". Installed executable main. Activated data_intel 0.0.0 at path "D:\Compute\Develop\Workspace\Dart\data_intelligence".
發現沒有,此時增加了兩行藍色的輸出,重要的是 Installed executable main. 安裝了可執行的main。那么到底發生了什么呢?我們繼續到PUB_CACHE中看,發現cache目錄下增加了一個bin目錄,其中有一個文件:main.bat(之前沒有),內容為:
@echo off rem This file was created by pub v2.10.4. rem Package: data_intel rem Version: 0.0.0 rem Executable: main rem Script: main pub global run data_intel:main %*
如上,其實是做了一個命令的快捷方式。這時再在命令行執行main,即可執行。但執行時又發現一個坑,項目中有讀寫文件,用的都是相對路徑,均報錯。后來又改成絕對路徑(或者和PUB_CACHE/bin相對的相對路徑也可),執行正常。
關于這點,最后補充一下,可以在bin文件夾中包含多個腳本,同樣也可以在pubspec中配置多個可執行腳本名稱。pubspec中配置的數量<=bin目錄下腳本的數量。
3.1.3.4 pubspec中可執行命令名稱與bin目錄下文件的對應:
繼續折騰,main這個名稱太籠統,我將pubspec中的代碼改為:
executables:
dtree:
如然后重新運行
pub global activate --source path data_intelligence
結果輸出如下:
Resolving dependencies... Got dependencies! Package data_intel is currently active at path "D:\Compute\Develop\Workspace\Dart\data_intelligence". Installed executable dtree. Warning: Executable "dtree" runs "bin\dtree.dart", which was not found in data_intel. Activated data_intel 0.0.0 at path "D:\Compute\Develop\Workspace\Dart\data_intelligence".
增加了一條紅色的警告信息。嘗試在命令行運行 dtree,輸出如下:
PS D:\Compute\Develop\Workspace\Dart> dtree
Could not find bin\dtree.dart.
看來pub 尋址是按在pubspec中配置的“executables:”的名稱來尋找腳本的。
3.1.4 更新已經激活的package
這個前面其實已經提到了,重復運行pub global activate 命令即可。可以對比cache目錄下的文件,你會發現文件是最新生成的。
3.2 運行腳本
其實前面已經提到,采用pub global activate激活后,并將%PUB_CACHE%\bin添加進系統path,即可從命令行運行該腳步。如果還有問題,可以參考前面的坑,看是否在pubspec中配置了executables參數,或者是否修改了path環境變量。
如果在pubspec中沒有配置executables參數,激活后(注意,仍然需要先運行pub global activate命令),仍然可以通過 pub global run 命令進行運行。如先反激活(或稱為卸載)剛才的data_intel包,然后在pubspec中刪除executables參數配置,然后重新運行:
PS D:\Compute\Develop\Workspace\Dart> pub global run data_intel:main
No active package data_intel.
這時候提示沒有激活。運行pub global activate --source path data_intelligence進行激活,然后運行:
PS D:\Compute\Develop\Workspace\Dart> pub global run main
No active package main.
提示沒有激活main,這告訴我們需要在腳本名稱前加上包名,如前文main.bat中最后一行所示。如果只有包名,沒有腳本名,則也會提示錯誤:
PS D:\Compute\Develop\Workspace\Dart> pub global run data_intel
Could not find bin\data_intel.dart.
運行
pub global run data_intel:main
則正確。但繼續測試,發現,如果腳本名和包名一致,則可運行正確。執行如下步驟測試:
a. 反激活data_intel;
b. 刪除pubspec中executables參數;
c. 重新激活data_intel;
此時運行,結果正常~!
PS E:\> pub global run data_intel
hello pub!
結合前面的錯誤,總結如下: 當執行
pub global run pkg_name
命令,不帶腳本名稱時,其實會到pkg_name\bin目錄下尋找與pkg_name同名的dart文件,即pkg_name.dart,如無則報錯。
3.3 配置package為可執行
這個前面已經提到,在pubspec中配置executables參數即可,注意參數名要和bin目錄下的腳本名稱要保持一致。
3.4 停用(卸載、反激活)package
可以使用 deactivate參數來停用(卸載)已經激活的package。此時不需要指定path參數路徑,示例:
PS E:\> pub global deactivate data_intel
Deactivated package data_intel 0.0.0 at path "D:\Compute\Develop\Workspace\Dart\data_intelligence".
查看cache目錄,發現pub刪除了bin目錄下的bat文件和global_packages文件夾下的對應的包文件。
3.5 列出已激活的所有的包
可以使用命令
pub global list
列出所有已激活的包。
4、pub upgrade
可以通過pub upgrade更新包依賴。pub upgrade 命令與 pub get 命令一樣,都是用于獲取依賴項的。不同的是 pub upgrade 命令會忽略掉任何已存在的 lockfile 文件,因此 Pub 可以獲取所有依賴項的最新版本。
在沒有指定其它參數的情況下,pub upgrade 命令會獲取當前工作目錄下 pubspec.yaml 文件中所列出的所有依賴項的最新版本,包括這些依賴項中內部依賴的其它依賴項。當然,也可以指定package的名稱,僅更新指定的包(依賴會一起更新)。其余的功能與pub get類似。
5、最后:其它命令
pub還有一些其它的命令,如deps、cache等,用法相對簡單,這里不再贅述,詳情可參考官網文檔:
浙公網安備 33010602011771號