astro 7.0.0-alpha.1 → 7.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/components/Code.astro +1 -1
  2. package/dist/assets/endpoint/dev.js +1 -1
  3. package/dist/assets/endpoint/generic.js +7 -16
  4. package/dist/assets/endpoint/loadImage.d.ts +11 -0
  5. package/dist/assets/endpoint/loadImage.js +19 -0
  6. package/dist/assets/fonts/config.d.ts +4 -4
  7. package/dist/assets/fonts/core/optimize-fallbacks.js +38 -13
  8. package/dist/assets/fonts/definitions.d.ts +2 -2
  9. package/dist/assets/fonts/infra/system-fallbacks-provider.d.ts +2 -2
  10. package/dist/assets/fonts/infra/system-fallbacks-provider.js +46 -9
  11. package/dist/assets/fonts/types.d.ts +1 -0
  12. package/dist/assets/internal.js +20 -16
  13. package/dist/assets/services/service.d.ts +1 -1
  14. package/dist/assets/services/service.js +9 -9
  15. package/dist/assets/services/sharp.js +48 -28
  16. package/dist/assets/utils/generateImageStylesCSS.js +26 -6
  17. package/dist/assets/utils/inferSourceFormat.d.ts +8 -3
  18. package/dist/assets/utils/inferSourceFormat.js +15 -4
  19. package/dist/assets/utils/metadata.js +1 -1
  20. package/dist/assets/utils/vendor/image-size/types/svg.js +1 -1
  21. package/dist/cli/dev/background.d.ts +16 -0
  22. package/dist/cli/dev/background.js +116 -0
  23. package/dist/cli/dev/index.js +82 -3
  24. package/dist/cli/dev/logs.d.ts +6 -0
  25. package/dist/cli/dev/logs.js +72 -0
  26. package/dist/cli/dev/status.d.ts +15 -0
  27. package/dist/cli/dev/status.js +27 -0
  28. package/dist/cli/dev/stop.d.ts +12 -0
  29. package/dist/cli/dev/stop.js +43 -0
  30. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  31. package/dist/content/content-layer.js +16 -10
  32. package/dist/content/data-store.d.ts +1 -1
  33. package/dist/content/runtime-assets.d.ts +2 -2
  34. package/dist/content/runtime.d.ts +1 -1
  35. package/dist/content/runtime.js +9 -4
  36. package/dist/content/types-generator.js +5 -1
  37. package/dist/content/utils.d.ts +1 -1
  38. package/dist/content/utils.js +1 -1
  39. package/dist/core/app/base.d.ts +9 -0
  40. package/dist/core/app/base.js +47 -67
  41. package/dist/core/app/entrypoints/node.d.ts +1 -1
  42. package/dist/core/app/entrypoints/node.js +2 -0
  43. package/dist/core/app/node.d.ts +16 -0
  44. package/dist/core/app/node.js +59 -13
  45. package/dist/core/base-pipeline.d.ts +10 -0
  46. package/dist/core/base-pipeline.js +13 -1
  47. package/dist/core/build/generate.js +8 -1
  48. package/dist/core/build/index.d.ts +0 -11
  49. package/dist/core/build/index.js +0 -3
  50. package/dist/core/build/internal.d.ts +7 -0
  51. package/dist/core/build/plugins/plugin-chunk-imports.d.ts +6 -0
  52. package/dist/core/build/plugins/plugin-chunk-imports.js +29 -17
  53. package/dist/core/build/plugins/plugin-css.js +33 -0
  54. package/dist/core/build/plugins/plugin-internals.js +1 -1
  55. package/dist/core/build/static-build.js +22 -155
  56. package/dist/core/build/types.d.ts +0 -1
  57. package/dist/core/build/util.js +8 -1
  58. package/dist/core/build/vite-build-config.d.ts +28 -0
  59. package/dist/core/build/vite-build-config.js +165 -0
  60. package/dist/core/config/merge.js +4 -0
  61. package/dist/core/config/schemas/base.d.ts +19 -11
  62. package/dist/core/config/schemas/base.js +29 -4
  63. package/dist/core/config/schemas/relative.d.ts +69 -45
  64. package/dist/core/config/validate.js +59 -0
  65. package/dist/core/constants.js +1 -1
  66. package/dist/core/create-vite.js +3 -1
  67. package/dist/core/csp/config.js +17 -5
  68. package/dist/core/dev/dev.d.ts +1 -0
  69. package/dist/core/dev/dev.js +4 -1
  70. package/dist/core/dev/lockfile.d.ts +54 -0
  71. package/dist/core/dev/lockfile.js +93 -0
  72. package/dist/core/errors/errors-data.d.ts +43 -38
  73. package/dist/core/errors/errors-data.js +79 -73
  74. package/dist/core/errors/zod-error-map.js +3 -1
  75. package/dist/core/fetch/fetch-state.d.ts +12 -26
  76. package/dist/core/fetch/fetch-state.js +137 -20
  77. package/dist/core/fetch/types.d.ts +19 -0
  78. package/dist/core/fetch/vite-plugin.js +11 -4
  79. package/dist/core/hono/index.d.ts +1 -1
  80. package/dist/core/hono/index.js +6 -3
  81. package/dist/core/i18n/domain.d.ts +12 -0
  82. package/dist/core/i18n/domain.js +66 -0
  83. package/dist/core/i18n/handler.js +3 -0
  84. package/dist/core/logger/core.d.ts +1 -1
  85. package/dist/core/logger/core.js +1 -1
  86. package/dist/core/messages/runtime.js +1 -1
  87. package/dist/core/middleware/astro-middleware.js +3 -5
  88. package/dist/core/module-loader/vite.js +1 -2
  89. package/dist/core/pages/handler.js +1 -0
  90. package/dist/core/preview/index.js +6 -5
  91. package/dist/core/preview/static-preview-server.js +5 -2
  92. package/dist/core/render/params-and-props.js +1 -1
  93. package/dist/core/render/route-cache.d.ts +1 -0
  94. package/dist/core/render/route-cache.js +4 -4
  95. package/dist/core/routing/create-manifest.js +11 -1
  96. package/dist/core/routing/handler.js +5 -6
  97. package/dist/core/routing/parse-route.js +1 -1
  98. package/dist/core/routing/rewrite.js +1 -1
  99. package/dist/core/routing/router.d.ts +8 -0
  100. package/dist/core/routing/router.js +28 -0
  101. package/dist/core/routing/validation.js +1 -1
  102. package/dist/core/server-islands/vite-plugin-server-islands.d.ts +6 -1
  103. package/dist/core/server-islands/vite-plugin-server-islands.js +13 -3
  104. package/dist/core/session/config.d.ts +1 -1
  105. package/dist/core/util/normalized-url.js +5 -2
  106. package/dist/core/util/pathname.d.ts +10 -1
  107. package/dist/core/util/pathname.js +13 -4
  108. package/dist/environments.js +1 -1
  109. package/dist/events/session.d.ts +8 -0
  110. package/dist/events/session.js +11 -0
  111. package/dist/jsx/rehype.d.ts +1 -1
  112. package/dist/manifest/virtual-module.js +3 -1
  113. package/dist/markdown/index.d.ts +4 -0
  114. package/dist/markdown/index.js +14 -0
  115. package/dist/prerender/utils.js +5 -1
  116. package/dist/runtime/client/dev-toolbar/apps/audit/rules/a11y.js +9 -0
  117. package/dist/runtime/server/jsx.js +1 -1
  118. package/dist/runtime/server/render/component.js +8 -6
  119. package/dist/runtime/server/render/head.js +1 -5
  120. package/dist/runtime/server/render/util.js +2 -2
  121. package/dist/runtime/server/transition.d.ts +1 -6
  122. package/dist/runtime/server/transition.js +0 -8
  123. package/dist/transitions/events.d.ts +0 -14
  124. package/dist/transitions/events.js +0 -14
  125. package/dist/transitions/index.d.ts +0 -1
  126. package/dist/transitions/index.js +0 -2
  127. package/dist/transitions/vite-plugin-transitions.js +2 -4
  128. package/dist/types/public/config.d.ts +66 -18
  129. package/dist/types/public/content.d.ts +1 -1
  130. package/dist/types/public/index.d.ts +2 -1
  131. package/dist/types/public/integrations.d.ts +11 -3
  132. package/dist/types/public/manifest.d.ts +1 -1
  133. package/dist/virtual-modules/i18n.d.ts +2 -2
  134. package/dist/virtual-modules/i18n.js +1 -1
  135. package/dist/vite-plugin-app/app.d.ts +9 -1
  136. package/dist/vite-plugin-app/app.js +31 -21
  137. package/dist/vite-plugin-app/createAstroServerApp.d.ts +3 -1
  138. package/dist/vite-plugin-app/createAstroServerApp.js +4 -3
  139. package/dist/vite-plugin-astro-server/plugin.js +11 -5
  140. package/dist/vite-plugin-astro-server/route-guard.d.ts +33 -0
  141. package/dist/vite-plugin-astro-server/route-guard.js +42 -23
  142. package/dist/vite-plugin-dev-status/index.d.ts +2 -0
  143. package/dist/vite-plugin-dev-status/index.js +15 -0
  144. package/dist/vite-plugin-hmr-reload/index.d.ts +1 -1
  145. package/dist/vite-plugin-hmr-reload/index.js +23 -1
  146. package/dist/vite-plugin-integrations-container/index.js +15 -6
  147. package/dist/vite-plugin-markdown/content-entry-type.js +7 -4
  148. package/dist/vite-plugin-markdown/images.js +9 -11
  149. package/dist/vite-plugin-markdown/index.js +12 -11
  150. package/dist/vite-plugin-utils/index.js +7 -1
  151. package/package.json +13 -13
  152. package/templates/content/types.d.ts +1 -0
  153. package/types/transitions.d.ts +0 -7
@@ -10,31 +10,23 @@ import { emptyDir, removeEmptyDirs } from "../../core/fs/index.js";
10
10
  import { appendForwardSlash, prependForwardSlash } from "../../core/path.js";
11
11
  import { runHookBuildSetup } from "../../integrations/hooks.js";
12
12
  import { SERIALIZED_MANIFEST_RESOLVED_ID } from "../../manifest/serialized.js";
13
- import {
14
- getClientOutputDirectory,
15
- getPrerenderOutputDirectory,
16
- getServerOutputDirectory
17
- } from "../../prerender/utils.js";
18
- import { VIRTUAL_PAGE_RESOLVED_MODULE_ID } from "../../vite-plugin-pages/const.js";
13
+ import { getPrerenderOutputDirectory, getServerOutputDirectory } from "../../prerender/utils.js";
19
14
  import { PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
20
15
  import { routeIsRedirect } from "../routing/helpers.js";
21
- import { getOutDirWithinCwd } from "./common.js";
22
- import { CHUNKS_PATH } from "./consts.js";
23
16
  import { generatePages } from "./generate.js";
24
17
  import { trackPageData } from "./internal.js";
25
18
  import { getAllBuildPlugins } from "./plugins/index.js";
26
19
  import { manifestBuildPostHook } from "./plugins/plugin-manifest.js";
27
- import {
28
- isLegacyAdapter,
29
- LEGACY_SSR_ENTRY_VIRTUAL_MODULE,
30
- RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE
31
- } from "./plugins/plugin-ssr.js";
32
20
  import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
33
- import { cleanChunkName, getTimeStat, viteBuildReturnToRolldownOutputs } from "./util.js";
21
+ import { getTimeStat, viteBuildReturnToRolldownOutputs } from "./util.js";
34
22
  import { NOOP_MODULE_ID } from "./plugins/plugin-noop.js";
35
23
  import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";
36
24
  import { getSSRAssets } from "./internal.js";
37
- import { SERVER_ISLAND_MAP_MARKER } from "../server-islands/vite-plugin-server-islands.js";
25
+ import {
26
+ SERVER_ISLAND_MAP_MARKER,
27
+ hasServerIslands
28
+ } from "../server-islands/vite-plugin-server-islands.js";
29
+ import { createViteBuildConfig } from "./vite-build-config.js";
38
30
  const PRERENDER_ENTRY_FILENAME_PREFIX = "prerender-entry";
39
31
  function extractRelevantChunks(outputs, prerender) {
40
32
  const extracted = [];
@@ -83,7 +75,6 @@ async function viteBuild(opts) {
83
75
  async function buildEnvironments(opts, internals) {
84
76
  const { allPages, settings, viteConfig } = opts;
85
77
  const routes = Object.values(allPages).flatMap((pageData) => pageData.route);
86
- const legacyAdapter = !settings.adapter || isLegacyAdapter(settings.adapter);
87
78
  const buildPlugins = getAllBuildPlugins(internals, opts);
88
79
  const flatPlugins = buildPlugins.flat().filter(Boolean);
89
80
  const plugins = [...flatPlugins, ...viteConfig.plugins || []];
@@ -149,76 +140,10 @@ async function buildEnvironments(opts, internals) {
149
140
  return Object.keys(currentRolldownInput).includes(moduleName);
150
141
  }
151
142
  }
152
- const viteBuildConfig = {
153
- ...viteConfig,
154
- logLevel: viteConfig.logLevel ?? "error",
155
- build: {
156
- target: "esnext",
157
- // Vite defaults cssMinify to false in SSR by default, but we want to minify it
158
- // as the CSS generated are used and served to the client.
159
- cssMinify: viteConfig.build?.minify == null ? true : !!viteConfig.build?.minify,
160
- ...viteConfig.build,
161
- emptyOutDir: false,
162
- copyPublicDir: false,
163
- manifest: false,
164
- rolldownOptions: {
165
- ...viteConfig.build?.rolldownOptions,
166
- // Setting as `exports-only` allows us to safely delete inputs that are only used during prerendering
167
- preserveEntrySignatures: "exports-only",
168
- ...legacyAdapter && settings.buildOutput === "server" ? { input: LEGACY_SSR_ENTRY_VIRTUAL_MODULE } : {},
169
- output: {
170
- hoistTransitiveImports: false,
171
- format: "esm",
172
- minifyInternalExports: true,
173
- // Server chunks can't go in the assets (_astro) folder
174
- // We need to keep these separate
175
- chunkFileNames(chunkInfo) {
176
- const { name } = chunkInfo;
177
- let prefix = CHUNKS_PATH;
178
- let suffix = "_[hash].mjs";
179
- if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
180
- const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
181
- return [prefix, cleanChunkName(sanitizedName), suffix].join("");
182
- }
183
- if (name.startsWith("pages/")) {
184
- const sanitizedName = name.split(".")[0];
185
- return [prefix, cleanChunkName(sanitizedName), suffix].join("");
186
- }
187
- return [prefix, cleanChunkName(name), suffix].join("");
188
- },
189
- assetFileNames(assetInfo) {
190
- const name = assetInfo.names?.[0] ?? "";
191
- if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
192
- const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
193
- return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
194
- }
195
- return `${settings.config.build.assets}/[name].[hash][extname]`;
196
- },
197
- ...viteConfig.build?.rolldownOptions?.output,
198
- entryFileNames(chunkInfo) {
199
- if (chunkInfo.facadeModuleId?.startsWith(VIRTUAL_PAGE_RESOLVED_MODULE_ID)) {
200
- return makeAstroPageEntryPointFileName(
201
- VIRTUAL_PAGE_RESOLVED_MODULE_ID,
202
- chunkInfo.facadeModuleId,
203
- routes
204
- );
205
- } else if (chunkInfo.facadeModuleId === RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE || // This catches the case when the adapter uses `entrypointResolution: 'auto'`. When doing so,
206
- // the adapter must set rolldownOptions.input or Astro sets it from `serverEntrypoint`.
207
- isRolldownInput(chunkInfo.name) || isRolldownInput(chunkInfo.facadeModuleId)) {
208
- return opts.settings.config.build.serverEntry;
209
- } else {
210
- return "[name].mjs";
211
- }
212
- }
213
- }
214
- },
215
- ssr: true,
216
- ssrEmitAssets: true,
217
- // improve build performance
218
- minify: false,
219
- modulePreload: { polyfill: false },
220
- reportCompressedSize: false
221
- },
143
+ const viteBuildConfig = createViteBuildConfig({
144
+ settings,
145
+ viteConfig,
146
+ routes,
222
147
  plugins,
223
148
  // Top-level buildApp for framework build orchestration
224
149
  // This takes precedence over platform plugin fallbacks (e.g., Cloudflare)
@@ -232,7 +157,7 @@ async function buildEnvironments(opts, internals) {
232
157
  const prerenderChunks = extractRelevantChunks(prerenderOutputs, true);
233
158
  prerenderOutput = void 0;
234
159
  let ssrChunks = [];
235
- if (settings.buildOutput !== "static") {
160
+ if (needsServerBuild(settings, builder2)) {
236
161
  settings.timer.start("SSR build");
237
162
  let ssrOutput = await builder2.build(
238
163
  builder2.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]
@@ -251,76 +176,15 @@ async function buildEnvironments(opts, internals) {
251
176
  internals.clientInput.add(NOOP_MODULE_ID);
252
177
  }
253
178
  const sortedClientInput = Array.from(internals.clientInput).sort();
254
- builder2.environments.client.config.build.rollupOptions.input = sortedClientInput;
179
+ builder2.environments.client.config.build.rolldownOptions.input = sortedClientInput;
255
180
  settings.timer.start("Client build");
256
181
  await builder2.build(builder2.environments.client);
257
182
  settings.timer.end("Client build");
258
183
  internals.extractedChunks = [...ssrChunks, ...prerenderChunks];
259
184
  }
260
185
  },
261
- envPrefix: viteConfig.envPrefix ?? "PUBLIC_",
262
- base: settings.config.base,
263
- environments: {
264
- ...viteConfig.environments ?? {},
265
- [ASTRO_VITE_ENVIRONMENT_NAMES.prerender]: {
266
- build: {
267
- emitAssets: true,
268
- outDir: fileURLToPath(getPrerenderOutputDirectory(settings)),
269
- rolldownOptions: {
270
- // Only skip the default prerender entrypoint if an adapter with `entrypointResolution: 'self'` is used
271
- // AND provides a custom prerenderer. Otherwise, use the default.
272
- ...!legacyAdapter && settings.prerenderer ? {} : { input: "astro/entrypoints/prerender" },
273
- output: {
274
- entryFileNames: `${PRERENDER_ENTRY_FILENAME_PREFIX}.[hash].mjs`,
275
- format: "esm",
276
- ...viteConfig.environments?.prerender?.build?.rolldownOptions?.output
277
- }
278
- },
279
- ssr: true
280
- }
281
- },
282
- [ASTRO_VITE_ENVIRONMENT_NAMES.client]: {
283
- build: {
284
- emitAssets: true,
285
- target: "esnext",
286
- outDir: fileURLToPath(getClientOutputDirectory(settings)),
287
- copyPublicDir: true,
288
- sourcemap: viteConfig.environments?.client?.build?.sourcemap ?? false,
289
- minify: true,
290
- rolldownOptions: {
291
- preserveEntrySignatures: "exports-only",
292
- output: {
293
- entryFileNames(chunkInfo) {
294
- return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
295
- },
296
- chunkFileNames(chunkInfo) {
297
- return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
298
- },
299
- assetFileNames(assetInfo) {
300
- const name = assetInfo.names?.[0] ?? "";
301
- if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
302
- const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
303
- return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
304
- }
305
- return `${settings.config.build.assets}/[name].[hash][extname]`;
306
- },
307
- ...viteConfig.environments?.client?.build?.rolldownOptions?.output
308
- }
309
- }
310
- }
311
- },
312
- [ASTRO_VITE_ENVIRONMENT_NAMES.ssr]: {
313
- build: {
314
- outDir: fileURLToPath(getServerOutputDirectory(settings)),
315
- rolldownOptions: {
316
- output: {
317
- ...viteConfig.environments?.ssr?.build?.rolldownOptions?.output
318
- }
319
- }
320
- }
321
- }
322
- }
323
- };
186
+ isRolldownInput
187
+ });
324
188
  const updatedViteBuildConfig = await runHookBuildSetup({
325
189
  config: settings.config,
326
190
  pages: internals.pagesByKeys,
@@ -369,15 +233,12 @@ async function runManifestInjection(opts, internals, chunks, buildPostHooks) {
369
233
  }
370
234
  async function writeMutatedChunks(opts, mutations) {
371
235
  const { settings } = opts;
372
- const config = settings.config;
373
236
  for (const [fileName, mutation] of mutations) {
374
237
  let root;
375
238
  if (mutation.prerender) {
376
239
  root = getPrerenderOutputDirectory(settings);
377
- } else if (settings.buildOutput === "server") {
378
- root = config.build.server;
379
240
  } else {
380
- root = getOutDirWithinCwd(config.outDir);
241
+ root = getServerOutputDirectory(settings);
381
242
  }
382
243
  const fullPath = path.join(fileURLToPath(root), fileName);
383
244
  const fileURL = pathToFileURL(fullPath);
@@ -435,6 +296,12 @@ function getClientInput(internals, settings) {
435
296
  }
436
297
  return clientInput;
437
298
  }
299
+ function needsServerBuild(settings, builder) {
300
+ if (settings.buildOutput === "server") {
301
+ return true;
302
+ }
303
+ return hasServerIslands(builder.environments.prerender);
304
+ }
438
305
  function makeAstroPageEntryPointFileName(prefix, facadeModuleId, routes) {
439
306
  const pageModuleId = facadeModuleId.replace(prefix, "").replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".");
440
307
  const route = routes.find((routeData) => routeData.component === pageModuleId);
@@ -37,7 +37,6 @@ export interface StaticBuildOptions {
37
37
  origin: string;
38
38
  pageNames: string[];
39
39
  viteConfig: InlineConfig;
40
- teardownCompiler: boolean;
41
40
  key: Promise<CryptoKey>;
42
41
  }
43
42
  type ImportComponentInstance = () => Promise<ComponentInstance>;
@@ -1,6 +1,13 @@
1
1
  function getTimeStat(timeStart, timeEnd) {
2
2
  const buildTime = timeEnd - timeStart;
3
- return buildTime < 1e3 ? `${Math.round(buildTime)}ms` : `${(buildTime / 1e3).toFixed(2)}s`;
3
+ if (buildTime < 1e3) {
4
+ return `${Math.round(buildTime)}ms`;
5
+ } else if (buildTime < 6e4) {
6
+ return `${(buildTime / 1e3).toFixed(2)}s`;
7
+ }
8
+ const mins = Math.floor(buildTime / 6e4);
9
+ const secs = Math.round(buildTime % 6e4 / 1e3);
10
+ return `${mins}m ${secs}s`;
4
11
  }
5
12
  function shouldAppendForwardSlash(trailingSlash, buildFormat) {
6
13
  switch (trailingSlash) {
@@ -0,0 +1,28 @@
1
+ import type * as vite from 'vite';
2
+ import type { RouteData } from '../../types/public/internal.js';
3
+ import type { AstroSettings } from '../../types/astro.js';
4
+ export interface CreateViteBuildConfigOptions {
5
+ /** The resolved Astro settings. */
6
+ settings: AstroSettings;
7
+ /** The base Vite config produced by createVite(). */
8
+ viteConfig: vite.InlineConfig;
9
+ /** All routes to be built. */
10
+ routes: RouteData[];
11
+ /** Assembled Vite plugins (build plugins + user plugins). */
12
+ plugins: vite.PluginOption[];
13
+ /** The buildApp callback for the Vite builder. */
14
+ builder: vite.BuilderOptions;
15
+ /**
16
+ * A function that checks whether a given module name is a rollup input.
17
+ * Used by entryFileNames to determine the server entry.
18
+ */
19
+ isRolldownInput: (moduleName: string | undefined) => boolean;
20
+ }
21
+ /**
22
+ * Creates the Vite InlineConfig used for the multi-environment build.
23
+ *
24
+ * This is a pure config assembly function — it does not execute the build.
25
+ * Extracted from `buildEnvironments()` to enable unit testing of config
26
+ * merging behavior (e.g. user rollup output overrides).
27
+ */
28
+ export declare function createViteBuildConfig(opts: CreateViteBuildConfigOptions): vite.InlineConfig;
@@ -0,0 +1,165 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import {
3
+ getClientOutputDirectory,
4
+ getPrerenderOutputDirectory,
5
+ getServerOutputDirectory
6
+ } from "../../prerender/utils.js";
7
+ import { VIRTUAL_PAGE_RESOLVED_MODULE_ID } from "../../vite-plugin-pages/const.js";
8
+ import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";
9
+ import { CHUNKS_PATH } from "./consts.js";
10
+ import {
11
+ isLegacyAdapter,
12
+ LEGACY_SSR_ENTRY_VIRTUAL_MODULE,
13
+ RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE
14
+ } from "./plugins/plugin-ssr.js";
15
+ import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
16
+ import { cleanChunkName } from "./util.js";
17
+ import { makeAstroPageEntryPointFileName } from "./static-build.js";
18
+ const PRERENDER_ENTRY_FILENAME_PREFIX = "prerender-entry";
19
+ function createViteBuildConfig(opts) {
20
+ const { settings, viteConfig, routes, plugins, builder, isRolldownInput } = opts;
21
+ const legacyAdapter = !settings.adapter || isLegacyAdapter(settings.adapter);
22
+ return {
23
+ ...viteConfig,
24
+ logLevel: viteConfig.logLevel ?? "error",
25
+ build: {
26
+ target: "esnext",
27
+ // Vite defaults cssMinify to false in SSR by default, but we want to minify it
28
+ // as the CSS generated are used and served to the client.
29
+ cssMinify: viteConfig.build?.minify == null ? true : !!viteConfig.build?.minify,
30
+ ...viteConfig.build,
31
+ emptyOutDir: false,
32
+ copyPublicDir: false,
33
+ manifest: false,
34
+ rolldownOptions: {
35
+ ...viteConfig.build?.rolldownOptions,
36
+ // Setting as `exports-only` allows us to safely delete inputs that are only used during prerendering
37
+ preserveEntrySignatures: "exports-only",
38
+ ...legacyAdapter && settings.buildOutput === "server" ? { input: LEGACY_SSR_ENTRY_VIRTUAL_MODULE } : {},
39
+ output: {
40
+ hoistTransitiveImports: false,
41
+ format: "esm",
42
+ minifyInternalExports: true,
43
+ // Server chunks can't go in the assets (_astro) folder
44
+ // We need to keep these separate
45
+ chunkFileNames(chunkInfo) {
46
+ const { name } = chunkInfo;
47
+ let prefix = CHUNKS_PATH;
48
+ let suffix = "_[hash].mjs";
49
+ if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
50
+ const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
51
+ return [prefix, cleanChunkName(sanitizedName), suffix].join("");
52
+ }
53
+ if (name.startsWith("pages/")) {
54
+ const sanitizedName = name.split(".")[0];
55
+ return [prefix, cleanChunkName(sanitizedName), suffix].join("");
56
+ }
57
+ return [prefix, cleanChunkName(name), suffix].join("");
58
+ },
59
+ assetFileNames(assetInfo) {
60
+ const name = assetInfo.names?.[0] ?? "";
61
+ if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
62
+ const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
63
+ return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
64
+ }
65
+ return `${settings.config.build.assets}/[name].[hash][extname]`;
66
+ },
67
+ ...viteConfig.build?.rolldownOptions?.output,
68
+ entryFileNames(chunkInfo) {
69
+ if (chunkInfo.facadeModuleId?.startsWith(VIRTUAL_PAGE_RESOLVED_MODULE_ID)) {
70
+ return makeAstroPageEntryPointFileName(
71
+ VIRTUAL_PAGE_RESOLVED_MODULE_ID,
72
+ chunkInfo.facadeModuleId,
73
+ routes
74
+ );
75
+ } else if (chunkInfo.facadeModuleId === RESOLVED_LEGACY_SSR_ENTRY_VIRTUAL_MODULE || // This catches the case when the adapter uses `entrypointResolution: 'auto'`. When doing so,
76
+ // the adapter must set rolldownOptions.input or Astro sets it from `serverEntrypoint`.
77
+ isRolldownInput(chunkInfo.name) || isRolldownInput(chunkInfo.facadeModuleId)) {
78
+ return settings.config.build.serverEntry;
79
+ } else {
80
+ return "[name].mjs";
81
+ }
82
+ }
83
+ }
84
+ },
85
+ ssr: true,
86
+ ssrEmitAssets: true,
87
+ // improve build performance
88
+ minify: false,
89
+ modulePreload: { polyfill: false },
90
+ reportCompressedSize: false
91
+ },
92
+ plugins,
93
+ builder,
94
+ envPrefix: viteConfig.envPrefix ?? "PUBLIC_",
95
+ base: settings.config.base,
96
+ environments: {
97
+ ...viteConfig.environments ?? {},
98
+ [ASTRO_VITE_ENVIRONMENT_NAMES.prerender]: {
99
+ build: {
100
+ emitAssets: true,
101
+ outDir: fileURLToPath(getPrerenderOutputDirectory(settings)),
102
+ rolldownOptions: {
103
+ // Only skip the default prerender entrypoint if an adapter with `entrypointResolution: 'self'` is used
104
+ // AND provides a custom prerenderer. Otherwise, use the default.
105
+ ...!legacyAdapter && settings.prerenderer ? {} : { input: "astro/entrypoints/prerender" },
106
+ output: {
107
+ entryFileNames: `${PRERENDER_ENTRY_FILENAME_PREFIX}.[hash].mjs`,
108
+ format: "esm",
109
+ ...viteConfig.environments?.prerender?.build?.rolldownOptions?.output
110
+ }
111
+ },
112
+ ssr: true
113
+ }
114
+ },
115
+ [ASTRO_VITE_ENVIRONMENT_NAMES.client]: {
116
+ build: {
117
+ emitAssets: true,
118
+ target: "esnext",
119
+ outDir: fileURLToPath(getClientOutputDirectory(settings)),
120
+ copyPublicDir: true,
121
+ sourcemap: viteConfig.environments?.client?.build?.sourcemap ?? viteConfig.build?.sourcemap ?? false,
122
+ minify: viteConfig.environments?.client?.build?.minify ?? viteConfig.build?.minify ?? true,
123
+ rolldownOptions: {
124
+ preserveEntrySignatures: "exports-only",
125
+ output: {
126
+ // Inherit top-level rolldown output options (e.g. compact) as a
127
+ // base, then layer Astro defaults on top so that Astro's
128
+ // naming functions are preserved unless explicitly overridden
129
+ // via the environment-specific config.
130
+ ...viteConfig.build?.rolldownOptions?.output,
131
+ entryFileNames(chunkInfo) {
132
+ return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
133
+ },
134
+ chunkFileNames(chunkInfo) {
135
+ return `${settings.config.build.assets}/${cleanChunkName(chunkInfo.name)}.[hash].js`;
136
+ },
137
+ assetFileNames(assetInfo) {
138
+ const name = assetInfo.names?.[0] ?? "";
139
+ if (name.includes(ASTRO_PAGE_EXTENSION_POST_PATTERN)) {
140
+ const [sanitizedName] = name.split(ASTRO_PAGE_EXTENSION_POST_PATTERN);
141
+ return `${settings.config.build.assets}/${sanitizedName}.[hash][extname]`;
142
+ }
143
+ return `${settings.config.build.assets}/[name].[hash][extname]`;
144
+ },
145
+ ...viteConfig.environments?.client?.build?.rolldownOptions?.output
146
+ }
147
+ }
148
+ }
149
+ },
150
+ [ASTRO_VITE_ENVIRONMENT_NAMES.ssr]: {
151
+ build: {
152
+ outDir: fileURLToPath(getServerOutputDirectory(settings)),
153
+ rolldownOptions: {
154
+ output: {
155
+ ...viteConfig.environments?.ssr?.build?.rolldownOptions?.output
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+ };
162
+ }
163
+ export {
164
+ createViteBuildConfig
165
+ };
@@ -38,6 +38,10 @@ function mergeConfigRecursively(defaults, overrides, rootPath) {
38
38
  merged[key] = value;
39
39
  continue;
40
40
  }
41
+ if (key === "processor" && rootPath === "markdown" && isObject(value) && typeof value.createRenderer === "function") {
42
+ merged[key] = value;
43
+ continue;
44
+ }
41
45
  if (isObject(existing) && isObject(value)) {
42
46
  merged[key] = mergeConfigRecursively(existing, value, rootPath ? `${rootPath}.${key}` : key);
43
47
  continue;
@@ -1,4 +1,4 @@
1
- import type { RehypePlugin as _RehypePlugin, RemarkPlugin as _RemarkPlugin, RemarkRehype as _RemarkRehype, Smartypants as _Smartypants, ShikiConfig } from '@astrojs/markdown-remark';
1
+ import type { RehypePlugin as _RehypePlugin, RemarkPlugin as _RemarkPlugin, RemarkRehype as _RemarkRehype, Smartypants as _Smartypants, ShikiConfig } from '@astrojs/internal-helpers/markdown';
2
2
  import type { OutgoingHttpHeaders } from 'node:http';
3
3
  import * as z from 'zod/v4';
4
4
  import type { ViteUserConfig } from '../../../types/public/config.js';
@@ -57,7 +57,7 @@ export declare const ASTRO_CONFIG_DEFAULTS: {
57
57
  allowedHosts: never[];
58
58
  };
59
59
  integrations: never[];
60
- markdown: Required<import("@astrojs/markdown-remark").AstroMarkdownOptions>;
60
+ markdown: Required<Omit<import("@astrojs/markdown-remark").AstroMarkdownOptions, "image">>;
61
61
  vite: {};
62
62
  legacy: {
63
63
  collectionsBackwardsCompat: false;
@@ -120,8 +120,8 @@ export declare const AstroConfigSchema: z.ZodObject<{
120
120
  redirects: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
121
121
  inlineStylesheets: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
122
122
  never: "never";
123
- auto: "auto";
124
123
  always: "always";
124
+ auto: "auto";
125
125
  }>>>;
126
126
  concurrency: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
127
127
  }, z.core.$strip>>;
@@ -139,10 +139,10 @@ export declare const AstroConfigSchema: z.ZodObject<{
139
139
  prefetch: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
140
140
  prefetchAll: z.ZodOptional<z.ZodBoolean>;
141
141
  defaultStrategy: z.ZodOptional<z.ZodEnum<{
142
- load: "load";
143
142
  tap: "tap";
144
143
  hover: "hover";
145
144
  viewport: "viewport";
145
+ load: "load";
146
146
  }>>;
147
147
  }, z.core.$strip>]>>;
148
148
  image: z.ZodPrefault<z.ZodObject<{
@@ -164,9 +164,9 @@ export declare const AstroConfigSchema: z.ZodObject<{
164
164
  }, z.core.$strip>>>;
165
165
  layout: z.ZodOptional<z.ZodEnum<{
166
166
  fixed: "fixed";
167
- none: "none";
168
167
  constrained: "constrained";
169
168
  "full-width": "full-width";
169
+ none: "none";
170
170
  }>>;
171
171
  objectFit: z.ZodOptional<z.ZodString>;
172
172
  objectPosition: z.ZodOptional<z.ZodString>;
@@ -330,8 +330,14 @@ export declare const AstroConfigSchema: z.ZodObject<{
330
330
  remarkPlugins: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodTuple<[z.ZodString, z.ZodAny], null>, z.ZodCustom<RemarkPlugin, RemarkPlugin>, z.ZodTuple<[z.ZodCustom<RemarkPlugin, RemarkPlugin>, z.ZodAny], null>]>>>;
331
331
  rehypePlugins: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodTuple<[z.ZodString, z.ZodAny], null>, z.ZodCustom<RehypePlugin, RehypePlugin>, z.ZodTuple<[z.ZodCustom<RehypePlugin, RehypePlugin>, z.ZodAny], null>]>>>;
332
332
  remarkRehype: z.ZodDefault<z.ZodCustom<RemarkRehype, RemarkRehype>>;
333
- gfm: z.ZodDefault<z.ZodBoolean>;
334
- smartypants: z.ZodPrefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodBoolean, z.ZodType<Smartypants, unknown, z.core.$ZodTypeInternals<Smartypants, unknown>>]>, z.ZodTransform<false | Smartypants, boolean | Smartypants>>>;
333
+ gfm: z.ZodOptional<z.ZodBoolean>;
334
+ smartypants: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodBoolean, z.ZodType<Smartypants, unknown, z.core.$ZodTypeInternals<Smartypants, unknown>>]>, z.ZodTransform<false | Smartypants, boolean | Smartypants>>>;
335
+ processor: z.ZodDefault<z.ZodObject<{
336
+ name: z.ZodString;
337
+ options: z.ZodDefault<z.ZodCustom<object, object>>;
338
+ createRenderer: z.ZodCustom<(shared: import("@astrojs/markdown-remark").AstroMarkdownOptions) => Promise<import("@astrojs/markdown-remark").MarkdownRenderer>, (shared: import("@astrojs/markdown-remark").AstroMarkdownOptions) => Promise<import("@astrojs/markdown-remark").MarkdownRenderer>>;
339
+ createMdxRenderer: z.ZodOptional<z.ZodCustom<((shared: import("@astrojs/markdown-remark").AstroMarkdownOptions, mdx: import("@astrojs/internal-helpers/markdown").MdxRendererOptions) => Promise<import("@astrojs/internal-helpers/markdown").MdxRenderer>) | undefined, ((shared: import("@astrojs/markdown-remark").AstroMarkdownOptions, mdx: import("@astrojs/internal-helpers/markdown").MdxRendererOptions) => Promise<import("@astrojs/internal-helpers/markdown").MdxRenderer>) | undefined>>;
340
+ }, z.core.$strip>>;
335
341
  }, z.core.$strip>>;
336
342
  vite: z.ZodDefault<z.ZodCustom<ViteUserConfig, ViteUserConfig>>;
337
343
  i18n: z.ZodOptional<z.ZodOptional<z.ZodObject<{
@@ -441,9 +447,9 @@ export declare const AstroConfigSchema: z.ZodObject<{
441
447
  path: z.ZodOptional<z.ZodString>;
442
448
  maxAge: z.ZodOptional<z.ZodNumber>;
443
449
  sameSite: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
450
+ none: "none";
444
451
  strict: "strict";
445
452
  lax: "lax";
446
- none: "none";
447
453
  }>, z.ZodBoolean]>>;
448
454
  secure: z.ZodOptional<z.ZodBoolean>;
449
455
  }, z.core.$strip>, z.ZodPipe<z.ZodString, z.ZodTransform<{
@@ -487,11 +493,11 @@ export declare const AstroConfigSchema: z.ZodObject<{
487
493
  fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
488
494
  optimizedFallbacks: z.ZodOptional<z.ZodBoolean>;
489
495
  display: z.ZodOptional<z.ZodEnum<{
490
- optional: "optional";
491
496
  auto: "auto";
497
+ optional: "optional";
498
+ fallback: "fallback";
492
499
  block: "block";
493
500
  swap: "swap";
494
- fallback: "fallback";
495
501
  }>>;
496
502
  stretch: z.ZodOptional<z.ZodString>;
497
503
  featureSettings: z.ZodOptional<z.ZodString>;
@@ -500,7 +506,9 @@ export declare const AstroConfigSchema: z.ZodObject<{
500
506
  options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
501
507
  }, z.core.$strict>>>;
502
508
  experimental: z.ZodPrefault<z.ZodObject<{
503
- advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
509
+ advancedRouting: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
510
+ fetchFile: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
511
+ }, z.core.$strict>]>>>;
504
512
  clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
505
513
  contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
506
514
  chromeDevtoolsWorkspace: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
@@ -1,4 +1,8 @@
1
- import { markdownConfigDefaults, syntaxHighlightDefaults } from "@astrojs/markdown-remark";
1
+ import {
2
+ markdownConfigDefaults,
3
+ syntaxHighlightDefaults
4
+ } from "@astrojs/internal-helpers/markdown";
5
+ import { unified } from "@astrojs/markdown-remark";
2
6
  import { bundledThemes } from "shiki";
3
7
  import * as z from "zod/v4";
4
8
  import { FontFamilySchema } from "../../../assets/fonts/config.js";
@@ -238,11 +242,27 @@ const AstroConfigSchema = z.object({
238
242
  z.tuple([z.custom((data) => typeof data === "function"), z.any()])
239
243
  ]).array().default(ASTRO_CONFIG_DEFAULTS.markdown.rehypePlugins),
240
244
  remarkRehype: z.custom((data) => data instanceof Object && !Array.isArray(data)).default(ASTRO_CONFIG_DEFAULTS.markdown.remarkRehype),
241
- gfm: z.boolean().default(ASTRO_CONFIG_DEFAULTS.markdown.gfm),
245
+ // Deprecated: left undefined unless the user explicitly sets them, so the
246
+ // deprecation warning only fires when actually used. The active processor
247
+ // (`unified()`) supplies the real default (`gfm`/smart punctuation on) when
248
+ // these are absent.
249
+ gfm: z.boolean().optional(),
242
250
  smartypants: z.union([z.boolean(), smartypantsOptionsSchema]).transform((val) => {
243
251
  if (val === true) return smartypantsOptionsSchema.parse({});
244
252
  return val;
245
- }).prefault(ASTRO_CONFIG_DEFAULTS.markdown.smartypants)
253
+ }).optional(),
254
+ processor: z.object({
255
+ name: z.string(),
256
+ // `z.custom` preserves reference identity; `z.record` would clone, breaking
257
+ // the closure inside `createRenderer` that reads `processor.options.*`.
258
+ options: z.custom((v) => typeof v === "object" && v !== null && !Array.isArray(v)).default(() => ({})),
259
+ createRenderer: z.custom(
260
+ (v) => typeof v === "function"
261
+ ),
262
+ createMdxRenderer: z.custom(
263
+ (v) => v === void 0 || typeof v === "function"
264
+ ).optional()
265
+ }).default(() => unified())
246
266
  }).prefault({}),
247
267
  vite: z.custom((data) => data instanceof Object && !Array.isArray(data)).default(ASTRO_CONFIG_DEFAULTS.vite),
248
268
  i18n: z.optional(
@@ -309,7 +329,12 @@ const AstroConfigSchema = z.object({
309
329
  prerenderConflictBehavior: z.enum(["error", "warn", "ignore"]).optional().default(ASTRO_CONFIG_DEFAULTS.prerenderConflictBehavior),
310
330
  fonts: z.array(FontFamilySchema).optional(),
311
331
  experimental: z.strictObject({
312
- advancedRouting: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.advancedRouting),
332
+ advancedRouting: z.union([
333
+ z.boolean(),
334
+ z.strictObject({
335
+ fetchFile: z.string().nullable().optional().default("app")
336
+ })
337
+ ]).optional().default(ASTRO_CONFIG_DEFAULTS.experimental.advancedRouting),
313
338
  clientPrerender: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.clientPrerender),
314
339
  contentIntellisense: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentIntellisense),
315
340
  chromeDevtoolsWorkspace: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.chromeDevtoolsWorkspace),