diff --git a/packages/vite/rolldown.config.ts b/packages/vite/rolldown.config.ts index 5fede87774cbc8..2738326fc7f824 100644 --- a/packages/vite/rolldown.config.ts +++ b/packages/vite/rolldown.config.ts @@ -4,6 +4,7 @@ import { ImportType, init, parse } from 'es-module-lexer' import MagicString from 'magic-string' import type { Plugin } from 'rolldown' import { defineConfig } from 'rolldown' +import rolldownPkg from 'rolldown/package.json' with { type: 'json' } import pkg from './package.json' with { type: 'json' } import licensePlugin from './rollupLicensePlugin' @@ -83,6 +84,11 @@ const nodeConfig = defineConfig({ cli: path.resolve(dirname, 'src/node/cli.ts'), internal: path.resolve(dirname, 'src/node/internalIndex.ts'), }, + transform: { + define: { + __VITE_BUNDLED_ROLLDOWN_VERSION__: JSON.stringify(rolldownPkg.version), + }, + }, external: [ /^vite\//, 'fsevents', diff --git a/packages/vite/src/client/bundledDevClient.ts b/packages/vite/src/client/bundledDevClient.ts index 58de0bc2afe4db..3211c299bfeb32 100644 --- a/packages/vite/src/client/bundledDevClient.ts +++ b/packages/vite/src/client/bundledDevClient.ts @@ -13,6 +13,10 @@ import { updateStyle, } from './client' +// Replaced with the rolldown version this client was built against when the +// file is served, see `getHmrImplementation` in `node/plugins/clientInjections.ts`. +declare const __VITE_BUNDLED_ROLLDOWN_VERSION__: string + // keep the same public exports as `client.ts`, which this entry replaces when inlined export { createHotContext, @@ -51,6 +55,8 @@ if (typeof DevRuntime !== 'undefined') { const runtime = ((globalThis as any).__rolldown_runtime__ ??= new ViteDevRuntime(clientId)) + ;(runtime as any).bundledRolldownVersion = __VITE_BUNDLED_ROLLDOWN_VERSION__ + const bundledDevHmrClient = new BundledDevHMRClient( { error: (err) => console.error('[vite]', err), diff --git a/packages/vite/src/node/constants.ts b/packages/vite/src/node/constants.ts index dd208e13d366b3..ed91bd8548e314 100644 --- a/packages/vite/src/node/constants.ts +++ b/packages/vite/src/node/constants.ts @@ -35,6 +35,12 @@ export const ROLLUP_HOOKS: RollupPluginHooks[] = [ export const VERSION = version as string +declare const __VITE_BUNDLED_ROLLDOWN_VERSION__: string +export const BUNDLED_ROLLDOWN_VERSION: string | undefined = + typeof __VITE_BUNDLED_ROLLDOWN_VERSION__ === 'undefined' + ? undefined + : __VITE_BUNDLED_ROLLDOWN_VERSION__ + const DEFAULT_MAIN_FIELDS = [ 'browser', 'module', diff --git a/packages/vite/src/node/plugins/clientInjections.ts b/packages/vite/src/node/plugins/clientInjections.ts index 782d28ad178f57..c12ed5eaaa416d 100644 --- a/packages/vite/src/node/plugins/clientInjections.ts +++ b/packages/vite/src/node/plugins/clientInjections.ts @@ -2,7 +2,12 @@ import fs from 'node:fs' import path from 'node:path' import { cleanUrl } from '../../shared/utils' import type { ResolvedConfig } from '../config' -import { CLIENT_ENTRY, ENV_ENTRY, BUNDLED_DEV_CLIENT_ENTRY } from '../constants' +import { + CLIENT_ENTRY, + ENV_ENTRY, + BUNDLED_DEV_CLIENT_ENTRY, + BUNDLED_ROLLDOWN_VERSION, +} from '../constants' import { perEnvironmentState } from '../environment' import type { Plugin } from '../plugin' import { isObject, normalizePath, resolveHostname } from '../utils' @@ -120,6 +125,9 @@ async function createClientConfigValueReplacer( const serverForwardConsoleReplacement = escapeReplacement( config.server.forwardConsole as any, ) + const bundledRolldownVersionReplacement = escapeReplacement( + BUNDLED_ROLLDOWN_VERSION ?? 'unknown', + ) return (code) => code @@ -136,6 +144,10 @@ async function createClientConfigValueReplacer( .replace(`__HMR_CONFIG_NAME__`, hmrConfigNameReplacement) .replace(`__WS_TOKEN__`, wsTokenReplacement) .replace(`__SERVER_FORWARD_CONSOLE__`, serverForwardConsoleReplacement) + .replace( + /__VITE_BUNDLED_ROLLDOWN_VERSION__/g, + bundledRolldownVersionReplacement, + ) } export async function getHmrImplementation( diff --git a/packages/vite/src/node/server/bundledDev.ts b/packages/vite/src/node/server/bundledDev.ts index 3519f188c1044f..df0eb25c561033 100644 --- a/packages/vite/src/node/server/bundledDev.ts +++ b/packages/vite/src/node/server/bundledDev.ts @@ -7,8 +7,12 @@ import { type DevEngine, dev, } from 'rolldown/experimental' +import rolldownPkg from 'rolldown/package.json' with { type: 'json' } import { ChunkMetadataMap, resolveRolldownOptions } from '../build' -import { BUNDLED_DEV_CLIENT_FILENAME } from '../constants' +import { + BUNDLED_DEV_CLIENT_FILENAME, + BUNDLED_ROLLDOWN_VERSION, +} from '../constants' import { getHmrImplementation } from '../plugins/clientInjections' import { createDebugger, formatAndTruncateFileList } from '../utils' import { convertToDevWatchOptions } from '../watch' @@ -116,6 +120,7 @@ export class BundledDev { async listen(): Promise { this._closed = false + checkBundledRolldownVersion(this.environment) debug?.('INITIAL: setup bundle options') const rolldownOptions = await this.getRolldownOptions() // NOTE: only single outputOptions is supported here @@ -561,3 +566,22 @@ function debounce(time: number, cb: () => void) { function payloadDeliveredAck(filename: string): string { return `\n;__rolldown_runtime__.payloadDelivered(${JSON.stringify(filename)});` } + +function checkBundledRolldownVersion(environment: DevEnvironment): void { + // undefined when running from source, where nothing is pre-bundled + if (BUNDLED_ROLLDOWN_VERSION === undefined) return + const installed = rolldownPkg.version + if (installed === BUNDLED_ROLLDOWN_VERSION) return + environment.logger.warn( + colors.yellow( + `experimental.bundledDev: this Vite release bundles the rolldown dev runtime ` + + `of rolldown@${BUNDLED_ROLLDOWN_VERSION}, but the installed rolldown@${installed} ` + + `generates the code that runtime executes. The mismatch can break dynamic ` + + `imports or HMR at runtime with errors like ` + + `"__rolldown_runtime__.requestLazy is not a function".\n` + + `To fix this, upgrade Vite to a release built against rolldown@${installed}, ` + + `or pin rolldown to ${BUNDLED_ROLLDOWN_VERSION} (e.g. via the "overrides" ` + + `field in package.json).`, + ), + ) +}