vite-uni-dev-tool
Version:
vite-uni-dev-tool, debug, uni-app, 一处编写,到处调试
695 lines (694 loc) • 21.5 kB
JavaScript
import { console as p, backup as w } from "../core.js";
import { DEV_APP_MESSAGE as M, DEV_WINDOW_VISIBLE as _, DEV_BUTTON_VISIBLE as f, DEV_OPTION_SEND as R, DEV_WINDOW_MESSAGE as I, DEV_CONSOLE_CLEAR as O, DEV_NETWORK_CLEAR as A, DEV_WEBSOCKET_CLEAR as N, DEV_WEBSOCKET_CLEAR_MESSAGE as U, DEV_UPLOAD_CLEAR as b, DEV_STORAGE_CLEAR as V, DEV_STORAGE_REFRESH as x, DEV_STORAGE_REMOVE as k, DEV_STORAGE_ADD as P, DEV_STORAGE_UPDATE as B, DEV_BUTTON_SHOW_OR_HIDE as W, DEV_RESTART_DEBUGGER as G, DEV_RESTART_APP as F, DEV_EXPORT_LOG as H, DEV_VUEX_CHANGE as j, DEV_PINIA_CHANGE as J, DEV_LOG_CACHE_CLEAR as z, DEV_DESTROY as q, DEV_WINDOW_OPEN as K, DEV_WINDOW_CLOSE as X, DEV_ROUTE_REFRESH as $, DEV_OPTION_GET as Y, DEV_EL_EVENT_CLEAR as Q, DEV_UNI_EVENT_CLEAR as Z, DEV_RUN_JS as tt, DEV_CAPTURE_SCREEN_CLEAR as et, DEV_INTERCEPT_NETWORK_UPDATE as st, DEV_INTERCEPT_NETWORK_REMOVE as ot, DEV_CHANGE_CACHE_INTERCEPT_CONFIG as it, DEV_BOTTOM_TAB_CHANGE as rt, DEV_SCAN_CODE_CLEAR as nt, DEV_NFC_CLEAR as at, DEV_CAPTURE_TAP_EVENT as m, DEV_CAPTURE_TOUCH_START as L, DEV_CAPTURE_TOUCH_MOVE as S, DEV_CAPTURE_TOUCH_END as C } from "../const.js";
import "../utils/index.js";
import { transformValueToView as ht, transformValueToShortString as lt } from "../utils/language.js";
import { throttle as d } from "../utils/function.js";
import { calculateObjectSize as pt, formatStorageSize as ct, parseValue as ut } from "../utils/object.js";
import { saveTextFileMicro as Et, saveTextFileH5 as vt, saveTxtFileApp as dt } from "../utils/file.js";
import { getCurrentDate as y } from "../utils/date.js";
import { getCurrentPagePath as c } from "../utils/page.js";
class wt {
constructor({ store: t, eventBus: e }) {
this.abnormalUploadCount = 0, this.abnormalUploadTimer = null, this.isAbnormalUploadActive = !1, this.postMessage = d(this.postMessageFn, 1e3), this.throttleAddElEvent = d(this.addElEvent, 1e3), this.throttleTouchStartEvent = d(this.touchStartEvent, 1e3), this.throttleTouchMoveEvent = d(this.touchMoveEvent, 1e3), this.throttleTouchEndEvent = d(this.touchEndEvent, 1e3), this.store = t, this.eventBus = e, this.acceptMessage();
}
setIntercept(t) {
this.intercept = t;
}
/**
* 发送数据
*
* @param {DevTool.WindowData} data
* @memberof DevEvent
*/
async postMessageFn() {
var i;
if (this.getDevToolDestroy())
return;
const t = await this.store.getDevData(), e = pt(t), s = ct(e);
t.size = e, t.sizeFormat = s, this.eventBus.emit(M, t), e > this.store.cacheMaxSize && ((i = this.store) == null || i.clearDevCache());
}
/**
* 创建调试器
*
* @return {*}
* @memberof DevEvent
*/
createDevTool(t) {
var s;
if (!this.getDevToolDestroy()) {
p.warn("[DevTool] 调试器已创建,不再创建");
return;
}
const e = this.store.getDevToolOptions();
(s = this.intercept) == null || s.init({
enableCaptureScreen: e == null ? void 0 : e.enableCaptureScreen,
enableInterceptPromiseReject: e == null ? void 0 : e.enableInterceptPromiseReject
}), this.addEventListener(), this.store.setDevToolDestroy(!1), this.updateRouteList(), this.showDevToolButton(), this.postMessage(), setTimeout(() => {
p.warn(
`[DevTool] 创建成功
当前版本:${t == null ? void 0 : t.devToolVersion}
构建时间:${t == null ? void 0 : t.devToolBuildTime}
一处编写,到处调试 😂
有问题前往反馈:https://gitee.com/cloud_l/vite-uni-dev-tool`
);
}, 500);
}
/**
* 销毁调试器
*
* @return {*}
* @memberof DevEvent
*/
destroyDevTool() {
var t;
if (this.getDevToolDestroy()) {
p.warn("[DevTool] 调试器已经销毁了,不再重新销毁");
return;
}
this.hideDevToolButton(), this.closeDevToolWindow(), this.removeEventListener(), this.store.setRequestIndex(-1), this.store.setUploadIndex(-1), this.store.setDevToolDestroy(!0), this.store.clearAll(), (t = this.intercept) == null || t.reset(), this.stopAbnormalUpload(), p.warn("[DevTool] 调试器已销毁");
}
/**
* 重启调试器
*
* @memberof DevEvent
*/
restartDevTool() {
this.destroyDevTool(), this.createDevTool({
devToolBuildTime: this.store.devToolBuildTime,
devToolVersion: this.store.devToolVersion
}), this.openDevToolWindow(), this.restartAbnormalUpload();
}
/**
* 打开调试器窗口
*
* @memberof DevEvent
*/
openDevToolWindow() {
if (this.getDevToolDestroy()) {
p.warn("[DevTool] 调试器已销毁");
return;
}
setTimeout(async () => {
this.postMessage();
}, 100), this.eventBus.emit(_, !0);
}
/**
* 关闭调试器窗口
*
* @memberof DevEvent
*/
closeDevToolWindow() {
if (this.getDevToolDestroy()) {
p.warn("[DevTool] 调试器已销毁");
return;
}
this.eventBus.emit(_, !1);
}
/**
* 显示调试按钮
*
* @export
*/
showDevToolButton() {
this.getDevToolDestroy() || (this.eventBus.emit(f, !0), this.store.setDevToolVisible(!0));
}
/**
* 隐藏调试按钮
*
* @return {*}
*/
hideDevToolButton() {
this.getDevToolDestroy() || (this.eventBus.emit(f, !1), this.store.setDevToolVisible(!1));
}
exportLog(t) {
const e = this.store.getExportData(t);
switch (uni.__dev_tool_platform__) {
case "app":
dt(JSON.stringify(e, null, 2), "dev-tool-log");
break;
case "web":
vt(JSON.stringify(e, null, 2), "dev-tool-log");
break;
case "mp-weixin":
case "mp-alipay":
case "mp-toutiao":
Et(JSON.stringify(e, null, 2), "dev-tool-log");
break;
}
}
/**
* 重启app
*
* @memberof DevEvent
*/
restartApp() {
var t;
switch (uni.__dev_tool_platform__) {
case "app":
plus.runtime.restart();
break;
case "web":
window.location.reload();
break;
case "mp-weixin":
if (wx != null && wx.restartMiniProgram) {
const e = "/" + this.store.getCurrentPagePath();
(t = wx.restartMiniProgram) == null || t.call(wx, {
path: e
});
}
break;
}
}
refreshRouteList() {
this.store.getRouteList(), this.postMessage();
}
sendDevToolOption() {
const t = this.store.getDevToolOptions();
this.eventBus.emit(R, t);
}
/**
* 接受消息
*
* @memberof DevEvent
*/
acceptMessage() {
this.eventBus.on(
I,
(t) => {
t.type === O ? this.store.clearConsoleList() : t.type === A ? (this.store.clearNetworkList(), this.postMessage()) : t.type === N ? (this.store.clearWsList(), this.postMessage()) : t.type === U ? (p.log("data: ", t), this.store.clearWsMessage(t.data.url), this.postMessage()) : t.type === b ? (this.store.clearUploadList(), this.postMessage()) : t.type === V ? (this.store.clearStorageList(!0), this.postMessage()) : t.type === x ? (this.store.refreshStore(), this.postMessage()) : t.type === k ? (this.store.removeStorage(t.data.key + "", !0), this.postMessage()) : t.type === P ? (this.store.addStorage(t.data, !0), this.postMessage()) : t.type === B ? (this.store.updateStore(t.data), this.postMessage()) : t.type === W ? (t.data.show ? this.showDevToolButton() : this.hideDevToolButton(), this.postMessage()) : t.type === G ? this.restartDevTool() : t.type === F ? this.restartApp() : t.type === H ? this.exportLog(t.data) : t.type === j ? (this.store.updateVuexStore(t.data), this.postMessage()) : t.type === J ? (this.store.updatePiniaStore(t.data), this.postMessage()) : t.type === z ? this.store.clearDevCache() : t.type === q ? this.destroyDevTool() : t.type === K ? this.openDevToolWindow() : t.type === X ? this.closeDevToolWindow() : t.type === $ ? this.refreshRouteList() : t.type === Y ? this.sendDevToolOption() : t.type === Q ? this.clearElEventList() : t.type === Z ? this.clearUniEvent() : t.type === tt ? this.devRunJS(t.data.code) : t.type === et ? this.store.clearCaptureScreenList() : t.type === st ? this.updateInterceptNetworkList(t.data) : t.type === ot ? this.removeInterceptNetwork(t.data) : t.type === it ? this.changeCacheInterceptConfig(t.data) : t.type === rt ? (this.closeDevToolWindow(), this.updateRouteList(t.data.path)) : t.type === nt ? this.store.clearScanCodeList() : t.type === at && this.store.clearNfcList();
}
);
}
/**
* 更新路由信息
*
* @param {string} path
* @memberof DevEvent
*/
updateRouteList(t) {
this.store.updateRouteList(t), this.postMessage();
}
/**
* 清除console日志
*
* @memberof DevEvent
*/
clearConsoleList() {
this.store.clearConsoleList(), this.postMessage();
}
/**
* 更新控制台日志
*
* @param {DevTool.ConsoleItem[]} addItems
* @param {number} [index]
* @memberof DevEvent
*/
updateConsoleList(t, e) {
this.store.updateConsoleList(t, e), this.postMessage();
}
/**
* 更新网络日志
*
* @param {DevTool.NetworkItem[]} addItems
* @param {number} [index]
* @memberof DevEvent
*/
updateNetworkList(t, e) {
this.store.updateNetworkList(t, e), this.postMessage();
}
/**
* 更新websocket日志
*
* @param {DevTool.WS} item
* @memberof DevEvent
*/
updateWsList(t) {
this.store.updateWsList(t), this.postMessage();
}
/**
* 重置websocket
*
* @memberof DevEvent
*/
resetWebSocket() {
uni.connectSocket = w.connectSocket;
}
/**
* 更新状态存储
*
* @param {DevTool.StorageItem[]} addItems
* @memberof DevEvent
*/
updateStoreList(t) {
this.store.updateStoreList(t), this.postMessage();
}
/**
* 移除状态
*
* @param {string} key
* @memberof DevEvent
*/
removeStorage(t, e) {
this.store.removeStorage(t, e), this.postMessage();
}
/**
* 清除缓存
*
* @memberof DevEvent
*/
clearStorage(t) {
this.store.clearStorageList(t), this.postMessage();
}
/**
* 更新上传日志
*
* @param {DevTool.UploadItem[]} addItems
* @param {number} [index]
* @memberof DevEvent
*/
updateUploadList(t, e) {
this.store.updateUploadList(t, e), this.postMessage();
}
/**
* 移除上传任务
*
* @param {(number | string)} index
* @memberof DevEvent
*/
removeUploadTask(t) {
this.store.removeUploadTask(t), this.postMessage();
}
/**
* 新增上传任务
*
* @param {(number | string)} index
* @param {UniApp.UploadTask} task
* @memberof DevEvent
*/
addUploadTask(t, e) {
this.store.addUploadTask(t, e), this.postMessage();
}
setRequestIndex(t) {
return this.store.setRequestIndex(t);
}
getRequestIndex() {
return this.store.getRequestIndex();
}
setUploadIndex(t) {
return this.store.setUploadIndex(t);
}
getUploadIndex() {
return this.store.getUploadIndex();
}
setScreenIndex(t) {
return this.store.setScreenIndex(t);
}
getScreenIndex() {
return this.store.getScreenIndex();
}
setVuexList(t) {
this.store.setVuexList(t);
}
setPiniaList(t) {
this.store.setPiniaList(t);
}
setPiniaStore(t) {
this.store.setPiniaStore(t);
}
getDevToolDestroy() {
return this.store.getDevToolDestroy();
}
updateUniEventCount(t) {
this.store.updateUniEventCount(t), this.postMessage();
}
updateUniEventList(t) {
this.store.updateUniEventList(t), this.postMessage();
}
clearUniEvent() {
this.store.clearUniEvent(), this.postMessage();
}
execute(t) {
const e = "_e_v_a_l_".replace(
/_/g,
""
), s = "_e_v_a_l_F_n_".replace(
/_/g,
""
);
if (globalThis != null && globalThis[s])
return Promise.resolve(globalThis == null ? void 0 : globalThis[s](t));
if (globalThis != null && globalThis[e])
return Promise.resolve(globalThis == null ? void 0 : globalThis[e](t));
throw new Error("[DevTool] DevRunJS 当前环境不支持执行js");
}
/**
* 运行js
*
* @param {string} code
* @memberof DevEvent
*/
devRunJS(t) {
var n, h;
const e = (h = (n = new Error()) == null ? void 0 : n.stack) == null ? void 0 : h.split(`
`), s = e == null ? void 0 : e[1], i = Date.now(), o = {
type: "log",
args: [
{
type: "string",
value: t
}
],
position: c(),
time: y(),
stack: s,
mode: "input"
};
this.updateConsoleList([{ ...o }]), this.execute(t).then((a) => {
const l = ht(a), u = ut(a), D = l === "object" || l === "array" ? lt(u, l) : "";
o.args = [
{
type: l,
value: u,
shortValue: D
}
], o.time = y(), o.mode = "output", o.executionTime = Date.now() - i, this.updateConsoleList([{ ...o }]);
});
}
/**
* 更新截屏列表
*
* @param {DevTool.ScreenItem[]} list
* @memberof DevEvent
*/
updateScreenList(t, e) {
this.store.updateScreenList(t, e), this.postMessage();
}
/**
* 清空截屏列表
*
* @memberof DevEvent
*/
clearCaptureScreenList() {
this.store.clearCaptureScreenList();
}
/**
* 更新拦截的网络请求列表
*
* @param {DevTool.NetworkItem[]} list
* @memberof DevEvent
*/
updateInterceptNetworkList(t) {
this.store.updateInterceptNetworkList(t), this.postMessage();
}
/**
* 清空拦截的网络请求列表
*
* @memberof DevEvent
*/
clearInterceptNetworkList() {
this.store.clearInterceptNetworkList(), this.postMessage();
}
/**
* 移除拦截的网络请求
*
* @param {DevTool.NetworkItem} item
* @memberof DevEvent
*/
removeInterceptNetwork(t) {
this.store.removeInterceptNetwork(t), this.postMessage();
}
/**
* 缓存网络请求到本地
*
* @param {{
* cacheInterceptConfig: boolean;
* }} {
* cacheInterceptConfig,
* }
* @memberof DevEvent
*/
changeCacheInterceptConfig({
cacheInterceptConfig: t
}) {
this.store.changeCacheInterceptConfig(t);
}
getInterceptNetworkMap() {
return this.store.getInterceptNetworkMap();
}
updateScanCodeList(t) {
this.store.updateScanCodeList(t), this.postMessage();
}
/**
* 外界扫描传入的code
* @param code
*/
devToolScanCode(t, e) {
var h, a;
if (this.getDevToolDestroy())
return;
let s = {};
try {
s = JSON.parse(t);
} catch {
}
const i = (a = (h = new Error()) == null ? void 0 : h.stack) == null ? void 0 : a.split(`
`), o = i == null ? void 0 : i[2], n = {
timer: Date.now(),
charSet: "utf-8",
rawData: t,
result: t,
scanType: e,
errMsg: "ok",
resultObject: s,
path: c(),
stack: o
};
this.updateScanCodeList([n]);
}
updateNfcList(t) {
this.store.updateNfcList(t), this.postMessage();
}
/** 外界 nfc 读取传入 */
devToolNFC(t) {
var o, n;
const e = (n = (o = new Error()) == null ? void 0 : o.stack) == null ? void 0 : n.split(`
`), s = e == null ? void 0 : e[1], i = {
...t,
stack: s,
timer: Date.now(),
path: c()
};
this.updateNfcList([i]);
}
addElEvent(t) {
this.store.addElEvent(t), this.postMessage();
}
clearElEventList() {
this.store.clearElEventList(), this.postMessage();
}
hasCaptureEvent(t) {
const {
includeCaptureElDataSet: e = [],
excludeCaptureElDataSet: s = []
} = this.store.getDevToolOptions() ?? {
includeCaptureElDataSet: [],
excludeCaptureElDataSet: []
};
return e.length ? e.some((i) => {
var o;
return Object.keys(((o = t == null ? void 0 : t.target) == null ? void 0 : o.dataset) ?? {}).includes(i);
}) : s.length ? !s.some((i) => {
var o;
return Object.keys(((o = t == null ? void 0 : t.target) == null ? void 0 : o.dataset) ?? {}).includes(i);
}) : !0;
}
tapEvent(t) {
if (!this.hasCaptureEvent(t))
return;
const e = {
type: t.type,
timer: Date.now(),
target: t.target,
touches: t.touches,
path: c()
};
this.addElEvent(e);
}
touchStartEvent(t) {
if (!this.hasCaptureEvent(t))
return;
const e = {
type: t.type,
timer: Date.now(),
target: t.target,
touches: t.touches,
path: c()
};
this.addElEvent(e);
}
touchMoveEvent(t) {
if (!this.hasCaptureEvent(t))
return;
const e = {
type: t.type,
timer: Date.now(),
target: t.target,
touches: t.touches,
path: c()
};
this.addElEvent(e);
}
touchEndEvent(t) {
if (!this.hasCaptureEvent(t))
return;
const e = {
type: t.type,
timer: Date.now(),
target: t.target,
touches: t.touches,
path: c()
};
this.addElEvent(e);
}
/**
* 添加事件监听
*/
addEventListener() {
const t = this.store.getCaptureList();
t.includes("tap") && this.eventBus.on(m, this.tapEvent.bind(this)), t.includes("touchstart") && this.eventBus.on(
L,
this.throttleTouchStartEvent.bind(this)
), t.includes("touchmove") && this.eventBus.on(
S,
this.throttleTouchMoveEvent.bind(this)
), t.includes("touchend") && this.eventBus.on(
C,
this.throttleTouchEndEvent.bind(this)
);
}
/**
* 移除事件监听
*/
removeEventListener() {
const t = this.store.getCaptureList();
t.includes("tap") && this.eventBus.off(m, this.tapEvent), t.includes("touchstart") && this.eventBus.off(L, this.throttleTouchStartEvent), t.includes("touchmove") && this.eventBus.off(S, this.throttleTouchMoveEvent), t.includes("touchend") && this.eventBus.off(C, this.throttleTouchEndEvent);
}
async getAbnormalData() {
var a, l, u, T, D, g;
const t = await this.store.getDevData(), e = ((a = t.consoleList) == null ? void 0 : a.filter(
(r) => ["error", "warn"].includes(r.type) && !r.hasUpload
)) ?? [], s = ((l = t.networkList) == null ? void 0 : l.filter(
(r) => {
var E, v;
return r.sponsor === "user" && !((v = (E = r.status) == null ? void 0 : E.toString()) != null && v.startsWith("2")) && !r.hasUpload;
}
)) ?? [], i = ((u = t.uploadList) == null ? void 0 : u.filter(
(r) => {
var E, v;
return !((v = (E = r.status) == null ? void 0 : E.toString()) != null && v.startsWith("2")) && !r.hasUpload;
}
)) ?? [], o = ((T = t.elEventList) == null ? void 0 : T.filter((r) => !r.hasUpload)) ?? [], n = ((D = t.uniEventList) == null ? void 0 : D.filter((r) => !r.hasUpload)) ?? [], h = ((g = t.screenList) == null ? void 0 : g.filter((r) => !r.hasUpload)) ?? [];
return {
consoleList: e,
networkList: s,
uploadList: i,
elEventList: o,
uniEventList: n,
screenList: h,
systemInfo: t.systemInfo,
deviceInfo: t.deviceInfo
};
}
async performAbnormalUpload(t) {
const {
consoleList: e,
networkList: s,
uploadList: i,
systemInfo: o,
elEventList: n,
uniEventList: h,
screenList: a,
deviceInfo: l
} = await this.getAbnormalData();
(e.length || s.length || i.length || n.length || h.length || a.length) && uni.request({
method: "POST",
url: t == null ? void 0 : t.url,
header: {
...(t == null ? void 0 : t.header) ?? {},
"dev-tool-sponsor": Date.now()
},
timeout: (t == null ? void 0 : t.timerOut) ?? 3 * 1e3,
data: {
...(t == null ? void 0 : t.payload) ?? {},
consoleList: e,
networkList: s,
uploadList: i,
elEventList: n,
uniEventList: h,
screenList: a,
deviceInfo: l,
systemInfo: o,
platform: uni.__dev_tool_platform__
},
success: () => {
this.store.updateHasUpload(), this.uploadAbnormal(), this.abnormalUploadCount = 0;
},
fail: () => {
this.uploadAbnormal(), this.abnormalUploadCount++;
}
});
}
/**
* 上报异常
*
* @memberof DevEvent
*/
uploadAbnormal(t) {
if (!this.isAbnormalUploadActive)
return;
const { uploadAbnormalUV: e } = this.store.getDevToolOptions() ?? {
uploadAbnormalUV: {
url: "",
header: {
"dev-tool-sponsor": Date.now()
},
payload: {},
duration: 10 * 1e3,
timerOut: 3 * 1e3
}
};
if (!(e != null && e.url)) {
p.log("[DevTool] 未配置异常上报地址,将不上报异常信息");
return;
}
const s = e.duration ?? 10 * 1e3, i = 5 * 60 * 1e3, o = Math.min(
s * Math.pow(2, this.abnormalUploadCount),
i
), n = Math.max(o, s);
this.abnormalUploadTimer && clearTimeout(this.abnormalUploadTimer), t != null && t.immediately && this.performAbnormalUpload(e), this.abnormalUploadTimer = setTimeout(() => {
this.performAbnormalUpload(e);
}, n);
}
/**
* 启动异常上报
*/
startAbnormalUpload(t) {
this.isAbnormalUploadActive = !0, this.abnormalUploadCount = 0, this.uploadAbnormal(t);
}
/**
* 停止异常上报
*/
stopAbnormalUpload() {
this.isAbnormalUploadActive = !1, this.abnormalUploadTimer && (clearTimeout(this.abnormalUploadTimer), this.abnormalUploadTimer = null);
}
/**
* 重启异常上报
*/
restartAbnormalUpload() {
this.stopAbnormalUpload(), this.startAbnormalUpload();
}
}
export {
wt as DevEvent
};