Skip to content

Commit 6ae085f

Browse files
committed
release: v1.1.0
1 parent 7f32174 commit 6ae085f

File tree

6 files changed

+180
-9
lines changed

6 files changed

+180
-9
lines changed

Diff for: CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## v1.1.0 (4 Sep 2024)
2+
3+
* feat: force dev mode
4+
15
## v1.0.1 (16 Aug 2024)
26

37
* fix: initial theme not correct

Diff for: index.html

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
88
/>
99
<title>Eruda-vue</title>
10-
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
10+
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
1111
</head>
1212
<body>
1313
<div id="app">{{ message }}</div>
@@ -25,6 +25,9 @@
2525
</script>
2626
<script src="node_modules/eruda/eruda.js"></script>
2727
<script>
28+
setTimeout(() => {
29+
console.log(__VUE_DEVTOOLS_GLOBAL_HOOK__)
30+
}, 3000)
2831
eruda.init({ tool: ['console'] })
2932
</script>
3033
<script src="assets/eruda-vue.js"></script>

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "eruda-vue",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"main": "eruda-vue.js",
55
"description": "Eruda plugin for Vue",
66
"files": [

Diff for: src/back.js

+162-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
import { installHook } from '@back/hook'
2-
import { initBackend } from '@back'
1+
import { installHook as _installHook } from '@back/hook'
32
import { Bridge } from '@utils/bridge'
43
import { SharedData } from '@utils/shared-data'
54
import createUrl from 'licia/createUrl'
65
import devtools from 'raw-loader!./devtools.txt'
76

8-
installHook(window)
9-
107
let theme = 'auto'
118
let shareDataLoaded = false
129

10+
export function installHook() {
11+
if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
12+
return
13+
}
14+
_installHook(window)
15+
}
16+
1317
export function initDevtools(iframe) {
1418
const bridge = new Bridge({
1519
listen(fn) {
@@ -31,7 +35,9 @@ export function initDevtools(iframe) {
3135
shareDataLoaded = true
3236
setTheme(theme)
3337
})
34-
initBackend(bridge)
38+
import('@back').then(({ initBackend }) => {
39+
initBackend(bridge)
40+
})
3541

3642
const devtoolsSrc = createUrl(devtools, { type: 'application/javascript' })
3743

@@ -62,3 +68,154 @@ export function setTheme(value) {
6268
SharedData.theme = value
6369
}
6470
}
71+
72+
// Modified from vue-devtools
73+
export function forceEnable() {
74+
if (!window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
75+
return
76+
}
77+
78+
let delay = 1000
79+
let detectRemainingTries = 10
80+
81+
function runDetect() {
82+
// Method 1: Check Nuxt.js
83+
const nuxtDetected = !!(window.__NUXT__ || window.$nuxt)
84+
85+
if (nuxtDetected) {
86+
let Vue
87+
88+
if (window.$nuxt) {
89+
Vue = window.$nuxt.$root && window.$nuxt.$root.constructor
90+
}
91+
92+
crack({
93+
devtoolsEnabled:
94+
(Vue && Vue.config.devtools) ||
95+
(window.__VUE_DEVTOOLS_GLOBAL_HOOK__ &&
96+
window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled),
97+
vueDetected: true,
98+
nuxtDetected: true,
99+
})
100+
101+
return
102+
}
103+
104+
// Method 2: Check Vue 3
105+
const vueDetected = !!window.__VUE__
106+
if (vueDetected) {
107+
crack({
108+
devtoolsEnabled:
109+
window.__VUE_DEVTOOLS_GLOBAL_HOOK__ &&
110+
window.__VUE_DEVTOOLS_GLOBAL_HOOK__.enabled,
111+
vueDetected: true,
112+
})
113+
114+
return
115+
}
116+
117+
// Method 3: Scan all elements inside document
118+
const all = document.querySelectorAll('*')
119+
let el
120+
for (let i = 0; i < all.length; i++) {
121+
if (all[i].__vue__) {
122+
el = all[i]
123+
break
124+
}
125+
}
126+
if (el) {
127+
let Vue = Object.getPrototypeOf(el.__vue__).constructor
128+
while (Vue.super) {
129+
Vue = Vue.super
130+
}
131+
crack({
132+
devtoolsEnabled: Vue.config.devtools,
133+
vueDetected: true,
134+
})
135+
return
136+
}
137+
138+
if (detectRemainingTries > 0) {
139+
detectRemainingTries--
140+
setTimeout(() => {
141+
runDetect()
142+
}, delay)
143+
delay *= 5
144+
}
145+
}
146+
147+
setTimeout(() => {
148+
runDetect()
149+
}, 100)
150+
}
151+
152+
// https://github.com/hzmming/vue-force-dev
153+
function crack(data) {
154+
if (data.devtoolsEnabled) {
155+
return
156+
}
157+
158+
// Nuxt.js
159+
if (data.nuxtDetected) {
160+
let Vue
161+
162+
if (window.$nuxt) {
163+
Vue = window.$nuxt.$root && window.$nuxt.$root.constructor
164+
}
165+
166+
// Vue 2
167+
if (Vue) {
168+
crackVue2(Vue)
169+
} else {
170+
// Vue 3.2.14+
171+
crackVue3()
172+
}
173+
}
174+
// Vue 3
175+
else if (window.__VUE__) {
176+
crackVue3()
177+
}
178+
// Vue 2
179+
else {
180+
crackVue2()
181+
}
182+
}
183+
184+
function crackVue2(Vue) {
185+
if (!Vue) {
186+
const app = getVueRootInstance(2)
187+
if (!app) return false // Vue may not be finished yet
188+
Vue = Object.getPrototypeOf(app).constructor
189+
while (Vue.super) {
190+
Vue = Vue.super
191+
}
192+
}
193+
194+
const devtools = window.__VUE_DEVTOOLS_GLOBAL_HOOK__
195+
Vue.config.devtools = true
196+
devtools.emit('init', Vue)
197+
}
198+
199+
function crackVue3() {
200+
const app = getVueRootInstance(3)
201+
if (!app) return false // Vue may not be finished yet
202+
const devtools = window.__VUE_DEVTOOLS_GLOBAL_HOOK__
203+
devtools.enabled = true
204+
const version = app.version
205+
devtools.emit('app:init' /* APP_INIT */, app, version, {
206+
Fragment: Symbol.for('v-fgt'),
207+
Text: Symbol.for('v-txt'),
208+
Comment: Symbol.for('v-cmt'),
209+
Static: Symbol.for('v-stc'),
210+
})
211+
}
212+
213+
function getVueRootInstance(version) {
214+
const signProperty = version === 2 ? '__vue__' : '__vue_app__'
215+
const all = document.querySelectorAll('*')
216+
for (let i = 0; i < all.length; i++) {
217+
if (all[i][signProperty]) {
218+
return all[i][signProperty]
219+
}
220+
}
221+
}

Diff for: src/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { initDevtools, setTheme } = require('./back')
1+
const { initDevtools, setTheme, installHook, forceEnable } = require('./back')
22

33
module.exports = function (eruda) {
44
let { evalCss } = eruda.util
@@ -14,6 +14,8 @@ module.exports = function (eruda) {
1414
$el.html('<iframe class="eruda-vue-devtools"></iframe>')
1515
const iframe = $el.find('.eruda-vue-devtools').get(0)
1616

17+
installHook()
18+
forceEnable()
1719
initDevtools(iframe)
1820

1921
setTheme(this._getTheme())

Diff for: webpack.config.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,12 @@ module.exports = (env, argv) => {
8989
},
9090
],
9191
},
92-
plugins: [new webpack.BannerPlugin(banner)],
92+
plugins: [
93+
new webpack.optimize.LimitChunkCountPlugin({
94+
maxChunks: 1,
95+
}),
96+
new webpack.BannerPlugin(banner)
97+
],
9398
}
9499

95100
if (argv.mode === 'production') {

0 commit comments

Comments
 (0)