Flutter如何通過(guò)一行命令解決多個(gè)pubspec.yaml文件的依賴(lài)項(xiàng)問(wèn)題
前言
項(xiàng)目為了模塊化,創(chuàng)建了一堆Package
和Plugin
,這么做沒(méi)什么問(wèn)題,但是遇到Flutter SDK目錄路徑變化或者其他一些情況導(dǎo)致需要重新獲取依賴(lài)項(xiàng)時(shí)就麻煩了。麻煩之處在于需要在每個(gè)pubspec.yaml
文件所在的目錄中運(yùn)行flutter pub get
命令,雖然也不是什么大問(wèn)題,但是這種重復(fù)簡(jiǎn)單的操作實(shí)在不想做。
開(kāi)發(fā)環(huán)境
- Flutter: 3.10.2
- Dart: 3.0.2
Flutter內(nèi)置命令
如果你研究過(guò)Flutter SDK(Flutter框架項(xiàng)目),那么你對(duì)flutter update-packages
命令一定不陌生,執(zhí)行這個(gè)命令可以獲取Flutter框架項(xiàng)目所需要的全部依賴(lài)項(xiàng),避免一個(gè)個(gè)去執(zhí)行flutter pub get
命令。可惜這個(gè)命令只能用于Flutter框架項(xiàng)目,不過(guò)我們可以先看看Flutter是怎么做的,然后自己實(shí)現(xiàn)一個(gè)。
根據(jù)flutter update-packages
命令執(zhí)行時(shí)的輸出日志Ran pub get in ...
,可以快速定位到update_packages.dart
文件(位于Flutter框架項(xiàng)目/packages/flutter_tools/lib/src/commands
目錄)中的_runPubGetOnPackages
方法:
Future<void> _runPubGetOnPackages(List<Directory> packages) async { ... try { ... for (final Directory dir in packages) { unawaited(queue.add(() async { final Stopwatch stopwatch = Stopwatch(); stopwatch.start(); await pub.get( context: PubContext.updatePackages, project: FlutterProject.fromDirectory(dir), // All dependencies should already have been downloaded by the fake // package, so the concurrent checks can all happen offline. offline: true, outputMode: PubOutputMode.none, ); stopwatch.stop(); final double seconds = stopwatch.elapsedMilliseconds / 1000.0; final String relativeDir = globals.fs.path.relative(dir.path, from: Cache.flutterRoot); globals.printStatus('Ran pub get in $relativeDir in ${seconds.toStringAsFixed(1)}s...'); })); count += 1; } ... } catch (exception) { // ignore: avoid_catches_without_on_clauses status.cancel(); rethrow; } ... }
pub.get
方法的作用就是執(zhí)行pub get
命令。通過(guò)這個(gè)方法大概也清楚了,其實(shí)Flutter是通過(guò)遍歷全部項(xiàng)目路徑,然后一個(gè)個(gè)執(zhí)行pub get
命令的方式獲取的依賴(lài)項(xiàng)。那項(xiàng)目路徑列表是怎么獲得的呢?
根據(jù)_runPubGetOnPackages
方法的調(diào)用,找到packages
初始化的位置:
@override Future<FlutterCommandResult> runCommand() async { final List<Directory> packages = runner!.getRepoPackages(); ... await _runPubGetOnPackages(packages); return FlutterCommandResult.success(); }
繼續(xù)找下去會(huì)發(fā)現(xiàn),F(xiàn)lutter其實(shí)也是通過(guò)遞歸找到項(xiàng)目路徑(包含pubspec.yaml
文件的目錄路徑):
static List<String> _gatherProjectPaths(String rootPath) { if (globals.fs.isFileSync(globals.fs.path.join(rootPath, '.dartignore'))) { return <String>[]; } final List<String> projectPaths = globals.fs.directory(rootPath) .listSync(followLinks: false) .expand((FileSystemEntity entity) { if (entity is Directory && !globals.fs.path.split(entity.path).contains('.dart_tool')) { return _gatherProjectPaths(entity.path); } return <String>[]; }) .toList(); if (globals.fs.isFileSync(globals.fs.path.join(rootPath, 'pubspec.yaml'))) { projectPaths.add(rootPath); } return projectPaths; }
這么一分析,好像Flutter用的方法也蠻簡(jiǎn)單的,大家一般也都能想的到。
一行命令實(shí)現(xiàn)
1. 命令使用
按照這個(gè)思路,我首先想到可以寫(xiě)一個(gè)shell
腳本,遞歸遍歷出全部的項(xiàng)目路徑,然后再挨個(gè)執(zhí)行flutter pub get
命令,結(jié)果寫(xiě)著寫(xiě)著發(fā)現(xiàn)完全用不到shell
腳本,一行命令就可以解決了。
完整命令如下:
find [path] -name "pubspec.yaml" -exec dirname {} \; | xargs -I {} flutter pub get -C {}
注意,使用時(shí)請(qǐng)將命令中的[path]
替換為你的Flutter項(xiàng)目路徑。如果命令就在Flutter項(xiàng)目路徑下執(zhí)行,那么可以直接使用以下命令(.
表示當(dāng)前路徑):
find . -name "pubspec.yaml" -exec dirname {} \; | xargs -I {} flutter pub get -C {}
2. 命令解釋
命令主要分前后兩部分,用管道符|
分割,前半部分用于查找所有的項(xiàng)目路徑,后半部分用于獲取全部的依賴(lài)項(xiàng)。
- find [path] -name "pubspec.yaml":在指定的路徑中遞歸查找所有名稱(chēng)為pubspec.yaml的文件
- -exec dirname {} \;:對(duì)于找到的每個(gè)文件,執(zhí)行dirname命令獲取目錄路徑
- |:管道符,將前一個(gè)命令的輸出傳遞給下一個(gè)命令
- xargs -I {} flutter pub get -C {}:xargs 命令的作用是將管道傳遞的輸入轉(zhuǎn)換為命令行參數(shù),-I 選項(xiàng)用于指定替換字符串 {}。簡(jiǎn)單來(lái)說(shuō),每一個(gè)項(xiàng)目路徑都會(huì)轉(zhuǎn)化為flutter pub get -C 項(xiàng)目路徑命令執(zhí)行
可以通過(guò)執(zhí)行man find
和man xargs
命令獲取更多關(guān)于find
和xargs
命令的使用方法。
3. 命令擴(kuò)展
前面的命令用于獲取全部依賴(lài)項(xiàng),稍微修改后同樣也可以用于升級(jí)全部依賴(lài)項(xiàng):
find [path] -name "pubspec.yaml" -exec dirname {} \; | xargs -I {} flutter pub upgrade -C {}
最后
到此這篇關(guān)于Flutter如何通過(guò)一行命令解決多個(gè)pubspec.yaml文件的依賴(lài)項(xiàng)問(wèn)題的文章就介紹到這了,更多相關(guān)Flutter pubspec.yaml文件的依賴(lài)項(xiàng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android模擬實(shí)現(xiàn)滑動(dòng)解鎖界面
這篇文章主要為大家詳細(xì)介紹了Android模擬實(shí)現(xiàn)滑動(dòng)解鎖界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Android 簡(jiǎn)單封裝獲取驗(yàn)證碼倒計(jì)時(shí)功能
倒計(jì)時(shí)效果相信大家都不陌生,我們可以使用很多種方法去實(shí)現(xiàn)此效果,這里自己采用 CountDownTimer 定時(shí)器簡(jiǎn)單封裝下此效果,方便我們隨時(shí)調(diào)用。下面小編給大家分享android驗(yàn)證碼倒計(jì)時(shí)封裝方法,感興趣的朋友一起看看吧2018-01-01Android實(shí)現(xiàn)Unity3D下RTMP推送的示例
像Unity3D下的RTMP或RTSP播放器一樣,好多開(kāi)發(fā)者苦于在Unity環(huán)境下,如何高效率低延遲的把數(shù)據(jù)采集并編碼實(shí)時(shí)推送到流媒體服務(wù)器,實(shí)現(xiàn)Unity場(chǎng)景下的低延遲推拉流方案。本文介紹幾種RTMP推送的方案2021-06-06Android監(jiān)聽(tīng)系統(tǒng)來(lái)電并彈出提示窗口
本篇文章主要介紹了Android監(jiān)聽(tīng)系統(tǒng)來(lái)電并彈出提示窗口,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10Android Studio中Logcat寫(xiě)入和查看日志
大家好,本篇文章主要講的是Android Studio中Logcat寫(xiě)入和查看日志,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01Android Bitmap的加載優(yōu)化與Cache相關(guān)介紹
這篇文章主要介紹了Android中性能優(yōu)化之Bitmap的加載優(yōu)化與Cache相關(guān)內(nèi)容介紹,文中介紹的很詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-02-02Android自定義View實(shí)現(xiàn)圓形切圖效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)圓形切圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android編程獲取設(shè)備MAC地址的實(shí)現(xiàn)方法
這篇文章主要介紹了Android編程獲取設(shè)備MAC地址的實(shí)現(xiàn)方法,涉及Android針對(duì)硬件設(shè)備的操作技巧,需要的朋友可以參考下2017-01-01