import nodeFs from "node:fs"; import { fileURLToPath } from "node:url"; import * as vite from "vite"; import { crawlFrameworkPkgs } from "vitefu"; import astroAssetsPlugin from "../assets/vite-plugin-assets.js"; import { astroContentAssetPropagationPlugin, astroContentImportPlugin, astroContentVirtualModPlugin } from "../content/index.js"; import astroPostprocessVitePlugin from "../vite-plugin-astro-postprocess/index.js"; import { vitePluginAstroServer } from "../vite-plugin-astro-server/index.js"; import astroVitePlugin from "../vite-plugin-astro/index.js"; import configAliasVitePlugin from "../vite-plugin-config-alias/index.js"; import envVitePlugin from "../vite-plugin-env/index.js"; import astroHeadPlugin from "../vite-plugin-head/index.js"; import htmlVitePlugin from "../vite-plugin-html/index.js"; import { astroInjectEnvTsPlugin } from "../vite-plugin-inject-env-ts/index.js"; import astroIntegrationsContainerPlugin from "../vite-plugin-integrations-container/index.js"; import jsxVitePlugin from "../vite-plugin-jsx/index.js"; import astroLoadFallbackPlugin from "../vite-plugin-load-fallback/index.js"; import markdownVitePlugin from "../vite-plugin-markdown/index.js"; import astroScannerPlugin from "../vite-plugin-scanner/index.js"; import astroScriptsPlugin from "../vite-plugin-scripts/index.js"; import astroScriptsPageSSRPlugin from "../vite-plugin-scripts/page-ssr.js"; import { vitePluginSSRManifest } from "../vite-plugin-ssr-manifest/index.js"; import { joinPaths } from "./path.js"; const ALWAYS_NOEXTERNAL = [ // This is only because Vite's native ESM doesn't resolve "exports" correctly. "astro", // Vite fails on nested `.astro` imports without bundling "astro/components", // Handle recommended nanostores. Only @nanostores/preact is required from our testing! // Full explanation and related bug report: https://github.com/withastro/astro/pull/3667 "@nanostores/preact", // fontsource packages are CSS that need to be processed "@fontsource/*" ]; const ONLY_DEV_EXTERNAL = [ // Imported by `` which is processed by Vite "shiki", // Imported by `@astrojs/prism` which exposes `` that is processed by Vite "prismjs/components/index.js", // Imported by `astro/assets` -> `packages/astro/src/core/logger/core.ts` "string-width" ]; async function createVite(commandConfig, { settings, logging, mode, command, fs = nodeFs }) { var _a, _b; const astroPkgsConfig = await crawlFrameworkPkgs({ root: fileURLToPath(settings.config.root), isBuild: mode === "build", viteUserConfig: settings.config.vite, isFrameworkPkgByJson(pkgJson) { var _a2, _b2, _c, _d, _e; if (((_a2 = pkgJson == null ? void 0 : pkgJson.astro) == null ? void 0 : _a2.external) === true) { return false; } return ( // Attempt: package relies on `astro`. ✅ Definitely an Astro package ((_b2 = pkgJson.peerDependencies) == null ? void 0 : _b2.astro) || ((_c = pkgJson.dependencies) == null ? void 0 : _c.astro) || // Attempt: package is tagged with `astro` or `astro-component`. ✅ Likely a community package ((_d = pkgJson.keywords) == null ? void 0 : _d.includes("astro")) || ((_e = pkgJson.keywords) == null ? void 0 : _e.includes("astro-component")) || // Attempt: package is named `astro-something` or `@scope/astro-something`. ✅ Likely a community package /^(@[^\/]+\/)?astro\-/.test(pkgJson.name) ); }, isFrameworkPkgByName(pkgName) { const isNotAstroPkg = isCommonNotAstro(pkgName); if (isNotAstroPkg) { return false; } else { return void 0; } } }); const commonConfig = { cacheDir: fileURLToPath(new URL("./node_modules/.vite/", settings.config.root)), // using local caches allows Astro to be used in monorepos, etc. clearScreen: false, // we want to control the output, not Vite logLevel: "warn", // log warnings and errors only appType: "custom", optimizeDeps: { entries: ["src/**/*"], exclude: ["astro", "node-fetch"] }, plugins: [ configAliasVitePlugin({ settings }), astroLoadFallbackPlugin({ fs, root: settings.config.root }), astroVitePlugin({ settings, logging }), astroScriptsPlugin({ settings }), // The server plugin is for dev only and having it run during the build causes // the build to run very slow as the filewatcher is triggered often. mode !== "build" && vitePluginAstroServer({ settings, logging, fs }), envVitePlugin({ settings }), markdownVitePlugin({ settings, logging }), htmlVitePlugin(), jsxVitePlugin({ settings, logging }), astroPostprocessVitePlugin(), mode === "dev" && astroIntegrationsContainerPlugin({ settings, logging }), astroScriptsPageSSRPlugin({ settings }), astroHeadPlugin(), astroScannerPlugin({ settings }), astroInjectEnvTsPlugin({ settings, logging, fs }), astroContentVirtualModPlugin({ settings }), astroContentImportPlugin({ fs, settings }), astroContentAssetPropagationPlugin({ mode, settings }), vitePluginSSRManifest(), settings.config.experimental.assets ? [astroAssetsPlugin({ settings, logging, mode })] : [] ], publicDir: fileURLToPath(settings.config.publicDir), root: fileURLToPath(settings.config.root), envPrefix: ((_a = settings.config.vite) == null ? void 0 : _a.envPrefix) ?? "PUBLIC_", define: { "import.meta.env.SITE": settings.config.site ? JSON.stringify(settings.config.site) : "undefined" }, server: { hmr: process.env.NODE_ENV === "test" || process.env.NODE_ENV === "production" ? false : void 0, // disable HMR for test // handle Vite URLs proxy: { // add proxies here }, watch: { // Prevent watching during the build to speed it up ignored: mode === "build" ? ["**"] : void 0 } }, resolve: { alias: [ { // This is needed for Deno compatibility, as the non-browser version // of this module depends on Node `crypto` find: "randombytes", replacement: "randombytes/browser" }, { // Typings are imported from 'astro' (e.g. import { Type } from 'astro') find: /^astro$/, replacement: fileURLToPath(new URL("../@types/astro", import.meta.url)) } ], conditions: ["astro"], // Astro imports in third-party packages should use the same version as root dedupe: ["astro"] }, ssr: { noExternal: [...ALWAYS_NOEXTERNAL, ...astroPkgsConfig.ssr.noExternal], external: [...mode === "dev" ? ONLY_DEV_EXTERNAL : [], ...astroPkgsConfig.ssr.external] } }; const assetsPrefix = settings.config.build.assetsPrefix; if (assetsPrefix) { commonConfig.experimental = { renderBuiltUrl(filename, { type }) { if (type === "asset") { return joinPaths(assetsPrefix, filename); } } }; } let result = commonConfig; if (command && ((_b = settings.config.vite) == null ? void 0 : _b.plugins)) { let { plugins, ...rest } = settings.config.vite; const applyToFilter = command === "build" ? "serve" : "build"; const applyArgs = [ { ...settings.config.vite, mode }, { command: command === "dev" ? "serve" : command, mode } ]; plugins = plugins.flat(Infinity).filter((p) => { if (!p || (p == null ? void 0 : p.apply) === applyToFilter) { return false; } if (typeof p.apply === "function") { return p.apply(applyArgs[0], applyArgs[1]); } return true; }); result = vite.mergeConfig(result, { ...rest, plugins }); } else { result = vite.mergeConfig(result, settings.config.vite || {}); } result = vite.mergeConfig(result, commandConfig); if (result.plugins) { sortPlugins(result.plugins); } result.customLogger = vite.createLogger(result.logLevel ?? "warn"); return result; } function isVitePlugin(plugin) { return Boolean(plugin == null ? void 0 : plugin.hasOwnProperty("name")); } function findPluginIndexByName(pluginOptions, name) { return pluginOptions.findIndex(function(pluginOption) { return isVitePlugin(pluginOption) && pluginOption.name === name; }); } function sortPlugins(pluginOptions) { const mdxPluginIndex = findPluginIndexByName(pluginOptions, "@mdx-js/rollup"); if (mdxPluginIndex === -1) return; const jsxPluginIndex = findPluginIndexByName(pluginOptions, "astro:jsx"); const mdxPlugin = pluginOptions[mdxPluginIndex]; pluginOptions.splice(mdxPluginIndex, 1); pluginOptions.splice(jsxPluginIndex, 0, mdxPlugin); } const COMMON_DEPENDENCIES_NOT_ASTRO = [ "autoprefixer", "react", "react-dom", "preact", "preact-render-to-string", "vue", "svelte", "solid-js", "lit", "cookie", "dotenv", "esbuild", "eslint", "jest", "postcss", "prettier", "astro", "tslib", "typescript", "vite" ]; const COMMON_PREFIXES_NOT_ASTRO = [ "@webcomponents/", "@fontsource/", "@postcss-plugins/", "@rollup/", "@astrojs/renderer-", "@types/", "@typescript-eslint/", "eslint-", "jest-", "postcss-plugin-", "prettier-plugin-", "remark-", "rehype-", "rollup-plugin-", "vite-plugin-" ]; function isCommonNotAstro(dep) { return COMMON_DEPENDENCIES_NOT_ASTRO.includes(dep) || COMMON_PREFIXES_NOT_ASTRO.some( (prefix) => prefix.startsWith("@") ? dep.startsWith(prefix) : dep.substring(dep.lastIndexOf("/") + 1).startsWith(prefix) // check prefix omitting @scope/ ); } export { createVite };