Skip to content

Commit

Permalink
feat(electron): enhance app (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
webfansplz committed Dec 18, 2023
1 parent 5cb92b3 commit e2abaf3
Show file tree
Hide file tree
Showing 15 changed files with 132 additions and 48 deletions.
27 changes: 27 additions & 0 deletions packages/client/src/components/WaitForConnection.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
<script setup lang="ts">
import { VueInput } from '@vue-devtools-next/ui'
import AppConnecting from '~/components/AppConnecting.vue'
const props = defineProps<{
local?: string
network?: string
}>()
function scriptWrapper(str: string) {
return `\<script src="${str}"\>\</script\>`
}
const _local = scriptWrapper(props.local!)
const _network = scriptWrapper(props.network!)
const local = ref(_local)
const network = ref(_network)
</script>

<template>
Expand All @@ -8,6 +24,17 @@ import AppConnecting from '~/components/AppConnecting.vue'
<p class="pt-5 font-bold text-base">
Waiting for connection...
</p>
<div v-if="props.local && props.network" class="mt-5">
<p class="text-center text-sm op80 text-base">
Add one of the following to the top of your page 👇:
</p>
<div class="mt-3 $ui-fcc flex-row">
<VueInput v-model="local" left-icon="i-carbon-copy" class="w-400px!" />
</div>
<div class="mt-3 $ui-fcc flex-row">
<VueInput v-model="network" left-icon="i-carbon-copy" class="w-400px!" />
</div>
</div>
</AppConnecting>
</div>
</template>
Expand Down
6 changes: 5 additions & 1 deletion packages/client/src/composables/state-tab.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useDevToolsBridgeRpc, useDevToolsState } from '@vue-devtools-next/core'
import type { MaybeRef } from 'vue'
import type { CustomTab } from '@vue-devtools-next/kit'
import { isInElectron } from '@vue-devtools-next/shared'

import type { ModuleBuiltinTab } from '~/types/tab'

export interface TabSettings {
Expand Down Expand Up @@ -31,7 +33,9 @@ export function useAllTabs() {
if (currentTab) {
if (currentTab[1].some(t => t.name === tab.name))
return
if (!vitePluginDetected && viteOnlyTabs.includes(tab.name))

// @TODO: electron app support vite only tabs
if ((!vitePluginDetected || isInElectron) && viteOnlyTabs.includes(tab.name))
return

currentTab[1].push({
Expand Down
6 changes: 4 additions & 2 deletions packages/client/src/constants/tab.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DevtoolsBridgeAppRecord } from '@vue-devtools-next/core'
import { deepClone } from '@vue-devtools-next/shared'
import { deepClone, isInElectron } from '@vue-devtools-next/shared'
import type { ModuleBuiltinTab } from '~/types'

// @unocss-include
Expand Down Expand Up @@ -93,7 +93,9 @@ export function getBuiltinTab(viteDetected: boolean, moduleDetectives?: Devtools
if (item[0] === 'modules')
item[1] = item[1].filter(t => moduleDetectives ? isDetected(moduleDetectives, t) : true)
})
return viteDetected

// @TODO: electron app support vite only tabs
return (viteDetected && !isInElectron)
? tab
: tab.map(([_, tabs]) => [_, tabs.filter(t => !viteOnlyTabs.includes(t.name))])
}
2 changes: 2 additions & 0 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { VIEW_MODE_STORAGE_KEY, isBrowser, isInChromePanel, target } from '@vue-

import { initDevTools as _initDevTools } from './main'

export { createConnectionApp } from './main'

export function initDevTools(shell) {
if (!isBrowser)
return
Expand Down
18 changes: 10 additions & 8 deletions packages/client/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import '@unocss/reset/tailwind.css'
import 'floating-vue/dist/style.css'

import type { BridgeInstanceType } from '@vue-devtools-next/core'
import { BROADCAST_CHANNEL_NAME, isInIframe } from '@vue-devtools-next/shared'
import { BROADCAST_CHANNEL_NAME, isInChromePanel, isInElectron, isInIframe } from '@vue-devtools-next/shared'
import { Bridge, BridgeEvents, HandShakeServer, createDevToolsVuePlugin, registerBridgeRpc } from '@vue-devtools-next/core'

import type { App as AppType } from 'vue'
Expand Down Expand Up @@ -105,6 +105,14 @@ export async function initDevTools(shell, options: { viewMode?: 'overlay' | 'pan
})
}

export function createConnectionApp(container: string = '#app', props?: Record<string, string>) {
const app = createApp(WaitForConnection, {
...props,
})
app.mount(container)
return app
}

window.addEventListener('message', (event) => {
if (event.data === '__VUE_DEVTOOLS_CREATE_CLIENT__') {
initDevTools({
Expand Down Expand Up @@ -133,7 +141,7 @@ window.addEventListener('message', (event) => {
})

// @TODO: refactor separate window channel
if (!isInIframe) {
if (!isInIframe && !isInChromePanel && !isInElectron) {
function initSeparateWindowChannel() {
const connectionInfo: {
connected: boolean
Expand All @@ -147,12 +155,6 @@ if (!isInIframe) {

const channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME)

function createConnectionApp() {
const app = createApp(WaitForConnection)
app.mount('#app')
return app
}

function connect() {
connectionInfo.timer = setInterval(() => {
channel.postMessage({
Expand Down
11 changes: 9 additions & 2 deletions packages/electron/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
display: flex;
height: 100%;
}
.loading {
width: 100vw;
height: 100vh;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
}
</style>
<link rel="stylesheet" type="text/css" href="./client/devtools-panel.css" />
<script>
Expand All @@ -20,8 +28,7 @@
<body>
<div id="container">
<div id="app">
<!-- @TODO: connection style and host/port input -->
Waiting for connection...
<p class="loading">Loading DevTools Client...</p>
</div>
</div>
<script src="./dist/devtools.js"></script>
Expand Down
1 change: 1 addition & 0 deletions packages/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"electron": "^28.0.0",
"execa": "^8.0.1",
"h3": "^1.9.0",
"ip": "^1.1.8",
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/electron/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ function createWindow() {
webSecurity: false,
nodeIntegration: true,
contextIsolation: false,
devTools: true,
// @TODO: enabled in dev mode
devTools: false,
},
})
const appEntryPath = path.join(__dirname, '../app.html')
Expand Down
80 changes: 50 additions & 30 deletions packages/electron/src/devtools.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,54 @@
import io from 'socket.io-client'
import { initDevTools } from '../client/devtools-panel'
import io from 'socket.io-client/dist/socket.io.js'
import ip from 'ip'
import { createConnectionApp, initDevTools } from '../client/devtools-panel'
import { Bridge } from '../../core/src/bridge'

const port = window.process.env.PORT || 8098
const socket = io(`http://localhost:${port}`)

let reload: Function | null = null

socket.on('vue-devtools:init', () => {
// If new page is opened reload devtools
if (reload)
return reload()

initDevTools({
connect(cb) {
const bridge = new Bridge({
tracker(fn) {
socket.on('vue-devtools:message', (data) => {
fn(data)
})
},
trigger(data) {
socket.emit('vue-devtools:message', data)
},
})

cb(bridge)
},
reload(fn) {
reload = fn
},

function init() {
const localhost = `http://localhost:${port}`
const socket = io(localhost)
let reload: Function | null = null

const app = createConnectionApp('#app', {
local: localhost,
network: `http://${ip.address()}:${port}`,
})

socket.on('vue-devtools:init', () => {
app.unmount()

// If new page is opened reload devtools
if (reload)
return reload()

initDevTools({
connect(cb) {
const bridge = new Bridge({
tracker(fn) {
socket.on('vue-devtools:message', (data) => {
fn(data)
})
},
trigger(data) {
socket.emit('vue-devtools:message', data)
},
})

cb(bridge)
},
reload(fn) {
reload = fn
},
})
})
})

socket.on('vue-devtools:disconnect', () => {
app.unmount()
reload = null
socket.close()
init()
})
}

init()
7 changes: 6 additions & 1 deletion packages/electron/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export function init() {
'/',
eventHandler(() => {
const userAppContent = fs.readFileSync(path.join(__dirname, './user-app.js'), 'utf-8')
return userAppContent
const processSyntaxPolyfill = `if(!window.process){window.process={env:{}}};`
return processSyntaxPolyfill + userAppContent
}),
)

Expand All @@ -30,6 +31,10 @@ export function init() {
socket.broadcast.emit('vue-devtools:init')
})

socket.on('vue-devtools:disconnect', () => {
socket.broadcast.emit('vue-devtools:disconnect')
})

socket.on('disconnect', (reason) => {
if (reason.indexOf('client'))
socket.broadcast.emit('vue-devtools-disconnect-devtools')
Expand Down
4 changes: 3 additions & 1 deletion packages/electron/src/user-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ socket.on('vue-devtools:disconnect-user-app', () => {
socket.disconnect()
})

// @TODO: disconnect logic
window.addEventListener('beforeunload', () => {
socket.emit('vue-devtools:disconnect')
})
5 changes: 4 additions & 1 deletion packages/playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue DevTools Playground</title>
<!-- <script src="http://localhost:8098"></script> -->
<!-- <script>
window.__VUE_DEVTOOLS_PORT__ = 8080
</script>
<script src="http://localhost:8080"></script> -->
</head>
<body>
<div id="app2"></div>
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Hey from './pages/Hey.vue'
import './style.css'

// connect to remote devtools
// devtools.connect('http://localhost', 8098)
// devtools.connect('http://localhost', 8080)

const pinia = createPinia()
const pinia2 = createPinia()
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export const target = (typeof globalThis !== 'undefined'

export const isInChromePanel = typeof target.chrome !== 'undefined' && !!target.chrome.devtools
export const isInIframe = isBrowser && target.self !== target.top
export const isInElectron = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().includes('electron')
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e2abaf3

Please sign in to comment.