diff --git a/.changeset/warn-vite8-cloudflare-override.md b/.changeset/warn-vite8-cloudflare-override.md new file mode 100644 index 000000000000..2b6f183fad9f --- /dev/null +++ b/.changeset/warn-vite8-cloudflare-override.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Warns on dev server startup when Vite 8 is detected at the top level of the user's project, and automatically adds a `"overrides": { "vite": "^7" }` entry to `package.json` when running `astro add cloudflare`. This prevents a `require_dist is not a function` crash caused by a Vite version split between Astro (requires Vite 7) and packages like `@tailwindcss/vite` that hoist Vite 8. diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index 1b48674cbc5d..0674933c7a36 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -246,6 +246,13 @@ export async function add(names: string[], { flags }: AddOptions) { logger, scripts: { 'generate-types': 'wrangler types' }, }); + + await updatePackageJsonOverrides({ + configURL, + flags, + logger, + overrides: { vite: '^7' }, + }); } if (integrations.find((integration) => integration.id === 'tailwind')) { const dir = new URL('./styles/', new URL(userConfig.srcDir ?? './src/', root)); @@ -715,6 +722,67 @@ async function updateAstroConfig({ } } +async function updatePackageJsonOverrides({ + configURL, + flags, + logger, + overrides, +}: { + configURL: URL; + flags: Flags; + logger: Logger; + overrides: Record; +}): Promise { + const pkgURL = new URL('./package.json', configURL); + if (!existsSync(pkgURL)) { + logger.debug('add', 'No package.json found, skipping overrides update'); + return UpdateResult.none; + } + + const pkgPath = fileURLToPath(pkgURL); + const input = await fs.readFile(pkgPath, { encoding: 'utf-8' }); + const pkgJson = JSON.parse(input); + + pkgJson.overrides ??= {}; + let hasChanges = false; + for (const [name, range] of Object.entries(overrides)) { + if (!(name in pkgJson.overrides)) { + pkgJson.overrides[name] = range; + hasChanges = true; + } + } + + if (!hasChanges) { + return UpdateResult.none; + } + + const output = JSON.stringify(pkgJson, null, 2); + const diff = getDiffContent(input, output); + + if (!diff) { + return UpdateResult.none; + } + + logger.info( + 'SKIP_FORMAT', + `\n ${magenta('Astro will add the following overrides to your package.json:')}`, + ); + + clack.box(diff, 'package.json', { + rounded: true, + withGuide: false, + width: 'auto', + }); + + if (await askToContinue({ flags, logger })) { + await fs.writeFile(pkgPath, output, { encoding: 'utf-8' }); + logger.debug('add', 'Updated package.json overrides'); + return UpdateResult.updated; + } else { + return UpdateResult.cancelled; + } +} + async function updatePackageJsonScripts({ configURL, flags, diff --git a/packages/astro/src/core/dev/dev.ts b/packages/astro/src/core/dev/dev.ts index 36ffb1fcbb04..7ed92db0b13a 100644 --- a/packages/astro/src/core/dev/dev.ts +++ b/packages/astro/src/core/dev/dev.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; import type http from 'node:http'; +import { createRequire } from 'node:module'; import type { AddressInfo } from 'node:net'; import { performance } from 'node:perf_hooks'; import colors from 'piccolore'; @@ -24,6 +25,19 @@ import { } from './update-check.js'; import { BuildTimeAstroVersionProvider } from '../../cli/infra/build-time-astro-version-provider.js'; import { piccoloreTextStyler } from '../../cli/infra/piccolore-text-styler.js'; +import type { Logger } from '../logger/core.js'; + +function warnIfVite8({ root, logger }: { root: URL | string; logger: Logger }) { + try { + const require = createRequire(root); + const { version } = require('vite/package.json') as { version: string }; + if (major(version) >= 8) { + logger.warn('SKIP_FORMAT', msg.vite8Warning({ viteVersion: version })); + } + } catch { + // If vite can't be resolved from the project root, skip the warning + } +} export interface DevServer { address: AddressInfo; @@ -140,6 +154,8 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise warnIfVite8({ root: restart.container.settings.config.root, logger })); + logger.info(null, colors.green('watching for file changes...')); return { diff --git a/packages/astro/src/core/messages/runtime.ts b/packages/astro/src/core/messages/runtime.ts index 115c1fb5e780..f83062426916 100644 --- a/packages/astro/src/core/messages/runtime.ts +++ b/packages/astro/src/core/messages/runtime.ts @@ -179,6 +179,12 @@ export function fsStrictWarning() { return `${title}\n${subtitle}\n`; } +export function vite8Warning({ viteVersion }: { viteVersion: string }) { + const title = yellow('▶ ' + `Vite ${bold(viteVersion)} detected in your project.`); + const subtitle = ` Astro requires Vite 7. Add ${bold('"overrides": { "vite": "^7" }')} to your ${bold('package.json')} to avoid issues.`; + return `${title}\n${subtitle}\n`; +} + export function prerelease({ currentVersion }: { currentVersion: string }) { const tag = currentVersion.split('-').slice(1).join('-').replace(/\..*$/, '') || 'unknown'; const badge = bgYellow(black(` ${tag} `));