Flutter Pub私有倉庫搭建

在Flutter開發的過程中也會遇到三方庫管理的問題,有些三方庫需要進行再定制,我們會fork一份下來進行維護,此外也有一些私有組件不適合上傳到公有倉庫,于是就有了自己搭建私有pub庫的需求。這篇文章主要介紹如何搭建私有化pub倉庫,及在搭建私有pub倉庫過程中的探索。首先進行準備工作,創建一個package,之后用它來進行上傳到公有倉庫和私有倉庫,在這個過程中會介紹怎么創建公有倉庫和私有倉庫。

1.準備package

首先介紹一下pub倉庫,pub倉庫里存放的是開發者提交的Package,Package包含以下兩種類別:

? 純 Dart 庫:用 Dart 編寫的傳統 package,比如 path。其中一些可能包含 Flutter 的特定功能,因此依賴于 Flutter 框架,其使用范圍僅限于 Flutter,比如 fluro

? 原生插件:使用 Dart 編寫的,按需使用 Java 或 Kotlin、ObjC 或 Swift 分別在 Android 和/或 iOS 平臺實現的 package。一個具體的例子是 battery

詳情可以參考Flutter Packages 的開發和提交,里面對于package的介紹。

想要提交自己的package,那么咱們就先創建一個吧。

// 創建純dart插件 package
flutter create --template=package hello

// 創建原生插件 package
flutter create --org com.example --template=plugin hello

r咱們就以復雜的為例,創建一個包含原生插件的package,在終端輸入以上指令,或者可以直接通過Android Studio來創建。

newpackage.png

創建好之后,一個最簡單的package就生成了,如果上傳到pub倉庫的話,就可以讓其他開發者輕松使用啦。

package的目錄如下,我創建了一個叫做dh_plugin的package,作為下面操作的例子:

packagefile.png

提交之前,請確保 pubspec.yamlREADME.md 以及 CHANGELOG.md 文件已被審查,以保證其內容的完整性和正確性。

其中最主要的是pubspec.yaml的編寫,參考Pubspec 文件,當然其中的設置不會全用,一個最簡單的pubspec.yaml只需要包含以下幾項即可:

name: dh_plugin
description: plugin test
version: 0.0.1
author: 作者 <郵箱> (或者 authors: )
environment:
 sdk: ">=2.1.0 <3.0.0"
homepage: 介紹當前package地址

可以通過dry-run命令以檢驗是否所有內容都通過了分析:

bogon:dh_plugin whqfor$ flutter packages pub publish --dry-run
Publishing dh_plugin 0.0.3 to https://pub.flutter-io.cn:
···
Package has 0 warnings.

其中出現一兩處warning也可以,只要沒有error即可。
到此package的準備工作就做好了,接下來就可以準備上傳了。

2.公有倉庫

介紹搭建私有倉庫之前,咱們先看下公有倉庫如何搭建,其發布流程差不多,主要差異在于倉庫的搭建,當然如果不關心公有庫的話也可以略過這部分不看。

通過dry-run命令的檢查后,開始上傳吧,上傳命令去掉dry-run就是了

bogon:dh_plugin whqfor$ flutter packages pub publish
Publishing dh_plugin 0.0.3 to https://pub.flutter-io.cn:
···
Looks great! Are you ready to upload your package (y/n)? 
輸入y
Pub needs your authorization to upload packages on your behalf.
In a web browser, go to https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&response_type=code&client_id=818368855108-8grd2eg9tj9f38os6f1urbcvsq399u8n.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A60578&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email
Then click "Allow access".
Waiting for your authorization...

如果環境搭建好的情況下,到這里上傳公有package的流程就到此結束了。
不過你可能會有疑問package上傳到哪里了吶?
這就和上面長長的一串authorization 地址有關聯了,從 https:// 開始拷貝直到userinfo.email結束,復制到瀏覽器中去。瀏覽器會根據鏈接帶著的信息進行解析,選擇你的google賬號進行登錄,之后就會看到

Pub Authorized Successfully
The pub client has been successfully authorized. You may now use it to upload packages and perform other tasks.

終端的進度也會變成,開始上傳啦

Waiting for your authorization...
Authorization received, processing...

等等,前面提到輸入google賬號...
是的,還需要創建一個a verified publisher賬號,發布 package

To create a verified publisher, follow these steps:
1  Go to pub.dev.
2  Log in to pub.dev using a Google Account.
3  In the user menu in the top-right corner, select Create Publisher.
4  Enter the domain name that you want to associate with your publisher (for example, dart.dev), and click Create Publisher.
5  In the confirmation dialog, select OK.
6  If prompted, complete the verification flow, which opens the Google Search Console.
  ?  When adding DNS records, it may take a few hours before the Search Console reflects the changes.
  ?  When the verification flow is complete, return to step 4.

一般的開發者可能會卡在第4步,需要域名認證。
在pub.dev登錄之后,點擊自己的頭像 creat publisher,出現如下界面

publisher.png

輸入域名,之后按照提示進行驗證

auth.png

選擇自己的驗證方式,我選擇是dns驗證,將txt記錄添加到dns解析中。

dns.png

創建好了之后可以在pub.dev進行管理packages也可以進行組員管理。
有沒有覺得好麻煩,publisher創建終于告一段落。
剛才上傳怎么樣了吶?失敗了...

Waiting for your authorization...
Authorization received, processing...
It looks like accounts.google.com is having some trouble.
Pub will wait for a while before trying to connect again.
OS Error: Operation timed out, errno = 60, address = accounts.google.com, port = 61646
pub finished with exit code 69
bogon:dh_plugin whqfor$ 

雖然瀏覽器通過各種手段翻·墻成功,但是終端還不能翻·墻,可以在終端ping google.com試試通不通,配置終端翻·墻在這里阻塞了半天,google 搜索終端翻·墻的前10個方法都試了一遍還是沒有配置好,如果你知道歡迎交流一下。

這是由于瀏覽器是通過傳輸層(第四層)ssr的socks代理,終端ping走的是網絡層(第三層)協議問題解釋
好吧,可能到這里就要放棄了吧。
先別走,看看私有倉庫怎么創建吧,不用經過認證,秒上傳。

3.私有倉庫

如果你搭建好了私有倉庫,上傳私有package和公有package流程差別不大。只是在pubspec.yaml多了一個字段publish_to標識私有倉庫地址。
完整的pubspec.yaml如下

name: dh_plugin
description: plugin test
version: 0.0.1
author: 作者 <郵箱> (或者 authors: )
publish_to: http://10.29.32.176:8080
environment:
 sdk: ">=2.1.0 <3.0.0"
homepage: 介紹當前package地址

publish_to官方介紹

首先我們需要搭建私有服務器,官方demo在此pub_server
按照pub_server的介紹搭建本地服務之后,就可以將package上傳私有倉庫啦,保持私有主機pub_server運行不要關機。

pubserver.png

注意這個默認地址是本地地址,如果想其他人也可以進行訪問的話,需要將這個地址進行修改。
修改方式如下圖,將localhost改為私有庫所在主機的ip地址即可。
修改pub_server源碼:

host.png

在啟動pub_server之后就可以發布啦,

server.png

發布指令為

flutter packages pub publish --server=http://10.29.XX.XXX:8080
Waiting for your authorization...
Authorization received, processing...
It looks like accounts.google.com is having some trouble.
Pub will wait for a while before trying to connect again.
OS Error: Operation timed out, errno = 60, address = accounts.google.com, port = 50135
pub finished with exit code 69

不出意外還是出錯,這是因為私有倉庫也是需要經過publisher驗證,被墻害苦了,那么自己的私有倉庫能夠不進行publisher驗證嗎?答案是可以的。

Flutter是完全開源的,那咱們首先看看pub工具怎么實現的,找到/Users/whqfor/Flutter/flutter/bin/cache/dart-sdk/bin/pub,用文本編輯器打開

# Run the pub snapshot.
DART="$BIN_DIR/dart"
if array_contains "--no-preview-dart-2"  "${VM_OPTIONS[@]}"; then
  echo "Pub no longer supports Dart 1"
  exit -1
else
  SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot"
  exec  "$DART"  "${VM_OPTIONS[@]}"  "$SNAPSHOT"  "$@"
fi

pub執行的其實是個pub.dart.snapshot文件,pub的源碼github也有,把里面的官方驗證去掉不就可以了嗎?

pub.png

這里感謝ameryzhu的文章指明了關鍵點替換oauth2。大家可以fork他的修改,然后使用fork的源碼生成自己的mypub.dart.snapshot文件即可。放到pub.dart.snapshot文件同目錄,然后修改以上pub源碼,將

SNAPSHOT="$BIN_DIR/snapshots/pub.dart.snapshot改為自己生成的SNAPSHOT="$BIN_DIR/snapshots/mypub.dart.snapshot

怎么生成snapshot,以及什么是snapshot可以看這里,可以使用這個指令:

dart --snapshot=<output_file> <dart_file>
例子:
dart --snapshot=mypub.dart.snapshot /Users/whqfor/Desktop/Pub/pub-master/bin/pub.dart 

生成的 mypub.dart.snapshot默認在當前目錄/Users/whqfor/下。將mypub.dart.snapshot放置到和pub.dart.snapshot同目錄。
到此構建pub私有庫的流程結束啦。
再來發布一次

bogon:dh_plugin whqfor$ flutter packages pub publish --server=http://10.29.32.176:8080
Publishing dh_plugin 0.0.4 to http://10.29.32.176:8080:
···
Suggestions:
* ./CHANGELOG.md doesn't mention current version (0.0.4).
 Consider updating it with notes on this version prior to publication.
Package has 1 warning. Upload anyway (y/n)? y
Uploading...
Successfully uploaded package.

秒傳有沒有。
那么怎么使用私有庫吶?dependencies

dependencies:
 transmogrify:
 hosted:
 name: transmogrify
 url: http://some-package-server.com
 version: ^1.0.0

在本demo中對應的即是

dh_plugin:
 hosted:
 name: dh_plugin
 url: http://10.29.XX.XXX:8080
 version: 0.0.4

注意事項:更細package時,版本號變化,記得也更新CHANGELOG.md

例如:

## 0.0.1
* TODO: Describe initial release.

## 0.0.2
* 更換pub_server ip地址

## 0.0.3
* 修改一點內容驗證是否成功

好啦,感謝看到這里,如有疑問歡迎與我交流。

幾個問題:

1.更改默認snapshot影響公有package使用嗎?
經過自測不影響

2.pub源碼怎么同步
這個問題沒有太好的答案,定期merge官網更新吧,可以參考咸魚的方案,還在研究。

3.自己的package發布到那里了吶?
在隱目錄/Users/whqfor/.pub-cache/hosted/中帶ip地址和8080端口的文件中。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容