254 lines
9.4 KiB
JavaScript
254 lines
9.4 KiB
JavaScript
![]() |
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 `<Code/>` which is processed by Vite
|
||
|
"shiki",
|
||
|
// Imported by `@astrojs/prism` which exposes `<Prism/>` 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
|
||
|
};
|