一、背景與簡介
在傳統的 PC Web 前端開發中,瀏覽器為開發者提供了體驗良好、功能豐富且強大的開發調試工具,比如常見的 Chrome devtools 等,這些調試工具極大的方便了開發者,它們普遍提供查看頁面結構、監聽網絡請求、管理本地數據存儲、debugger 代碼、使用 Console 快速顯示數據等功能。
但是在近幾年興起的微信小程序的前端開發中,卻少有類似的體驗和功能對標的開發調試工具出現。當然微信小程序的官方也提供了類似的工具,那就是 vConsole,但是相比 PC 端提供的工具來説確實無論是功能和體驗都有所欠缺,所以我們開發了 weconsole 來提供更加全面的功能和更好的體驗。
基於上述背景,我們想開發一款運行在微信小程序環境上,無論在用户體驗還是功能等方面都能媲美 PC 端的前端開發調試工具,當然某些(如 debugger 代碼等)受限於技術在當前時期無法實現的功能我們暫且忽略。
我們將這款工具命名為Weimob Console,簡寫為WeConsole。
該項目屬於微盟前端開源項目之一,項目主頁:https://github.com/weimobGrou...
二、安裝與使用
1、通過 npm 安裝
npm i weconsole -S
2、普通方式安裝
可將 npm 包下載到本地,然後將其中的dist/full文件夾拷貝至項目目錄中;
3、引用
WeConsole 分為核心和組件兩部分,使用時需要全部引用後方可使用,核心負責重寫系統變量或方法,以達到全局監控的目的;組件負責將監控的數據顯示出來。
在app.js文件中引用核心:
// NPM方式引用
import 'weconsole/init';
// 普通方式引用
import 'xxx/weconsole/init';
引入weconsole/init後,就是默認將 App、Page、Component、Api、Console 全部重寫監控!如果想按需重寫,可以使用如下方式進行:
import { replace, restore, showWeConsole, hideWeConsole } from 'weconsole'; // scope可選值:App/Page/Component/Console/Api
// 按需替換系統變量或函數以達到監控
replace(scope); // 可還原
restore(scope);
// 通過show/hide方法控制顯示入口圖標
showWeConsole();
如果沒有顯式調用過showWeConsole/hideWeConsole方法,組件第一次初始化時,會根據小程序是否開啓調試模式來決定入口圖標的顯示性。
在需要的地方引用組件,需要先將組件註冊進app/page/component.json中:
// NPM方式引用
"usingComponents": {
"weconsole": "weconsole/components/main/index"
}
// 普通方式引用
"usingComponents": {
"weconsole": "xxx/weconsole/components/main/index"
}
然後在wxml中使用<weconsole>標籤進行初始化:
<!-- page/component.wxml -->
<weconsole />
<weconsole>標籤支持傳入以下屬性:
properties: {
// 組件全屏化後,距離窗口頂部距離
fullTop: String,
// 劉海屏機型(如iphone12等)下組件全屏化後,距離窗口頂部距離
adapFullTop: String,
}
4、建議
如果不想將 weconsole 放置在主包中,建議將組件放在分包內使用,利用小程序的 分包異步化 的特性,減少主包大小
三、功能
1、Console
- 界面如圖 1
- 實時顯示
console.log/info/warn/error記錄; Filter框輸入關鍵字已進行記錄篩選;- 使用分類標籤
All, Mark, Log, Errors, Warnings...等進行記錄分類顯示,分類列表中All, Mark, Log, Errors, Warnings為固定項,其他可由配置項consoleCategoryGetter產生 - 點擊
🚫按鈕清空記錄(不會清除留存的記錄) -
長按記錄可彈出操作項(如圖 2):複製:將記錄數據執行復制操作,具體形式可使用配置項copyPolicy指定,未指定時,將使用JSON.stringify序列化數據,將其複製到剪切板取消置頂/置頂顯示:將記錄取消置頂/置頂顯示,最多可置頂三條(置頂無非是想快速找到重要的數據,當重要的數據過多時,就不宜用置頂了,可以使用標記功能,然後在使用篩選欄中的Mark分類進行篩選顯示)取消留存/留存:留存是指將記錄保留下來,使其不受清除,即點擊🚫按鈕不被清除取消全部留存:取消所有留存的記錄取消標記/標記:標記就是將數據添加一個Mark的分類,可以通過篩選欄快速分類顯示取消全部標記:取消所有標記的記錄
圖 1
圖 2
2、Api
- 界面如圖 3
- 實時顯示
wx對象下的相關 api 執行記錄 Filter框輸入關鍵字已進行記錄篩選- 使用分類標籤
All, Mark, Cloud, xhr...等進行記錄分類顯示,分類列表由配置項apiCategoryList與apiCategoryGetter產生 - 點擊
🚫按鈕清空記錄(不會清除留存的記錄) -
長按記錄可彈出操作項(如圖 4):複製:將記錄數據執行復制操作,具體形式可使用配置項copyPolicy置頂,未指定時,將使用系統默認方式序列化數據(具體看實際效果),將其複製到剪切板- 其他操作項含義與
Console功能類似
- 點擊條目可展示詳情,如圖 5
圖 3
圖 4
圖 5
3、Component
- 界面如圖 6
-
樹結構顯示組件實例列表
- 根是
App - 二級固定為
getCurrentPages返回的頁面實例 - 三級及更深通過
this.selectOwnerComponent()進行父實例定位,進而確定層級
- 根是
- 點擊節點名稱(帶有下劃虛線),可顯示組件實例詳情,以 JSON 樹的方式查看組件的所有數據,如圖 7
圖 6
圖 7
4、Storage
- 界面如圖 8
- 顯示 Storage 記錄
Filter框輸入關鍵字已進行記錄篩選- 點擊
🚫按鈕清空記錄(不會清除留存的記錄) 長按操作項含義與Console功能類似- 點擊條目後,再點擊
❌按鈕可將其刪除 - 點擊
Filter框左側的刷新按鈕可刷新全部數據 - 點擊條目顯示詳情,如圖 9
圖 8
圖 9
5、其他
- 界面如圖 10
- 默認顯示 系統信息
- 可通過
customActions配置項進行界面功能快速定製,也可通過addCustomAction/removeCustomAction添加/刪除定製項目 - 幾個簡單的定製案例如下,效果如圖 11:
import { setUIRunConfig } from 'xxx/weconsole/index.js';
setUIRunConfig({
customActions: [
{
id: 'test1',
title: '顯示文本',
autoCase: 'show',
cases: [
{
id: 'show',
button: '查看',
showMode: WcCustomActionShowMode.text,
handler(): string {
return '測試文本';
}
},
{
id: 'show2',
button: '查看2',
showMode: WcCustomActionShowMode.text,
handler(): string {
return '測試文本2';
}
}
]
},
{
id: 'test2',
title: '顯示JSON',
autoCase: 'show',
cases: [
{
id: 'show',
button: '查看',
showMode: WcCustomActionShowMode.json,
handler() {
return wx;
}
}
]
},
{
id: 'test3',
title: '顯示錶格',
autoCase: 'show',
cases: [
{
id: 'show',
button: '查看',
showMode: WcCustomActionShowMode.grid,
handler(): WcCustomActionGrid {
return {
cols: [
{
title: 'Id',
field: 'id',
width: 30
},
{
title: 'Name',
field: 'name',
width: 70
}
],
data: [
{
id: 1,
name: 'Tom'
},
{
id: 2,
name: 'Alice'
}
]
};
}
}
]
}
]
});
圖 10
圖 10
四、API
通過以下方式使用 API
import { showWeConsole, ... } from 'weconsole';
showWeConsole();
replace(scope:'App'|'Page'|'Component'|'Api'|'Console')
替換系統變量或函數以達到監控,底層控制全局僅替換一次
restore(scope:'App'|'Page'|'Component'|'Api'|'Console')
還原被替換的系統變量或函數,還原後界面將不在顯示相關數據
showWeConsole()
顯示WeConsole入口圖標
hideWeConsole()
隱藏WeConsole入口圖標
setUIConfig(config: Partial<MpUIConfig>)
設置WeConsole組件內的相關配置,可接受的配置項及含義如下:
interface MpUIConfig {
/**監控小程序API數據後,使用該選項進行該數據的分類值計算,計算後的結果顯示在界面上 */
apiCategoryGetter?: MpProductCategoryMap | MpProductCategoryGetter;
/**監控Console數據後,使用該選項進行該數據的分類值計算,計算後的結果顯示在界面上 */
consoleCategoryGetter?: MpProductCategoryMap | MpProductCategoryGetter;
/**API選項卡下顯示的數據分類列表,all、mark、other 分類固定存在 */
apiCategoryList?: Array<string | MpNameValue<string>>;
/**複製策略,傳入複製數據,可通過數據的type字段判斷數據哪種類型,比如api/console */
copyPolicy?: MpProductCopyPolicy;
/**定製化列表 */
customActions?: WcCustomAction[];
}
/**取數據的category字段值對應的prop */
interface MpProductCategoryMap {
[prop: string]: string | MpProductCategoryGetter;
}
interface MpProductCategoryGetter {
(product: Partial<MpProduct>): string | string[];
}
interface MpProductCopyPolicy {
(product: Partial<MpProduct>);
}
/**定製化 */
interface WcCustomAction {
/**標識,需要保持唯一 */
id: string;
/**標題 */
title: string;
/**默認執行哪個case? */
autoCase?: string;
/**該定製化有哪些情況 */
cases: WcCustomActionCase[];
}
const enum WcCustomActionShowMode {
/**顯示JSON樹 */
json = 'json',
/**顯示數據表格 */
grid = 'grid',
/** 固定顯示<weconsole-customer>組件,該組件需要在app.json中註冊,同時需要支持傳入data屬性,屬性值就是case handler執行後的結果 */
component = 'component',
/**顯示一段文本 */
text = 'text',
/**什麼都不做 */
none = 'none'
}
interface WcCustomActionCase {
id: string;
/**按鈕文案 */
button?: string;
/**執行邏輯 */
handler: Function;
/**顯示方式 */
showMode?: WcCustomActionShowMode;
}
interface WcCustomActionGrid {
cols: DataGridCol[];
data: any;
}
addCustomAction(action: WcCustomAction)
添加一個定製化項目;當你添加的項目中需要顯示你自己的組件時:
- 請將 case 的
showMode值設置為component - 在
app.json中註冊名稱為weconsole-customer的組件 - 定製化項目的 case 被執行時,會將執行結果傳遞給
weconsole-customer的data屬性 - 開發者根據
data屬性中的數據自行判斷內部顯示邏輯
removeCustomAction(actionId: string)
根據 ID 刪除一個定製化項目
getWcControlMpViewInstances():any[]
獲取小程序內 weconsole 已經監控到的所有的 App/Page/Component 實例
log(type = "log", ...args)
因為 console 被重寫,當你想使用最原始的 console 方法時,可以通過該方式,type 就是 console 的方法名
on/once/off/emit
提供一個事件總線功能,全局事件及相關函數定義如下:
const enum WeConsoleEvents {
/**UIConfig對象發生變化時 */
WcUIConfigChange = 'WcUIConfigChange',
/**入口圖標顯示性發生變化時 */
WcVisableChange = 'WcVisableChange',
/**CanvasContext準備好時,CanvasContext用於JSON樹組件的界面文字寬度計算 */
WcCanvasContextReady = 'WcCanvasContextReady',
/**CanvasContext銷燬時 */
WcCanvasContextDestory = 'WcCanvasContextDestory',
/**主組件的寬高發生變化時 */
WcMainComponentSizeChange = 'WcMainComponentSizeChange'
}
interface IEventEmitter<T = any> {
on(type: string, handler: EventHandler<T>);
once(type: string, handler: EventHandler<T>);
off(type: string, handler?: EventHandler<T>);
emit(type: string, data?: T);
}
五、後續規劃
- 優化包大小
- 單元測試
- 體驗優化
- 定製化升級
- 基於網絡通信的界面化 weconsole
- 標準化
- 支持 H5
- 支持其他小程序平台(支付寶/百度/字節跳動)
六、License
WeConsole 使用 MIT 協議.
七、聲明
生產環境請謹慎使用。