Skip to content

Commit

Permalink
fix: use import.meta.hot.on to do client server communication
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Jan 20, 2023
1 parent 7b54a0c commit aa853a8
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 78 deletions.
43 changes: 13 additions & 30 deletions packages/runtime/src/ws.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
// #region
// copied from https://github.com/vitejs/vite/blob/d76db0cae645beaecd970d95b4819158c5dd568a/packages/vite/src/client/client.ts#LL25
// use server configuration, then fallback to inference
const importMetaUrl = new URL(import.meta.url)

const socketProtocol = __HMR_PROTOCOL__ || (location.protocol === 'https:' ? 'wss' : 'ws')
const hmrPort = __HMR_PORT__
const socketHost = `${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${
hmrPort || importMetaUrl.port
}${__HMR_BASE__}`
const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr')
// #endregion

// #region
// NOTE: sync modification with packages/vite-plugin-checker/client/index.ts
const WS_CHECKER_ERROR_EVENT = 'vite-plugin-checker:error'
Expand All @@ -34,28 +21,24 @@ export function listenToReconnectMessage(cb) {
}

export function prepareListen() {
const onMessage = async ({ data: dataStr }) => {
const data = JSON.parse(dataStr)
switch (data.type) {
case 'update':
const onMessage = async (data) => {
switch (data.event) {
case WS_CHECKER_ERROR_EVENT:
onCustomMessage.forEach((callbackfn) => callbackfn(data.data))
break
case 'full-reload':
case WS_CHECKER_RECONNECT_EVENT:
onReconnectMessage.forEach((callbackfn) => callbackfn(data.data))
break
}

if (data.type === 'custom') {
switch (data.event) {
case WS_CHECKER_ERROR_EVENT:
onCustomMessage.forEach((callbackfn) => callbackfn(data.data))
break
case WS_CHECKER_RECONNECT_EVENT:
onReconnectMessage.forEach((callbackfn) => callbackfn(data.data))
break
}
}
}

return {
start: () => socket.addEventListener('message', onMessage),
start: () => {
if (import.meta.hot) {
import.meta.hot.on('vite-plugin-checker', (data) => {
onMessage(data)
})
}
},
}
}
52 changes: 9 additions & 43 deletions packages/vite-plugin-checker/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import chalk from 'chalk'
import { spawn } from 'child_process'
import pick from 'lodash.pick'
import npmRunPath from 'npm-run-path'
import path from 'path'
import type { ConfigEnv, Plugin, ResolvedConfig } from 'vite'
import { Checker } from './Checker.js'
import {
Expand Down Expand Up @@ -59,6 +58,7 @@ export function checker(userConfig: UserPluginConfig): Plugin {
let checkers: ServeAndBuildChecker[] = []
let isProduction = true
let skipRuntime = false
let devBase = '/'

let viteMode: ConfigEnv['command'] | undefined
let resolvedConfig: ResolvedConfig | undefined
Expand Down Expand Up @@ -87,6 +87,7 @@ export function checker(userConfig: UserPluginConfig): Plugin {
},
configResolved(config) {
resolvedConfig = config
devBase = config.base
isProduction = config.isProduction
skipRuntime ||= isProduction || config.command === 'build'
},
Expand All @@ -107,37 +108,11 @@ export function checker(userConfig: UserPluginConfig): Plugin {
},
load(id) {
if (id === RUNTIME_CLIENT_RUNTIME_PATH) {
if (!resolvedConfig) return

const devBase = resolvedConfig.base

// #region
// copied from https://github.com/vitejs/vite/blob/d76db0cae645beaecd970d95b4819158c5dd568a/packages/vite/src/client/client.ts#LL25
const hmrConfig = isObject(resolvedConfig.server.hmr) ? resolvedConfig.server.hmr : {}
const host = hmrConfig.host || null
const protocol = hmrConfig.protocol || null
// hmr.clientPort -> hmr.port
// -> (24678 if middleware mode) -> new URL(import.meta.url).port
let port = hmrConfig?.clientPort || hmrConfig?.port || null
if (resolvedConfig.server.middlewareMode) {
port ||= 24678
}

let hmrBase = devBase
if (hmrConfig?.path) {
hmrBase = path.posix.join(hmrBase, hmrConfig.path)
}

return runtimeCode
.replace(/__HMR_PROTOCOL__/g, JSON.stringify(protocol))
.replace(/__HMR_HOSTNAME__/g, JSON.stringify(host))
.replace(/__HMR_PORT__/g, JSON.stringify(port))
.replace(/__HMR_BASE__/g, JSON.stringify(hmrBase))
// #endregion
}

if (id === RUNTIME_CLIENT_ENTRY_PATH) {
return composePreambleCode(resolvedConfig!.base, overlayConfig)
return composePreambleCode(devBase, overlayConfig)
}

return
Expand Down Expand Up @@ -179,7 +154,6 @@ export function checker(userConfig: UserPluginConfig): Plugin {
})()
},
configureServer(server) {
let connectedTimes = 0
let latestOverlayErrors: OverlayErrorAction['payload'][] = new Array(checkers.length)
// for dev mode (2/2)
// Get the server instance and keep reference in a closure
Expand All @@ -190,7 +164,7 @@ export function checker(userConfig: UserPluginConfig): Plugin {
if (action.type === ACTION_TYPES.overlayError) {
latestOverlayErrors[index] = action.payload
if (action.payload) {
server.ws.send(action.payload)
server.ws.send('vite-plugin-checker', action.payload)
}
} else if (action.type === ACTION_TYPES.console) {
Checker.log(action)
Expand All @@ -204,15 +178,11 @@ export function checker(userConfig: UserPluginConfig): Plugin {
// may update the overlay before full-reload fired. So we make sure the overlay
// will be displayed again after full-reload.
server.ws.on('connection', () => {
connectedTimes++
// if connectedCount !== 1, means Vite is doing a full-reload, so we don't need to send overlay again
if (connectedTimes > 1) {
server.ws.send({
type: 'custom',
event: WS_CHECKER_RECONNECT_EVENT,
data: latestOverlayErrors.filter(Boolean),
})
}
server.ws.send('vite-plugin-checker', {
type: 'custom',
event: WS_CHECKER_RECONNECT_EVENT,
data: latestOverlayErrors.filter(Boolean),
})
})
} else {
setTimeout(() => {
Expand Down Expand Up @@ -266,8 +236,4 @@ function spawnChecker(
})
}

function isObject(value: unknown): value is Record<string, any> {
return Object.prototype.toString.call(value) === '[object Object]'
}

export default checker
1 change: 1 addition & 0 deletions playground/config-default/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import checker from 'vite-plugin-checker'

// https://vitejs.dev/config/
export default defineConfig({
base: '/my-app/',
// config-edit-slot
plugins: [
checker({
Expand Down
12 changes: 8 additions & 4 deletions playground/vitestSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,16 @@ export async function startDefaultServe(_server?: ViteDevServer, port?: number):
}`

const rawWsSend = server.ws.send
server.ws.send = (_payload) => {
if (_payload.type === 'custom' && _payload.event === 'vite-plugin-checker:error') {
diagnostics = _payload.data.diagnostics
server.ws.send = (...args) => {
const type = args?.[0]
const payload = args?.[1]

if (type === 'vite-plugin-checker' && payload.event === 'vite-plugin-checker:error') {
diagnostics = payload.data.diagnostics
}

return rawWsSend(_payload)
// @ts-ignore
return rawWsSend(...args)
}

await page.goto(viteTestUrl)
Expand Down
2 changes: 1 addition & 1 deletion vitest.config.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineConfig({
hookTimeout: timeout,
globals: true,
reporters: 'dot',
outputTruncateLength: 999999999,
outputTruncateLength: Infinity,
onConsoleLog(log) {
if (log.match(/experimental|jit engine|emitted file|tailwind/i)) return false
},
Expand Down

0 comments on commit aa853a8

Please sign in to comment.