From aa853a890f3025493e14fcf95609729ae13798dc Mon Sep 17 00:00:00 2001 From: fi3ework Date: Fri, 20 Jan 2023 01:46:04 +0800 Subject: [PATCH] fix: use import.meta.hot.on to do client server communication --- packages/runtime/src/ws.js | 43 ++++++-------------- packages/vite-plugin-checker/src/main.ts | 52 ++++-------------------- playground/config-default/vite.config.js | 1 + playground/vitestSetup.ts | 12 ++++-- vitest.config.e2e.ts | 2 +- 5 files changed, 32 insertions(+), 78 deletions(-) diff --git a/packages/runtime/src/ws.js b/packages/runtime/src/ws.js index 18f51efc..010c9809 100644 --- a/packages/runtime/src/ws.js +++ b/packages/runtime/src/ws.js @@ -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' @@ -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) + }) + } + }, } } diff --git a/packages/vite-plugin-checker/src/main.ts b/packages/vite-plugin-checker/src/main.ts index 9fd1f76a..df3d3d5a 100644 --- a/packages/vite-plugin-checker/src/main.ts +++ b/packages/vite-plugin-checker/src/main.ts @@ -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 { @@ -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 @@ -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' }, @@ -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 @@ -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 @@ -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) @@ -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(() => { @@ -266,8 +236,4 @@ function spawnChecker( }) } -function isObject(value: unknown): value is Record { - return Object.prototype.toString.call(value) === '[object Object]' -} - export default checker diff --git a/playground/config-default/vite.config.js b/playground/config-default/vite.config.js index ea83ce6f..ba4750a4 100644 --- a/playground/config-default/vite.config.js +++ b/playground/config-default/vite.config.js @@ -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({ diff --git a/playground/vitestSetup.ts b/playground/vitestSetup.ts index 29446901..320b98c5 100644 --- a/playground/vitestSetup.ts +++ b/playground/vitestSetup.ts @@ -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) diff --git a/vitest.config.e2e.ts b/vitest.config.e2e.ts index 8309d8d6..5bd65115 100644 --- a/vitest.config.e2e.ts +++ b/vitest.config.e2e.ts @@ -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 },