diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index 8ae8312f7..9c9ca8c77 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -5,6 +5,7 @@ import type { RenderedChunk } from 'rollup'; import { rollupPluginAstroBuildHTML } from '../../vite-plugin-build-html/index.js'; import { rollupPluginAstroBuildCSS } from '../../vite-plugin-build-css/index.js'; +import { rollupPluginAstroBuildLoadFallback } from '../../vite-plugin-build-load-fallback/index.js'; import fs from 'fs'; import * as colors from 'kleur/colors'; import { performance } from 'perf_hooks'; @@ -200,6 +201,10 @@ class AstroBuilder { pureCSSChunks, }), ...(viteConfig.plugins || []), + rollupPluginAstroBuildLoadFallback({ + astroConfig: this.config, + viteServer + }), ], publicDir: viteConfig.publicDir, root: viteConfig.root, diff --git a/packages/astro/src/vite-plugin-build-html/index.ts b/packages/astro/src/vite-plugin-build-html/index.ts index 29005842a..139cc4051 100644 --- a/packages/astro/src/vite-plugin-build-html/index.ts +++ b/packages/astro/src/vite-plugin-build-html/index.ts @@ -38,7 +38,7 @@ interface PluginOptions { viteServer: ViteDevServer; } -export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin[] { +export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin { const { astroConfig, astroStyleMap, astroPageStyleMap, chunkToReferenceIdMap, pureCSSChunks, logging, origin, allPages, routeCache, viteServer, pageNames } = options; // The filepath root of the src folder @@ -56,7 +56,7 @@ export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin[] const cssChunkMap = new Map(); - return [{ + return { name: PLUGIN_NAME, enforce: 'pre', @@ -452,26 +452,5 @@ export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin[] }); } }, - }, { - name: '@astro/rollup-plugin-build-load-fallback', - enforce: 'post', - resolveId(id) { - // If we got here, nothing picked up this module, so let's try - // and grab it from the viteServer used for SSR loading. - if(id[0] === '/') { - return id; - } - return null; - }, - async load(id) { - try { - // This uses ssrLoadModule and not transformResult because - // transformResult is always giving JavaScript. - const mod = await viteServer.ssrLoadModule(id); - return mod.default; - } catch { - return null; - } - } - }]; + }; } diff --git a/packages/astro/src/vite-plugin-build-load-fallback/index.ts b/packages/astro/src/vite-plugin-build-load-fallback/index.ts new file mode 100644 index 000000000..ff1b287e7 --- /dev/null +++ b/packages/astro/src/vite-plugin-build-load-fallback/index.ts @@ -0,0 +1,59 @@ +import type { Plugin as VitePlugin, ViteDevServer } from 'vite'; +import type { AstroConfig } from '../@types/astro'; + +export interface PluginOptions { + astroConfig: AstroConfig; + viteServer: ViteDevServer; +} + +export function rollupPluginAstroBuildLoadFallback({ astroConfig, viteServer }: PluginOptions): VitePlugin { + let viteFallback: VitePlugin | undefined; + + return { + name: '@astro/rollup-plugin-build-load-fallback', + enforce: 'post', + configResolved(resolvedConfig) { + resolvedConfig.plugins?.findIndex(p => p.name === ''); + + // Move this plugin right before the end. vite:load-fallback throws if nothing + // is found. But we want to try it and if it fails, try to get from SSR. + const plugins = resolvedConfig.plugins as VitePlugin[]; + const ourIndex = plugins.findIndex((p) => p.name === '@astro/rollup-plugin-build-load-fallback'); + if (ourIndex !== -1) { + const ourPlugin = plugins[ourIndex]; + plugins.splice(ourIndex, 1); + plugins.splice(plugins.length - 1, 0, ourPlugin); + viteFallback = plugins.find(p => p.name === 'vite:load-fallback'); + } + }, + resolveId(id) { + // If we got here, nothing picked up this module, so let's try + // and grab it from the viteServer used for SSR loading. + if(id[0] === '/' && !id.startsWith(astroConfig.projectRoot.pathname)) { + return id; + } + return null; + }, + async load(id) { + if(id[0] === '/' && !id.startsWith(astroConfig.projectRoot.pathname)) { + try { + if(viteFallback) { + // First try viteFallback. Assuming this is a filepath, it will pick it up. + return await viteFallback.load?.call(this, id); + } + } catch { + try { + // This uses ssrLoadModule and not transformResult because + // transformResult is always giving JavaScript. + const mod = await viteServer.ssrLoadModule(id); + return mod.default; + } catch { + return null; + } + } + } + + return null; + } + }; +} \ No newline at end of file