有個 OpenBuild 的社區生態專案貌似搁置得有點久了,發起者想要繼續迅速地推進,但一直沒什麼起色,一時間也找不到其他合適的人 —— 沒辦法,只能我去接下來了。
這個專案要做的事是給開源問答平台 Answer 開發一個支持用 Web3 錢包登錄的插件;從要實現的功能上來看,這應該是個很小的專案,開發加上聯調前後端算在一起估計 1.5~3 個人日。
然而,現實卻給了我一棒槌……
需求分析#
初步從官方的插件開發文檔來看,要做的應該是「連接器 - 後端插件」。
以此為前提,大致了解了下幾個已有連接器的代碼發現,每個插件只能指定一種型別,且後端插件是不能直接支持 UI 的,它們都是跳轉到外部的授權用 URL。
可是,Web3 錢包登錄並沒有現成的外部授權用 URL,要實現需求那就可能得另外編寫個配套的「路由 - 標準 UI 插件」,開發一個頁面:
- 顯示連接錢包按鈕;
- 連接錢包後用戶簽名;
- 從後端獲取 nonce,前端傳入錢包地址;
- 前端喚起錢包讓用戶簽名;
- 簽名後調用後端授權接口,前端傳入用戶簽名信息、錢包地址等;
- 請求成功後返回到主界面。
上面文字加粗部分是需要與後端進行數據交互的,也就是得有兩個後端接口。
流程看起來很簡單是吧?也確實是很簡單!
開發過程#
後端部分幾個月前就已大體開發完成,基本只差前端界面和聯調。
由於這個專案沒有前後端分離,我要是完整運行的話,從官方文檔的信息來看,得安裝 Docker、數據庫等。
但我本地之前沒安裝這些,目前也沒有做其他用到這些的專案的打算,不可能單單為了這而去安裝幾乎用不到的軟體佔用寶貴的電腦存儲空間。
於是,我就先採用純前端的方式把界面佈局、樣式和功能開發好,即便後端接口請求都失敗了;算上閱讀文檔、代碼熟悉插件基本機制的時間,大概用了 1 人日左右完成。
跟負責後端的人約了周末的一天集中聯調,爭取搞定交付,可卻挫折連連……
因為我本地沒有安裝並設置後端環境,無法走正常的插件加載運行流程,有些問題在開發階段並未遇到;當讓後端小夥伴下載我的代碼跑整個流程時,各種「奇奇怪怪」的問題就冒了出來……
起初,基本一遇到前端問題就發起視頻會議,看他是怎麼操作的,我指導他去解決 —— 搞了幾次我突然發覺,這不就是傳說中的「結對編程」嗎?😂😂😂
後來我心想:「這樣下去不行啊,實在是太低效了!」
最終,我嘗試放下心中的芥蒂,讓他指導我如何把後端跑起來,就可以自己去測試並調整前端代碼了。
被指導後發現,實際我真的只需額外安裝 Go 就行,數據庫直接用 macOS 自帶的 SQLite 即可,更不用去搞 Docker—— 真應該一開始就讓他當我的「導航員」!
雖說之後並沒有順風順水,但我們無需再開視頻會議了,有問題只需微信上發個截圖並簡單描述下就可以了,效率大大提升!
我在測試自己開發的插件時,還發現了一個插件加載機制上的 bug,就順手修掉並提了個 PR,成就額外 +1!😁😁😁
經過一兩天的收尾,我們開發的插件也交付了,在官方 reviewer 的指導與建議下,將原本的兩個插件合併為一個—— 表面上是「路由 - 標準 UI 插件」,實則也是「連接器 - 後端插件」。
至此,我們集中在這三五天裡處理掉了「便秘」問題,撒花!🎉🎉🎉
踩坑經驗#
本次是基於主專案版本 1.4.0 開發,官方文檔、插件體系的不完善以及自己較為別扭的心態令我踩了些坑,下面針對前端開發人員分享下本地調試的要點,以便少走彎路!
首先,對像我一樣介意的人再次強調下 ——只需額外安裝 Go,數據庫可用 macOS 自帶的 SQLite!
以我們開發的插件為例,假設插件名為 connector-wallet
——
後端環境#
確保在主專案的 cmd/answer/main.go
裡引入了插件包,即使它當前並不存在:
import (
answercmd "github.com/apache/incubator-answer/cmd"
_ "github.com/apache/incubator-answer-plugins/connector-wallet"
)
無論是純前端插件還是「表面上是前端插件」的插件,在調試時需將用模板生成的代碼放到 ui/src/plugins
文件夾下,並在根文件夾創建 go.work
文件:
go 1.22.0
toolchain go1.23.2
use (
.
./ui/src/plugins/connector-wallet
)
執行 make ui
構建前端代碼,再用 go build -o answer ./cmd/answer/main.go
編譯後端代碼,會生成 answer
文件,接下來的操作都用它。
執行 ./answer init -C ./answer-data/
初始化系統,需要在瀏覽器中訪問 http://localhost
填寫信息,其中數據庫要選擇 SQLite 且文件存放路徑把 /data
替換成 answer-data
文件夾的絕對路徑。
執行 ./answer run -C ./answer-data/
啟動後端服務,再次訪問 http://localhost
即可登錄初始賬號並到後台啟用要調試的插件!
最後將 ui/.env.development
中的 REACT_APP_API_URL
改為 http://localhost:80/
就能啟動前端開發伺服器訪問後端接口了。
前端環境#
安裝好依賴後,需將插件文件夾下的幾個文件夾刪除,否則會引起問題:
- 刪除
dist
文件夾和package.json
中的main
、module
、types
、exports
字段,否則頁面渲染的是編譯後的文件,源文件的變動不會響應刷新; - 刪除
node_modules
,否則插件中讀取的 i18n 配置不是主專案的,可能是由於react-i18next
底層沒使用單例模式而實際產生了兩份配置。
發布插件#
若前端插件中添加了額外的依賴,需要修改插件包中 vite.config.ts
的配置:
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
export default defineConfig({
plugins: [
...,
cssInjectedByJsPlugin(), // 有樣式文件引入時必須,不然會樣式錯亂
...,
],
build: {
...,
rollupOptions: {
external: [
..., // 把自己額外的依賴進行聲明
],
output: {
globals: {
..., // 把自己額外的依賴進行聲明
},
},
},
},
});
結語#
感謝 OpenBuild 提供的這次機會,雖說一開始因為有我認為更重要更優先的事需要去做而不太想接…… 但時間使勁兒擠擠的話還是會有的嘛!
感謝後端小夥伴的積極配合,讓我們一起把這拖延幾個月的「便秘」問題給解決了!
感謝 Answer 官方的 reviewers 陪我在 PR 裡練英語,為我之後的國際化發展開了個好頭兒!
雖然之前我也給其他幾個開源專案提過 PR,但基本都是小修小補,每次都沒啥交流就直接合進去了;這次給 Answer 做貢獻讓我有了真正的做開源的感覺!
Salute to all OPEN SOURCERORs!!!