UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

55 lines (54 loc) • 2.5 kB
const VIRTUAL_MODULE_ID = "astro:prefetch"; const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID; const prefetchInternalModuleFsSubpath = "astro/dist/prefetch/index.js"; const prefetchCode = `import { init } from 'astro/virtual-modules/prefetch.js';init()`; export default function astroPrefetch({ settings }) { const prefetchOption = settings.config.prefetch; const prefetch = prefetchOption ? typeof prefetchOption === "object" ? prefetchOption : {} : undefined; // Check against existing scripts as this plugin could be called multiple times if (prefetch && settings.scripts.every((s) => s.content !== prefetchCode)) { // Inject prefetch script to all pages settings.scripts.push({ stage: "page", content: `import { init } from 'astro/virtual-modules/prefetch.js';init()` }); } // Throw a normal error instead of an AstroError as Vite captures this in the plugin lifecycle // and would generate a different stack trace itself through Vite's transform pipeline. const throwPrefetchNotEnabledError = () => { throw new Error("You need to enable the `prefetch` Astro config to import `astro:prefetch`"); }; return { name: "astro:prefetch", resolveId: { filter: { id: new RegExp(`^${VIRTUAL_MODULE_ID}$`) }, handler() { if (!prefetch) throwPrefetchNotEnabledError(); return RESOLVED_VIRTUAL_MODULE_ID; } }, load: { filter: { id: new RegExp(`^${RESOLVED_VIRTUAL_MODULE_ID}$`) }, handler() { if (!prefetch) throwPrefetchNotEnabledError(); return { code: `export { prefetch } from "astro/virtual-modules/prefetch.js";` }; } }, transform: { filter: { // NOTE: Handle replacing the specifiers even if prefetch is disabled so View Transitions // can import the internal module and not hit runtime issues. id: new RegExp(`${prefetchInternalModuleFsSubpath}`) }, handler(code) { // We perform a simple replacement with padding so that the code offset is not changed and // we don't have to generate a sourcemap. This has the assumption that the replaced string // will always be shorter than the search string to work. code = code.replace("__PREFETCH_PREFETCH_ALL__", `${JSON.stringify(prefetch?.prefetchAll)}`.padEnd(25)).replace("__PREFETCH_DEFAULT_STRATEGY__", `${JSON.stringify(prefetch?.defaultStrategy)}`.padEnd(29)).replace("__EXPERIMENTAL_CLIENT_PRERENDER__", `${JSON.stringify(settings.config.experimental.clientPrerender)}`.padEnd(33)); return { code, map: null }; } } }; }