diff --git a/.changeset/remove-build-end-public-path.md b/.changeset/remove-build-end-public-path.md new file mode 100644 index 0000000000..56b396c863 --- /dev/null +++ b/.changeset/remove-build-end-public-path.md @@ -0,0 +1,5 @@ +--- +"@react-router/dev": major +--- + +For Remix consumers migrating to React Router who used the Vite plugin's `buildEnd` hook, the resolved `reactRouterConfig` object no longer contains a `publicPath` property since this belongs to Vite, not React Router. diff --git a/integration/vite-presets-test.ts b/integration/vite-presets-test.ts index d508e4efb6..1ff99dc4e2 100644 --- a/integration/vite-presets-test.ts +++ b/integration/vite-presets-test.ts @@ -214,7 +214,6 @@ test("Vite / presets", async () => { "buildEnd", "future", "prerender", - "publicPath", "routes", "serverBuildFile", "serverBundles", diff --git a/packages/remix-dev/config.ts b/packages/remix-dev/config.ts index 4d7cd6cbe4..2a3ddd7a91 100644 --- a/packages/remix-dev/config.ts +++ b/packages/remix-dev/config.ts @@ -193,10 +193,6 @@ export type ResolvedVitePluginConfig = Readonly<{ * An array of URLs to prerender to HTML files at build time. */ prerender: Array | null; - /** - * Derived from Vite's `base` config - * */ - publicPath: string; /** * An object of all available routes, keyed by route id. */ @@ -314,6 +310,10 @@ let deepFreeze = (o: any) => { return o; }; +export function resolvePublicPath(viteUserConfig: Vite.UserConfig) { + return viteUserConfig.base ?? "/"; +} + export async function resolveReactRouterConfig({ rootDirectory, reactRouterUserConfig, @@ -404,7 +404,7 @@ export async function resolveReactRouterConfig({ let appDirectory = path.resolve(rootDirectory, userAppDirectory || "app"); let buildDirectory = path.resolve(rootDirectory, userBuildDirectory); - let publicPath = viteUserConfig.base ?? "/"; + let publicPath = resolvePublicPath(viteUserConfig); if ( basename !== "/" && @@ -453,7 +453,6 @@ export async function resolveReactRouterConfig({ buildEnd, future, prerender, - publicPath, routes, serverBuildFile, serverBundles, diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index c632482928..9e876daae0 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -36,6 +36,7 @@ import { type ResolvedVitePluginConfig, resolveReactRouterConfig, resolveEntryFiles, + resolvePublicPath, } from "../config"; export async function resolveViteConfig({ @@ -150,6 +151,7 @@ export type ReactRouterPluginContext = ReactRouterPluginSsrBuildContext & { rootDirectory: string; entryClientFilePath: string; entryServerFilePath: string; + publicPath: string; reactRouterConfig: ResolvedVitePluginConfig; viteManifestEnabled: boolean; }; @@ -233,14 +235,14 @@ const getReactRouterManifestBuildAssets = ( ]); return { - module: `${ctx.reactRouterConfig.publicPath}${entryChunk.file}`, + module: `${ctx.publicPath}${entryChunk.file}`, imports: dedupe(chunks.flatMap((e) => e.imports ?? [])).map((imported) => { - return `${ctx.reactRouterConfig.publicPath}${viteManifest[imported].file}`; + return `${ctx.publicPath}${viteManifest[imported].file}`; }) ?? [], css: dedupe(chunks.flatMap((e) => e.css ?? [])).map((href) => { - return `${ctx.reactRouterConfig.publicPath}${href}`; + return `${ctx.publicPath}${href}`; }) ?? [], }; }; @@ -442,6 +444,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => { reactRouterConfig, }); + let publicPath = resolvePublicPath(viteUserConfig); let viteManifestEnabled = viteUserConfig.build?.manifest === true; let ssrBuildCtx: ReactRouterPluginSsrBuildContext = @@ -460,6 +463,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => { rootDirectory, entryClientFilePath, entryServerFilePath, + publicPath, viteManifestEnabled, ...ssrBuildCtx, }; @@ -507,9 +511,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => { export const isSpaMode = ${ !ctx.reactRouterConfig.ssr && ctx.reactRouterConfig.prerender == null }; - export const publicPath = ${JSON.stringify( - ctx.reactRouterConfig.publicPath - )}; + export const publicPath = ${JSON.stringify(ctx.publicPath)}; export const entry = { module: entryServer }; export const routes = { ${Object.keys(routes) @@ -625,7 +627,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => { viteConfig.build.assetsDir, `manifest-${version}.js` ); - let url = `${ctx.reactRouterConfig.publicPath}${manifestPath}`; + let url = `${ctx.publicPath}${manifestPath}`; let nonFingerprintedValues = { url, version }; let reactRouterBrowserManifest: ReactRouterManifest = { @@ -671,7 +673,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => { index: route.index, caseSensitive: route.caseSensitive, module: path.posix.join( - ctx.reactRouterConfig.publicPath, + ctx.publicPath, `${resolveFileUrl( ctx, resolveRelativeRouteFilePath(route, ctx.reactRouterConfig) @@ -689,18 +691,18 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = (_config) => { return { version: String(Math.random()), url: path.posix.join( - ctx.reactRouterConfig.publicPath, + ctx.publicPath, VirtualModule.url(browserManifestId) ), hmr: { runtime: path.posix.join( - ctx.reactRouterConfig.publicPath, + ctx.publicPath, VirtualModule.url(injectHmrRuntimeId) ), }, entry: { module: path.posix.join( - ctx.reactRouterConfig.publicPath, + ctx.publicPath, resolveFileUrl(ctx, ctx.entryClientFilePath) ), imports: [], @@ -1624,7 +1626,7 @@ async function getRouteMetadata( index: route.index, caseSensitive: route.caseSensitive, url: path.posix.join( - ctx.reactRouterConfig.publicPath, + ctx.publicPath, "/" + path.relative( ctx.rootDirectory, @@ -1632,7 +1634,7 @@ async function getRouteMetadata( ) ), module: path.posix.join( - ctx.reactRouterConfig.publicPath, + ctx.publicPath, `${resolveFileUrl( ctx, resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)