H5线上开启vconsole调试
1kb (gzip) 代码搞定开发调试发布,错误监控上报,用户问题定位。
- 支持错误监控和上报
- 支持 vConsole (opens new window) 错误展示
- 支持开发阶段使用 vConsole (opens new window)
- 支持生产环境机关拉取 vConsole (opens new window)
- 支持预埋机关唤起
- 支持url带参数唤起
# 1. 安装
# 1.1 npm
npm install alloylever
1
# 1.2 yarn
yarn add alloylever
1
# 1.3 CDN地址下载下来使用
https://unpkg.com/alloylever (opens new window)
# 2. 使用指南
import AlloyLever from 'alloylever'
AlloyLever.config({
cdn:'//s.url.cn/qqun/qun/qqweb/m/qun/confession/js/vconsole.min.js', // vconsole的CDN地址
reportUrl: null, // 错误上报地址
reportPrefix: 'qun', // 错误上报msg前缀,一般用于标识业务类型
reportKey: 'msg', // 错误上报msg前缀的key,用户上报系统接收存储msg
otherReport: { // 需要上报的其他信息
uin: 491862102,
},
entry: "#app", // 请点击这个DOM元素6次召唤vConsole。
// 你可以通过AlloyLever.entry('#entry2')设置多个机关入口召唤神龙
})
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
AlloyLever会监听window.onerror
并把错误信息保存下来,并且上报到reportUrl,你也可以召唤到vConsole并显示出来错误和相关日志。 或者使用这个CDN也可以: //pub.idqqimg.com/qqun/qun/qqweb/m/qun/confession/js/vconsole.min.js
# 2.1 入口DOM元素点击6次唤起vConsole
# 2.2 url唤起vConsole
只要你的页面引用了AlloyLever,你只需要在你的url里带上 vconsole=show
就能显示vConsole面板。如:
// 加载并显示log面板
http://localhost:63342/AlloyLever/index.html?vconsole=show
// 加载但不显示log面板
http://localhost:63342/AlloyLever/index.html?vconsole=hide
// 不加载vConsole脚本
http://localhost:63342/AlloyLever/index.html
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
这些url的作用很好理解:
- 开发阶段用于调试
- 发给投诉的用户打开带有vconsole=show的url
# 3. 在线演示
- https://alloyteam.github.io/AlloyLever/ (opens new window)
- https://alloyteam.github.io/AlloyLever/?vconsole=show (opens new window)
- https://alloyteam.github.io/AlloyLever/?vconsole=hide (opens new window)
![](http://cdn.1024vip.cn/tech/images/202105/59f1d75476ef069fa08e76e989b4caa1.jpg)
# 4. 源码
点击查看 alloy-lever.js 源码
;(function (root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory()
else if(typeof define === 'function' && define.amd)
define([], factory)
else if(typeof exports === 'object')
exports["AlloyLever"] = factory()
else
root["AlloyLever"] = factory()
})(this, function() {
var AlloyLever = {}
AlloyLever.settings = {
cdn:'//s.url.cn/qqun/qun/qqweb/m/qun/confession/js/vconsole.min.js',
reportUrl: null,
reportPrefix: '',
reportKey: 'msg',
otherReport: null,
entry: null
}
AlloyLever.store = []
var methodList = ['log', 'info', 'warn', 'debug', 'error'];
methodList.forEach(function(item) {
var method = console[item];
console[item] = function() {
AlloyLever.store.push({
logType: item,
logs: arguments
});
method.apply(console, arguments);
}
});
AlloyLever.logs = []
AlloyLever.config = function(config){
for(var i in config){
if(config.hasOwnProperty(i)){
AlloyLever.settings[i] = config[i]
}
}
if(config.entry){
window.addEventListener('load', function() {
AlloyLever.entry(config.entry)
})
}
var parameter = getParameter('vconsole')
if(parameter) {
if (parameter === 'show') {
AlloyLever.vConsole(true)
} else {
AlloyLever.vConsole(false)
}
}
}
AlloyLever.vConsole = function(show){
loadScript(AlloyLever.settings.cdn, function() {
//support vconsole3.0
if (typeof vConsole === 'undefined') {
window.vConsole = new VConsole({
defaultPlugins: ['system', 'network', 'element', 'storage'],
maxLogNumber: 5000
})
}
var i = 0,
len = AlloyLever.store.length
for (; i < len; i++) {
var item = AlloyLever.store[i]
//console[item.type].apply(console, item.logs)
//prevent twice log
item.noOrigin = true
window.vConsole.pluginList.default.printLog(item)
}
if(show) {
try {
window.vConsole.show()
} catch (e) {
}
window.addEventListener('load', function () {
window.vConsole.show()
})
}
})
}
var parameter = getParameter('vconsole')
if (parameter) {
if (parameter === 'show') {
AlloyLever.vConsole(true)
} else {
AlloyLever.vConsole(false)
}
}
AlloyLever.entry = function(selector) {
var count = 0,
entry = document.querySelector(selector)
if(entry) {
entry.addEventListener('click', function () {
count++
if (count > 5) {
count = -10000
AlloyLever.vConsole(true)
}
})
}
}
window.onerror = function(msg, url, line, col, error) {
var newMsg = msg
if (error && error.stack) {
newMsg = processStackMsg(error)
}
if (isOBJByType(newMsg, "Event")) {
newMsg += newMsg.type ?
("--" + newMsg.type + "--" + (newMsg.target ?
(newMsg.target.tagName + "::" + newMsg.target.src) : "")) : ""
}
newMsg = (newMsg + "" || "").substr(0,500)
AlloyLever.logs.push({
msg: newMsg,
target: url,
rowNum: line,
colNum: col
})
if (msg.toLowerCase().indexOf('script error') > -1) {
console.error('Script Error: See Browser Console for Detail')
} else {
console.error(newMsg)
}
var ss = AlloyLever.settings
if(ss.reportUrl) {
var src = ss.reportUrl + (ss.reportUrl.indexOf('?')>-1?'&':'?') + ss.reportKey + '='+( ss.reportPrefix?('[' + ss.reportPrefix +']'):'')+ newMsg+'&t='+new Date().getTime()
if(ss.otherReport) {
for (var i in ss.otherReport) {
if (ss.otherReport.hasOwnProperty(i)) {
src += '&' + i + '=' + ss.otherReport[i]
}
}
}
new Image().src = src
}
}
function loadScript(src, callback){
var s,
r,
t
r = false
s = document.createElement('script')
s.type = 'text/javascript'
s.src = src
s.onload = s.onreadystatechange = function() {
//console.log( this.readyState ); //uncomment this line to see which ready states are called.
if ( !r && (!this.readyState || this.readyState == 'complete') )
{
r = true
callback()
}
}
t = document.getElementsByTagName('script')[0]
t.parentNode.insertBefore(s, t)
}
function getParameter(n) {
var m = window.location.hash.match(new RegExp('(?:#|&)' + n + '=([^&]*)(&|$)')),
result = !m ? '' : decodeURIComponent(m[1])
return result ||getParameterByName(n)
}
function getParameterByName(name, url) {
if (!url) url = window.location.href
name = name.replace(/[\[\]]/g, "\\$&")
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url)
if (!results) return null
if (!results[2]) return ''
return decodeURIComponent(results[2].replace(/\+/g, " "))
}
function isOBJByType(o, type) {
return Object.prototype.toString.call(o) === "[object " + (type || "Object") + "]"
}
function processStackMsg (error) {
var stack = error.stack
.replace(/\n/gi, "")
.split(/\bat\b/)
.slice(0, 9)
.join("@")
.replace(/\?[^:]+/gi, "")
var msg = error.toString()
if (stack.indexOf(msg) < 0) {
stack = msg + "@" + stack
}
return stack
}
function getCookie(name){
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)")
if(arr=document.cookie.match(reg))
return unescape(arr[2])
else
return null
}
AlloyLever.getCookie = getCookie
AlloyLever.getParameter= getParameter
AlloyLever.loadScript = loadScript
return AlloyLever
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
上次更新: 2023-06-21 10:49:53