|
1 | 1 | import path from 'node:path'
|
| 2 | +import fs from 'node:fs' |
2 | 3 | import type { Plugin } from '../plugin'
|
3 | 4 | import type { ResolvedConfig } from '../config'
|
4 | 5 | import { CLIENT_ENTRY, ENV_ENTRY } from '../constants'
|
@@ -121,3 +122,65 @@ function escapeReplacement(value: string | number | boolean | null) {
|
121 | 122 | const jsonValue = JSON.stringify(value)
|
122 | 123 | return () => jsonValue
|
123 | 124 | }
|
| 125 | + |
| 126 | +export async function getHmrImplement(config: ResolvedConfig): Promise<string> { |
| 127 | + const content = fs.readFileSync(normalizedClientEntry, 'utf-8') |
| 128 | + const resolvedServerHostname = (await resolveHostname(config.server.host)) |
| 129 | + .name |
| 130 | + const resolvedServerPort = config.server.port! |
| 131 | + const devBase = config.base |
| 132 | + |
| 133 | + const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}` |
| 134 | + |
| 135 | + let hmrConfig = config.server.hmr |
| 136 | + hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined |
| 137 | + const host = hmrConfig?.host || null |
| 138 | + const protocol = hmrConfig?.protocol || null |
| 139 | + const timeout = hmrConfig?.timeout || 30000 |
| 140 | + const overlay = hmrConfig?.overlay !== false |
| 141 | + const isHmrServerSpecified = !!hmrConfig?.server |
| 142 | + const hmrConfigName = path.basename(config.configFile || 'vite.config.js') |
| 143 | + |
| 144 | + // hmr.clientPort -> hmr.port |
| 145 | + // -> (24678 if middleware mode and HMR server is not specified) -> new URL(import.meta.url).port |
| 146 | + let port = hmrConfig?.clientPort || hmrConfig?.port || null |
| 147 | + if (config.server.middlewareMode && !isHmrServerSpecified) { |
| 148 | + port ||= 24678 |
| 149 | + } |
| 150 | + |
| 151 | + let directTarget = hmrConfig?.host || resolvedServerHostname |
| 152 | + directTarget += `:${hmrConfig?.port || resolvedServerPort}` |
| 153 | + directTarget += devBase |
| 154 | + |
| 155 | + let hmrBase = devBase |
| 156 | + if (hmrConfig?.path) { |
| 157 | + hmrBase = path.posix.join(hmrBase, hmrConfig.path) |
| 158 | + } |
| 159 | + |
| 160 | + const modeReplacement = escapeReplacement(config.mode) |
| 161 | + const baseReplacement = escapeReplacement(devBase) |
| 162 | + const serverHostReplacement = escapeReplacement(serverHost) |
| 163 | + const hmrProtocolReplacement = escapeReplacement(protocol) |
| 164 | + const hmrHostnameReplacement = escapeReplacement(host) |
| 165 | + const hmrPortReplacement = escapeReplacement(port) |
| 166 | + const hmrDirectTargetReplacement = escapeReplacement(directTarget) |
| 167 | + const hmrBaseReplacement = escapeReplacement(hmrBase) |
| 168 | + const hmrTimeoutReplacement = escapeReplacement(timeout) |
| 169 | + const hmrEnableOverlayReplacement = escapeReplacement(overlay) |
| 170 | + const hmrConfigNameReplacement = escapeReplacement(hmrConfigName) |
| 171 | + const wsTokenReplacement = escapeReplacement(config.webSocketToken) |
| 172 | + |
| 173 | + return content |
| 174 | + .replace(`__MODE__`, modeReplacement) |
| 175 | + .replace(/__BASE__/g, baseReplacement) |
| 176 | + .replace(`__SERVER_HOST__`, serverHostReplacement) |
| 177 | + .replace(`__HMR_PROTOCOL__`, hmrProtocolReplacement) |
| 178 | + .replace(`__HMR_HOSTNAME__`, hmrHostnameReplacement) |
| 179 | + .replace(`__HMR_PORT__`, hmrPortReplacement) |
| 180 | + .replace(`__HMR_DIRECT_TARGET__`, hmrDirectTargetReplacement) |
| 181 | + .replace(`__HMR_BASE__`, hmrBaseReplacement) |
| 182 | + .replace(`__HMR_TIMEOUT__`, hmrTimeoutReplacement) |
| 183 | + .replace(`__HMR_ENABLE_OVERLAY__`, hmrEnableOverlayReplacement) |
| 184 | + .replace(`__HMR_CONFIG_NAME__`, hmrConfigNameReplacement) |
| 185 | + .replace(`__WS_TOKEN__`, wsTokenReplacement) |
| 186 | +} |
0 commit comments