Skip to content

Commit

Permalink
fix: escape replacements in clientInjections (#12486)
Browse files Browse the repository at this point in the history
Co-authored-by: patak <matias.capeletto@gmail.com>
  • Loading branch information
d-fischer and patak-dev authored Mar 21, 2023
1 parent 0cb9171 commit 3765067
Showing 1 changed file with 64 additions and 39 deletions.
103 changes: 64 additions & 39 deletions packages/vite/src/node/plugins/clientInjections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,74 @@ const normalizedEnvEntry = normalizePath(ENV_ENTRY)
* @server-only
*/
export function clientInjectionsPlugin(config: ResolvedConfig): Plugin {
let injectConfigValues: (code: string) => string

return {
name: 'vite:client-inject',
async transform(code, id, options) {
if (id === normalizedClientEntry || id === normalizedEnvEntry) {
const resolvedServerHostname = (
await resolveHostname(config.server.host)
).name
const resolvedServerPort = config.server.port!
const devBase = config.base
async buildStart() {
const resolvedServerHostname = (await resolveHostname(config.server.host))
.name
const resolvedServerPort = config.server.port!
const devBase = config.base

const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}`

const serverHost = `${resolvedServerHostname}:${resolvedServerPort}${devBase}`
let hmrConfig = config.server.hmr
hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined
const host = hmrConfig?.host || null
const protocol = hmrConfig?.protocol || null
const timeout = hmrConfig?.timeout || 30000
const overlay = hmrConfig?.overlay !== false
const isHmrServerSpecified = !!hmrConfig?.server

let hmrConfig = config.server.hmr
hmrConfig = isObject(hmrConfig) ? hmrConfig : undefined
const host = hmrConfig?.host || null
const protocol = hmrConfig?.protocol || null
const timeout = hmrConfig?.timeout || 30000
const overlay = hmrConfig?.overlay !== false
const isHmrServerSpecified = !!hmrConfig?.server
// hmr.clientPort -> hmr.port
// -> (24678 if middleware mode and HMR server is not specified) -> new URL(import.meta.url).port
let port = hmrConfig?.clientPort || hmrConfig?.port || null
if (config.server.middlewareMode && !isHmrServerSpecified) {
port ||= 24678
}

let directTarget = hmrConfig?.host || resolvedServerHostname
directTarget += `:${hmrConfig?.port || resolvedServerPort}`
directTarget += devBase

// hmr.clientPort -> hmr.port
// -> (24678 if middleware mode and HMR server is not specified) -> new URL(import.meta.url).port
let port = hmrConfig?.clientPort || hmrConfig?.port || null
if (config.server.middlewareMode && !isHmrServerSpecified) {
port ||= 24678
}
let hmrBase = devBase
if (hmrConfig?.path) {
hmrBase = path.posix.join(hmrBase, hmrConfig.path)
}

let directTarget = hmrConfig?.host || resolvedServerHostname
directTarget += `:${hmrConfig?.port || resolvedServerPort}`
directTarget += devBase
const serializedDefines = serializeDefine(config.define || {})

let hmrBase = devBase
if (hmrConfig?.path) {
hmrBase = path.posix.join(hmrBase, hmrConfig.path)
}
const modeReplacement = escapeReplacement(config.mode)
const baseReplacement = escapeReplacement(devBase)
const definesReplacement = () => serializedDefines
const serverHostReplacement = escapeReplacement(serverHost)
const hmrProtocolReplacement = escapeReplacement(protocol)
const hmrHostnameReplacement = escapeReplacement(host)
const hmrPortReplacement = escapeReplacement(port)
const hmrDirectTargetReplacement = escapeReplacement(directTarget)
const hmrBaseReplacement = escapeReplacement(hmrBase)
const hmrTimeoutReplacement = escapeReplacement(timeout)
const hmrEnableOverlayReplacement = escapeReplacement(overlay)

injectConfigValues = (code: string) => {
return code
.replace(`__MODE__`, JSON.stringify(config.mode))
.replace(/__BASE__/g, JSON.stringify(devBase))
.replace(`__DEFINES__`, serializeDefine(config.define || {}))
.replace(`__SERVER_HOST__`, JSON.stringify(serverHost))
.replace(`__HMR_PROTOCOL__`, JSON.stringify(protocol))
.replace(`__HMR_HOSTNAME__`, JSON.stringify(host))
.replace(`__HMR_PORT__`, JSON.stringify(port))
.replace(`__HMR_DIRECT_TARGET__`, JSON.stringify(directTarget))
.replace(`__HMR_BASE__`, JSON.stringify(hmrBase))
.replace(`__HMR_TIMEOUT__`, JSON.stringify(timeout))
.replace(`__HMR_ENABLE_OVERLAY__`, JSON.stringify(overlay))
.replace(`__MODE__`, modeReplacement)
.replace(/__BASE__/g, baseReplacement)
.replace(`__DEFINES__`, definesReplacement)
.replace(`__SERVER_HOST__`, serverHostReplacement)
.replace(`__HMR_PROTOCOL__`, hmrProtocolReplacement)
.replace(`__HMR_HOSTNAME__`, hmrHostnameReplacement)
.replace(`__HMR_PORT__`, hmrPortReplacement)
.replace(`__HMR_DIRECT_TARGET__`, hmrDirectTargetReplacement)
.replace(`__HMR_BASE__`, hmrBaseReplacement)
.replace(`__HMR_TIMEOUT__`, hmrTimeoutReplacement)
.replace(`__HMR_ENABLE_OVERLAY__`, hmrEnableOverlayReplacement)
}
},
transform(code, id, options) {
if (id === normalizedClientEntry || id === normalizedEnvEntry) {
return injectConfigValues(code)
} else if (!options?.ssr && code.includes('process.env.NODE_ENV')) {
// replace process.env.NODE_ENV instead of defining a global
// for it to avoid shimming a `process` object during dev,
Expand All @@ -75,6 +95,11 @@ export function clientInjectionsPlugin(config: ResolvedConfig): Plugin {
}
}

function escapeReplacement(value: string | number | boolean | null) {
const jsonValue = JSON.stringify(value)
return () => jsonValue
}

function serializeDefine(define: Record<string, any>): string {
let res = `{`
for (const key in define) {
Expand Down

0 comments on commit 3765067

Please sign in to comment.