astro 2.6.6 → 2.7.1

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 (79) hide show
  1. package/README.md +3 -6
  2. package/dist/@types/astro.d.ts +30 -15
  3. package/dist/assets/utils/emitAsset.js +1 -2
  4. package/dist/content/utils.d.ts +1 -2
  5. package/dist/content/utils.js +3 -4
  6. package/dist/content/vite-plugin-content-imports.js +0 -1
  7. package/dist/content/vite-plugin-content-virtual-mod.d.ts +1 -1
  8. package/dist/content/vite-plugin-content-virtual-mod.js +7 -1
  9. package/dist/core/add/babel.d.ts +8 -2
  10. package/dist/core/app/index.d.ts +3 -4
  11. package/dist/core/app/index.js +21 -14
  12. package/dist/core/app/node.d.ts +1 -1
  13. package/dist/core/app/node.js +9 -5
  14. package/dist/core/app/types.d.ts +5 -5
  15. package/dist/core/build/generate.js +9 -12
  16. package/dist/core/build/index.js +1 -8
  17. package/dist/core/build/internal.d.ts +3 -1
  18. package/dist/core/build/internal.js +5 -6
  19. package/dist/core/build/plugins/index.js +2 -1
  20. package/dist/core/build/plugins/plugin-middleware.js +15 -0
  21. package/dist/core/build/plugins/plugin-pages.d.ts +1 -2
  22. package/dist/core/build/plugins/plugin-pages.js +6 -9
  23. package/dist/core/build/plugins/plugin-ssr.d.ts +13 -2
  24. package/dist/core/build/plugins/plugin-ssr.js +220 -73
  25. package/dist/core/build/plugins/util.d.ts +15 -0
  26. package/dist/core/build/plugins/util.js +17 -1
  27. package/dist/core/build/static-build.d.ts +33 -0
  28. package/dist/core/build/static-build.js +57 -26
  29. package/dist/core/build/types.d.ts +5 -3
  30. package/dist/core/compile/compile.js +0 -5
  31. package/dist/core/compile/style.js +0 -1
  32. package/dist/core/config/schema.d.ts +12 -0
  33. package/dist/core/config/schema.js +6 -3
  34. package/dist/core/config/settings.js +1 -1
  35. package/dist/core/constants.js +1 -1
  36. package/dist/core/dev/dev.js +1 -1
  37. package/dist/core/endpoint/dev/index.js +1 -1
  38. package/dist/core/endpoint/index.d.ts +2 -2
  39. package/dist/core/endpoint/index.js +3 -3
  40. package/dist/core/errors/dev/vite.js +1 -9
  41. package/dist/core/errors/errors-data.d.ts +29 -70
  42. package/dist/core/errors/errors-data.js +20 -75
  43. package/dist/core/errors/errors.d.ts +1 -9
  44. package/dist/core/errors/errors.js +8 -9
  45. package/dist/core/errors/index.d.ts +1 -1
  46. package/dist/core/errors/utils.d.ts +2 -3
  47. package/dist/core/errors/utils.js +3 -3
  48. package/dist/core/messages.js +2 -2
  49. package/dist/core/module-loader/loader.d.ts +4 -0
  50. package/dist/core/redirects/component.js +1 -4
  51. package/dist/core/render/context.d.ts +1 -0
  52. package/dist/core/render/context.js +17 -1
  53. package/dist/core/render/core.d.ts +3 -3
  54. package/dist/core/render/core.js +3 -4
  55. package/dist/core/render/dev/index.js +18 -8
  56. package/dist/core/render/dev/vite.js +25 -19
  57. package/dist/core/render/ssr-element.js +3 -4
  58. package/dist/core/request.d.ts +2 -1
  59. package/dist/core/request.js +3 -2
  60. package/dist/core/routing/manifest/create.js +3 -4
  61. package/dist/core/util.d.ts +1 -0
  62. package/dist/core/util.js +5 -4
  63. package/dist/events/error.d.ts +0 -1
  64. package/dist/events/error.js +1 -5
  65. package/dist/integrations/index.d.ts +6 -7
  66. package/dist/integrations/index.js +8 -11
  67. package/dist/jsx/babel.js +3 -3
  68. package/dist/vite-plugin-astro/compile.js +2 -0
  69. package/dist/vite-plugin-astro-server/route.js +4 -1
  70. package/dist/vite-plugin-jsx/index.js +2 -0
  71. package/dist/vite-plugin-load-fallback/index.js +2 -2
  72. package/dist/vite-plugin-markdown/content-entry-type.d.ts +0 -5
  73. package/dist/vite-plugin-markdown/content-entry-type.js +1 -26
  74. package/dist/vite-plugin-markdown/index.js +0 -2
  75. package/package.json +39 -40
  76. package/dist/content/template/types.d.js +0 -0
  77. package/dist/content/template/virtual-mod.d.mts +0 -7
  78. /package/{src/content/template/virtual-mod.mjs → content-module.template.mjs} +0 -0
  79. /package/{src/content/template/types.d.ts → content-types.template.d.ts} +0 -0
@@ -3,9 +3,9 @@ import { routeIsRedirect } from "../../redirects/index.js";
3
3
  import { addRollupInput } from "../add-rollup-input.js";
4
4
  import { MIDDLEWARE_MODULE_ID } from "./plugin-middleware.js";
5
5
  import { RENDERERS_MODULE_ID } from "./plugin-renderers.js";
6
+ import { ASTRO_PAGE_EXTENSION_POST_PATTERN, getPathFromVirtualModulePageName } from "./util.js";
6
7
  const ASTRO_PAGE_MODULE_ID = "@astro-page:";
7
- const ASTRO_PAGE_RESOLVED_MODULE_ID = "\0@astro-page:";
8
- const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
8
+ const ASTRO_PAGE_RESOLVED_MODULE_ID = "\0" + ASTRO_PAGE_MODULE_ID;
9
9
  function getVirtualModulePageNameFromPath(path) {
10
10
  const extension = extname(path);
11
11
  return `${ASTRO_PAGE_MODULE_ID}${path.replace(
@@ -41,10 +41,8 @@ function vitePluginPages(opts, internals) {
41
41
  if (id.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
42
42
  const imports = [];
43
43
  const exports = [];
44
- const pageName = id.slice(ASTRO_PAGE_RESOLVED_MODULE_ID.length);
45
- const pageData = internals.pagesByComponent.get(
46
- `${pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".")}`
47
- );
44
+ const pageName = getPathFromVirtualModulePageName(ASTRO_PAGE_RESOLVED_MODULE_ID, id);
45
+ const pageData = internals.pagesByComponent.get(pageName);
48
46
  if (pageData) {
49
47
  const resolvedPage = await this.resolve(pageData.moduleSpecifier);
50
48
  if (resolvedPage) {
@@ -54,8 +52,8 @@ function vitePluginPages(opts, internals) {
54
52
  exports.push(`export { renderers };`);
55
53
  const middlewareModule = await this.resolve(MIDDLEWARE_MODULE_ID);
56
54
  if (middlewareModule) {
57
- imports.push(`import * as middleware from "${middlewareModule.id}";`);
58
- exports.push(`export { middleware };`);
55
+ imports.push(`import { onRequest } from "${middlewareModule.id}";`);
56
+ exports.push(`export { onRequest };`);
59
57
  }
60
58
  return `${imports.join("\n")}${exports.join("\n")}`;
61
59
  }
@@ -77,7 +75,6 @@ function pluginPages(opts, internals) {
77
75
  };
78
76
  }
79
77
  export {
80
- ASTRO_PAGE_EXTENSION_POST_PATTERN,
81
78
  ASTRO_PAGE_MODULE_ID,
82
79
  ASTRO_PAGE_RESOLVED_MODULE_ID,
83
80
  getVirtualModulePageIdFromPath,
@@ -1,6 +1,17 @@
1
+ import type { SerializedSSRManifest } from '../../app/types';
1
2
  import { type BuildInternals } from '../internal.js';
2
3
  import type { AstroBuildPlugin } from '../plugin';
3
- import type { StaticBuildOptions } from '../types';
4
+ import type { OutputChunk, StaticBuildOptions } from '../types';
4
5
  export declare const SSR_VIRTUAL_MODULE_ID = "@astrojs-ssr-virtual-entry";
5
- export declare function injectManifest(buildOpts: StaticBuildOptions, internals: BuildInternals): Promise<string>;
6
6
  export declare function pluginSSR(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
7
+ export declare const SPLIT_MODULE_ID = "@astro-page-split:";
8
+ export declare const RESOLVED_SPLIT_MODULE_ID = "\0@astro-page-split:";
9
+ export declare function pluginSSRSplit(options: StaticBuildOptions, internals: BuildInternals): AstroBuildPlugin;
10
+ /**
11
+ * It injects the manifest in the given output rollup chunk. It returns the new emitted code
12
+ * @param buildOpts
13
+ * @param internals
14
+ * @param chunk
15
+ */
16
+ export declare function injectManifest(manifest: SerializedSSRManifest, chunk: Readonly<OutputChunk>): string;
17
+ export declare function createManifest(buildOpts: StaticBuildOptions, internals: BuildInternals): Promise<SerializedSSRManifest>;
@@ -1,5 +1,6 @@
1
1
  import glob from "fast-glob";
2
- import { fileURLToPath } from "url";
2
+ import { join } from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
3
4
  import { runHookBuildSsr } from "../../../integrations/index.js";
4
5
  import { isServerLikeOutput } from "../../../prerender/utils.js";
5
6
  import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../../vite-plugin-scripts/index.js";
@@ -9,15 +10,16 @@ import { serializeRouteData } from "../../routing/index.js";
9
10
  import { addRollupInput } from "../add-rollup-input.js";
10
11
  import { getOutFile, getOutFolder } from "../common.js";
11
12
  import { cssOrder, mergeInlineCss } from "../internal.js";
12
- import { getVirtualModulePageNameFromPath } from "./plugin-pages.js";
13
+ import { ASTRO_PAGE_MODULE_ID } from "./plugin-pages.js";
13
14
  import { RENDERERS_MODULE_ID } from "./plugin-renderers.js";
15
+ import { getPathFromVirtualModulePageName, getVirtualModulePageNameFromPath } from "./util.js";
14
16
  const SSR_VIRTUAL_MODULE_ID = "@astrojs-ssr-virtual-entry";
15
17
  const RESOLVED_SSR_VIRTUAL_MODULE_ID = "\0" + SSR_VIRTUAL_MODULE_ID;
16
18
  const manifestReplace = "@@ASTRO_MANIFEST_REPLACE@@";
17
19
  const replaceExp = new RegExp(`['"](${manifestReplace})['"]`, "g");
18
20
  function vitePluginSSR(internals, adapter, options) {
19
21
  return {
20
- name: "@astrojs/vite-plugin-astro-ssr",
22
+ name: "@astrojs/vite-plugin-astro-ssr-server",
21
23
  enforce: "post",
22
24
  options(opts) {
23
25
  return addRollupInput(opts, [SSR_VIRTUAL_MODULE_ID]);
@@ -42,7 +44,7 @@ function vitePluginSSR(internals, adapter, options) {
42
44
  if (routeIsRedirect(pageData.route)) {
43
45
  continue;
44
46
  }
45
- const virtualModuleName = getVirtualModulePageNameFromPath(path);
47
+ const virtualModuleName = getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path);
46
48
  let module = await this.resolve(virtualModuleName);
47
49
  if (module) {
48
50
  const variable = `_page${i}`;
@@ -56,32 +58,10 @@ function vitePluginSSR(internals, adapter, options) {
56
58
  }
57
59
  contents.push(`const pageMap = new Map([${pageMap.join(",")}]);`);
58
60
  exports.push(`export { pageMap }`);
59
- const content = `import * as adapter from '${adapter.serverEntrypoint}';
60
- import { renderers } from '${RENDERERS_MODULE_ID}';
61
- import { deserializeManifest as _deserializeManifest } from 'astro/app';
62
- import { _privateSetManifestDontUseThis } from 'astro:ssr-manifest';
63
- const _manifest = Object.assign(_deserializeManifest('${manifestReplace}'), {
64
- pageMap,
65
- renderers,
66
- });
67
- _privateSetManifestDontUseThis(_manifest);
68
- const _args = ${adapter.args ? JSON.stringify(adapter.args) : "undefined"};
69
-
70
- ${adapter.exports ? `const _exports = adapter.createExports(_manifest, _args);
71
- ${adapter.exports.map((name) => {
72
- if (name === "default") {
73
- return `const _default = _exports['default'];
74
- export { _default as default };`;
75
- } else {
76
- return `export const ${name} = _exports['${name}'];`;
77
- }
78
- }).join("\n")}
79
- ` : ""}
80
- const _start = 'start';
81
- if(_start in adapter) {
82
- adapter[_start](_manifest, _args);
83
- }`;
84
- return `${imports.join("\n")}${contents.join("\n")}${content}${exports.join("\n")}`;
61
+ const ssrCode = generateSSRCode(options.settings.config, adapter);
62
+ imports.push(...ssrCode.imports);
63
+ contents.push(...ssrCode.contents);
64
+ return `${imports.join("\n")}${contents.join("\n")}${exports.join("\n")}`;
85
65
  }
86
66
  return void 0;
87
67
  },
@@ -103,30 +83,220 @@ if(_start in adapter) {
103
83
  }
104
84
  };
105
85
  }
106
- async function injectManifest(buildOpts, internals) {
107
- if (!internals.ssrEntryChunk) {
108
- throw new Error(`Did not generate an entry chunk for SSR`);
86
+ function pluginSSR(options, internals) {
87
+ const ssr = isServerLikeOutput(options.settings.config);
88
+ return {
89
+ build: "ssr",
90
+ hooks: {
91
+ "build:before": () => {
92
+ let vitePlugin = ssr && !options.settings.config.build.split ? vitePluginSSR(internals, options.settings.adapter, options) : void 0;
93
+ return {
94
+ enforce: "after-user-plugins",
95
+ vitePlugin
96
+ };
97
+ },
98
+ "build:post": async ({ mutate }) => {
99
+ if (!ssr) {
100
+ return;
101
+ }
102
+ if (options.settings.config.build.split) {
103
+ return;
104
+ }
105
+ if (!internals.ssrEntryChunk) {
106
+ throw new Error(`Did not generate an entry chunk for SSR`);
107
+ }
108
+ internals.ssrEntryChunk.fileName = options.settings.config.build.serverEntry;
109
+ const manifest = await createManifest(options, internals);
110
+ await runHookBuildSsr({
111
+ config: options.settings.config,
112
+ manifest,
113
+ logging: options.logging,
114
+ entryPoints: internals.entryPoints
115
+ });
116
+ const code = injectManifest(manifest, internals.ssrEntryChunk);
117
+ mutate(internals.ssrEntryChunk, "server", code);
118
+ }
119
+ }
120
+ };
121
+ }
122
+ const SPLIT_MODULE_ID = "@astro-page-split:";
123
+ const RESOLVED_SPLIT_MODULE_ID = "\0@astro-page-split:";
124
+ function vitePluginSSRSplit(internals, adapter, options) {
125
+ return {
126
+ name: "@astrojs/vite-plugin-astro-ssr-split",
127
+ enforce: "post",
128
+ options(opts) {
129
+ if (options.settings.config.build.split) {
130
+ const inputs = /* @__PURE__ */ new Set();
131
+ for (const path of Object.keys(options.allPages)) {
132
+ inputs.add(getVirtualModulePageNameFromPath(SPLIT_MODULE_ID, path));
133
+ }
134
+ return addRollupInput(opts, Array.from(inputs));
135
+ }
136
+ },
137
+ resolveId(id) {
138
+ if (id.startsWith(SPLIT_MODULE_ID)) {
139
+ return "\0" + id;
140
+ }
141
+ },
142
+ async load(id) {
143
+ if (id.startsWith(RESOLVED_SPLIT_MODULE_ID)) {
144
+ const {
145
+ settings: { config },
146
+ allPages
147
+ } = options;
148
+ const imports = [];
149
+ const contents = [];
150
+ const exports = [];
151
+ const path = getPathFromVirtualModulePageName(RESOLVED_SPLIT_MODULE_ID, id);
152
+ const virtualModuleName = getVirtualModulePageNameFromPath(ASTRO_PAGE_MODULE_ID, path);
153
+ let module = await this.resolve(virtualModuleName);
154
+ if (module) {
155
+ imports.push(`import * as pageModule from "${virtualModuleName}";`);
156
+ }
157
+ const ssrCode = generateSSRCode(options.settings.config, adapter);
158
+ imports.push(...ssrCode.imports);
159
+ contents.push(...ssrCode.contents);
160
+ return `${imports.join("\n")}${contents.join("\n")}${exports.join("\n")}`;
161
+ }
162
+ return void 0;
163
+ },
164
+ async generateBundle(_opts, bundle) {
165
+ for (const [_chunkName, chunk] of Object.entries(bundle)) {
166
+ if (chunk.type === "asset") {
167
+ internals.staticFiles.add(chunk.fileName);
168
+ }
169
+ }
170
+ for (const [chunkName, chunk] of Object.entries(bundle)) {
171
+ if (chunk.type === "asset") {
172
+ continue;
173
+ }
174
+ let shouldDeleteBundle = false;
175
+ for (const moduleKey of Object.keys(chunk.modules)) {
176
+ if (moduleKey.startsWith(RESOLVED_SPLIT_MODULE_ID)) {
177
+ internals.ssrSplitEntryChunks.set(moduleKey, chunk);
178
+ storeEntryPoint(moduleKey, options, internals, chunk.fileName);
179
+ shouldDeleteBundle = true;
180
+ }
181
+ }
182
+ if (shouldDeleteBundle) {
183
+ delete bundle[chunkName];
184
+ }
185
+ }
186
+ }
187
+ };
188
+ }
189
+ function pluginSSRSplit(options, internals) {
190
+ const ssr = isServerLikeOutput(options.settings.config);
191
+ return {
192
+ build: "ssr",
193
+ hooks: {
194
+ "build:before": () => {
195
+ let vitePlugin = ssr && options.settings.config.build.split ? vitePluginSSRSplit(internals, options.settings.adapter, options) : void 0;
196
+ return {
197
+ enforce: "after-user-plugins",
198
+ vitePlugin
199
+ };
200
+ },
201
+ "build:post": async ({ mutate }) => {
202
+ if (!ssr) {
203
+ return;
204
+ }
205
+ if (!options.settings.config.build.split) {
206
+ return;
207
+ }
208
+ if (internals.ssrSplitEntryChunks.size === 0) {
209
+ throw new Error(`Did not generate an entry chunk for SSR serverless`);
210
+ }
211
+ const manifest = await createManifest(options, internals);
212
+ await runHookBuildSsr({
213
+ config: options.settings.config,
214
+ manifest,
215
+ logging: options.logging,
216
+ entryPoints: internals.entryPoints
217
+ });
218
+ for (const [moduleName, chunk] of internals.ssrSplitEntryChunks) {
219
+ const code = injectManifest(manifest, chunk);
220
+ mutate(chunk, "server", code);
221
+ }
222
+ }
223
+ }
224
+ };
225
+ }
226
+ function generateSSRCode(config, adapter) {
227
+ const imports = [];
228
+ const contents = [];
229
+ let pageMap;
230
+ if (config.build.split) {
231
+ pageMap = "pageModule";
232
+ } else {
233
+ pageMap = "pageMap";
234
+ }
235
+ contents.push(`import * as adapter from '${adapter.serverEntrypoint}';
236
+ import { renderers } from '${RENDERERS_MODULE_ID}';
237
+ import { deserializeManifest as _deserializeManifest } from 'astro/app';
238
+ import { _privateSetManifestDontUseThis } from 'astro:ssr-manifest';
239
+ const _manifest = Object.assign(_deserializeManifest('${manifestReplace}'), {
240
+ ${pageMap},
241
+ renderers,
242
+ });
243
+ _privateSetManifestDontUseThis(_manifest);
244
+ const _args = ${adapter.args ? JSON.stringify(adapter.args) : "undefined"};
245
+
246
+ ${adapter.exports ? `const _exports = adapter.createExports(_manifest, _args);
247
+ ${adapter.exports.map((name) => {
248
+ if (name === "default") {
249
+ return `const _default = _exports['default'];
250
+ export { _default as default };`;
251
+ } else {
252
+ return `export const ${name} = _exports['${name}'];`;
253
+ }
254
+ }).join("\n")}
255
+ ` : ""}
256
+ const _start = 'start';
257
+ if(_start in adapter) {
258
+ adapter[_start](_manifest, _args);
259
+ }`);
260
+ return {
261
+ imports,
262
+ contents
263
+ };
264
+ }
265
+ function injectManifest(manifest, chunk) {
266
+ const code = chunk.code;
267
+ return code.replace(replaceExp, () => {
268
+ return JSON.stringify(manifest);
269
+ });
270
+ }
271
+ async function createManifest(buildOpts, internals) {
272
+ if (buildOpts.settings.config.build.split) {
273
+ if (internals.ssrSplitEntryChunks.size === 0) {
274
+ throw new Error(`Did not generate an entry chunk for SSR in serverless mode`);
275
+ }
276
+ } else {
277
+ if (!internals.ssrEntryChunk) {
278
+ throw new Error(`Did not generate an entry chunk for SSR`);
279
+ }
109
280
  }
110
281
  const clientStatics = new Set(
111
282
  await glob("**/*", {
112
- cwd: fileURLToPath(buildOpts.buildConfig.client)
283
+ cwd: fileURLToPath(buildOpts.settings.config.build.client)
113
284
  })
114
285
  );
115
286
  for (const file of clientStatics) {
116
287
  internals.staticFiles.add(file);
117
288
  }
118
289
  const staticFiles = internals.staticFiles;
119
- const manifest = buildManifest(buildOpts, internals, Array.from(staticFiles));
120
- await runHookBuildSsr({
121
- config: buildOpts.settings.config,
122
- manifest,
123
- logging: buildOpts.logging
124
- });
125
- const chunk = internals.ssrEntryChunk;
126
- const code = chunk.code;
127
- return code.replace(replaceExp, () => {
128
- return JSON.stringify(manifest);
129
- });
290
+ return buildManifest(buildOpts, internals, Array.from(staticFiles));
291
+ }
292
+ function storeEntryPoint(moduleKey, options, internals, fileName) {
293
+ const componentPath = getPathFromVirtualModulePageName(RESOLVED_SPLIT_MODULE_ID, moduleKey);
294
+ for (const [page, pageData] of Object.entries(options.allPages)) {
295
+ if (componentPath == page) {
296
+ const publicPath = fileURLToPath(options.settings.config.build.server);
297
+ internals.entryPoints.set(pageData.route, pathToFileURL(join(publicPath, fileName)));
298
+ }
299
+ }
130
300
  }
131
301
  function buildManifest(opts, internals, staticFiles) {
132
302
  const { settings } = opts;
@@ -203,7 +373,6 @@ function buildManifest(opts, internals, staticFiles) {
203
373
  base: settings.config.base,
204
374
  assetsPrefix: settings.config.build.assetsPrefix,
205
375
  markdown: settings.config.markdown,
206
- pageMap: null,
207
376
  componentMetadata: Array.from(internals.componentMetadata),
208
377
  renderers: [],
209
378
  clientDirectives: Array.from(settings.clientDirectives),
@@ -212,34 +381,12 @@ function buildManifest(opts, internals, staticFiles) {
212
381
  };
213
382
  return ssrManifest;
214
383
  }
215
- function pluginSSR(options, internals) {
216
- const ssr = isServerLikeOutput(options.settings.config);
217
- return {
218
- build: "ssr",
219
- hooks: {
220
- "build:before": () => {
221
- let vitePlugin = ssr ? vitePluginSSR(internals, options.settings.adapter, options) : void 0;
222
- return {
223
- enforce: "after-user-plugins",
224
- vitePlugin
225
- };
226
- },
227
- "build:post": async ({ mutate }) => {
228
- if (!ssr) {
229
- return;
230
- }
231
- if (!internals.ssrEntryChunk) {
232
- throw new Error(`Did not generate an entry chunk for SSR`);
233
- }
234
- internals.ssrEntryChunk.fileName = options.settings.config.build.serverEntry;
235
- const code = await injectManifest(options, internals);
236
- mutate(internals.ssrEntryChunk, "server", code);
237
- }
238
- }
239
- };
240
- }
241
384
  export {
385
+ RESOLVED_SPLIT_MODULE_ID,
386
+ SPLIT_MODULE_ID,
242
387
  SSR_VIRTUAL_MODULE_ID,
388
+ createManifest,
243
389
  injectManifest,
244
- pluginSSR
390
+ pluginSSR,
391
+ pluginSSRSplit
245
392
  };
@@ -6,4 +6,19 @@ type ExtendManualChunksHooks = {
6
6
  after?: (id: string, meta: any) => string | undefined;
7
7
  };
8
8
  export declare function extendManualChunks(outputOptions: OutputOptions, hooks: ExtendManualChunksHooks): void;
9
+ export declare const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
10
+ /**
11
+ * 1. We add a fixed prefix, which is used as virtual module naming convention;
12
+ * 2. We replace the dot that belongs extension with an arbitrary string.
13
+ *
14
+ * @param virtualModulePrefix
15
+ * @param path
16
+ */
17
+ export declare function getVirtualModulePageNameFromPath(virtualModulePrefix: string, path: string): string;
18
+ /**
19
+ *
20
+ * @param virtualModulePrefix
21
+ * @param id
22
+ */
23
+ export declare function getPathFromVirtualModulePageName(virtualModulePrefix: string, id: string): string;
9
24
  export {};
@@ -1,3 +1,4 @@
1
+ import { extname } from "node:path";
1
2
  function extendManualChunks(outputOptions, hooks) {
2
3
  const manualChunks = outputOptions.manualChunks;
3
4
  outputOptions.manualChunks = function(id, meta) {
@@ -24,6 +25,21 @@ function extendManualChunks(outputOptions, hooks) {
24
25
  return null;
25
26
  };
26
27
  }
28
+ const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
29
+ function getVirtualModulePageNameFromPath(virtualModulePrefix, path) {
30
+ const extension = extname(path);
31
+ return `${virtualModulePrefix}${path.replace(
32
+ extension,
33
+ extension.replace(".", ASTRO_PAGE_EXTENSION_POST_PATTERN)
34
+ )}`;
35
+ }
36
+ function getPathFromVirtualModulePageName(virtualModulePrefix, id) {
37
+ const pageName = id.slice(virtualModulePrefix.length);
38
+ return pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".");
39
+ }
27
40
  export {
28
- extendManualChunks
41
+ ASTRO_PAGE_EXTENSION_POST_PATTERN,
42
+ extendManualChunks,
43
+ getPathFromVirtualModulePageName,
44
+ getVirtualModulePageNameFromPath
29
45
  };
@@ -1,6 +1,39 @@
1
+ import type { RouteData } from '../../@types/astro';
1
2
  import { type BuildInternals } from '../../core/build/internal.js';
2
3
  import type { StaticBuildOptions } from './types';
3
4
  export declare function viteBuild(opts: StaticBuildOptions): Promise<{
4
5
  internals: BuildInternals;
5
6
  }>;
6
7
  export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals): Promise<void>;
8
+ /**
9
+ * This function takes the virtual module name of any page entrypoint and
10
+ * transforms it to generate a final `.mjs` output file.
11
+ *
12
+ * Input: `@astro-page:src/pages/index@_@astro`
13
+ * Output: `pages/index.astro.mjs`
14
+ * Input: `@astro-page:../node_modules/my-dep/injected@_@astro`
15
+ * Output: `pages/injected.mjs`
16
+ *
17
+ * 1. We clean the `facadeModuleId` by removing the `ASTRO_PAGE_MODULE_ID` prefix and `ASTRO_PAGE_EXTENSION_POST_PATTERN`.
18
+ * 2. We find the matching route pattern in the manifest (or fallback to the cleaned module id)
19
+ * 3. We replace square brackets with underscore (`[slug]` => `_slug_`) and `...` with `` (`[...slug]` => `_---slug_`).
20
+ * 4. We append the `.mjs` extension, so the file will always be an ESM module
21
+ *
22
+ * @param prefix string
23
+ * @param facadeModuleId string
24
+ * @param pages AllPagesData
25
+ */
26
+ export declare function makeAstroPageEntryPointFileName(prefix: string, facadeModuleId: string, routes: RouteData[]): string;
27
+ /**
28
+ * The `facadeModuleId` has a shape like: \0@astro-serverless-page:src/pages/index@_@astro.
29
+ *
30
+ * 1. We call `makeAstroPageEntryPointFileName` which normalise its name, making it like a file path
31
+ * 2. We split the file path using the file system separator and attempt to retrieve the last entry
32
+ * 3. The last entry should be the file
33
+ * 4. We prepend the file name with `entry.`
34
+ * 5. We built the file path again, using the new entry built in the previous step
35
+ *
36
+ * @param facadeModuleId
37
+ * @param opts
38
+ */
39
+ export declare function makeSplitEntryPointFileName(facadeModuleId: string, routes: RouteData[]): string;
@@ -3,6 +3,7 @@ import * as eslexer from "es-module-lexer";
3
3
  import glob from "fast-glob";
4
4
  import fs from "fs";
5
5
  import { bgGreen, bgMagenta, black, dim } from "kleur/colors";
6
+ import { extname } from "node:path";
6
7
  import path from "path";
7
8
  import { fileURLToPath } from "url";
8
9
  import * as vite from "vite";
@@ -23,12 +24,11 @@ import { generatePages } from "./generate.js";
23
24
  import { trackPageData } from "./internal.js";
24
25
  import { createPluginContainer } from "./plugin.js";
25
26
  import { registerAllPlugins } from "./plugins/index.js";
26
- import {
27
- ASTRO_PAGE_EXTENSION_POST_PATTERN,
28
- ASTRO_PAGE_RESOLVED_MODULE_ID
29
- } from "./plugins/plugin-pages.js";
27
+ import { MIDDLEWARE_MODULE_ID } from "./plugins/plugin-middleware.js";
28
+ import { ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugins/plugin-pages.js";
30
29
  import { RESOLVED_RENDERERS_MODULE_ID } from "./plugins/plugin-renderers.js";
31
- import { SSR_VIRTUAL_MODULE_ID } from "./plugins/plugin-ssr.js";
30
+ import { RESOLVED_SPLIT_MODULE_ID, SSR_VIRTUAL_MODULE_ID } from "./plugins/plugin-ssr.js";
31
+ import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
32
32
  import { getTimeStat } from "./util.js";
33
33
  async function viteBuild(opts) {
34
34
  var _a, _b, _c;
@@ -104,7 +104,8 @@ async function ssrBuild(opts, internals, input, container) {
104
104
  var _a, _b, _c, _d, _e;
105
105
  const { allPages, settings, viteConfig } = opts;
106
106
  const ssr = isServerLikeOutput(settings.config);
107
- const out = ssr ? opts.buildConfig.server : getOutDirWithinCwd(settings.config.outDir);
107
+ const out = ssr ? settings.config.build.server : getOutDirWithinCwd(settings.config.outDir);
108
+ const routes = Object.values(allPages).map((pd) => pd.route);
108
109
  const { lastVitePlugins, vitePlugins } = container.runBeforeHook("ssr", input);
109
110
  const viteBuildConfig = {
110
111
  ...viteConfig,
@@ -131,14 +132,16 @@ async function ssrBuild(opts, internals, input, container) {
131
132
  assetFileNames: `${settings.config.build.assets}/[name].[hash][extname]`,
132
133
  ...(_e = (_d = viteConfig.build) == null ? void 0 : _d.rollupOptions) == null ? void 0 : _e.output,
133
134
  entryFileNames(chunkInfo) {
134
- var _a2;
135
+ var _a2, _b2;
135
136
  if ((_a2 = chunkInfo.facadeModuleId) == null ? void 0 : _a2.startsWith(ASTRO_PAGE_RESOLVED_MODULE_ID)) {
136
- return makeAstroPageEntryPointFileName(chunkInfo.facadeModuleId, allPages);
137
- } else if (
138
- // checks if the path of the module we have middleware, e.g. middleware.js / middleware/index.js
139
- chunkInfo.moduleIds.find((m) => m.includes("middleware")) !== void 0 && // checks if the file actually export the `onRequest` function
140
- chunkInfo.exports.includes("_middleware")
141
- ) {
137
+ return makeAstroPageEntryPointFileName(
138
+ ASTRO_PAGE_RESOLVED_MODULE_ID,
139
+ chunkInfo.facadeModuleId,
140
+ routes
141
+ );
142
+ } else if ((_b2 = chunkInfo.facadeModuleId) == null ? void 0 : _b2.startsWith(RESOLVED_SPLIT_MODULE_ID)) {
143
+ return makeSplitEntryPointFileName(chunkInfo.facadeModuleId, routes);
144
+ } else if (chunkInfo.facadeModuleId === MIDDLEWARE_MODULE_ID) {
142
145
  return "middleware.mjs";
143
146
  } else if (chunkInfo.facadeModuleId === SSR_VIRTUAL_MODULE_ID) {
144
147
  return opts.settings.config.build.serverEntry;
@@ -161,21 +164,21 @@ async function ssrBuild(opts, internals, input, container) {
161
164
  envPrefix: viteConfig.envPrefix ?? "PUBLIC_",
162
165
  base: settings.config.base
163
166
  };
164
- await runHookBuildSetup({
167
+ const updatedViteBuildConfig = await runHookBuildSetup({
165
168
  config: settings.config,
166
169
  pages: internals.pagesByComponent,
167
170
  vite: viteBuildConfig,
168
171
  target: "server",
169
172
  logging: opts.logging
170
173
  });
171
- return await vite.build(viteBuildConfig);
174
+ return await vite.build(updatedViteBuildConfig);
172
175
  }
173
176
  async function clientBuild(opts, internals, input, container) {
174
177
  var _a, _b, _c;
175
178
  const { settings, viteConfig } = opts;
176
179
  const timer = performance.now();
177
180
  const ssr = isServerLikeOutput(settings.config);
178
- const out = ssr ? opts.buildConfig.client : getOutDirWithinCwd(settings.config.outDir);
181
+ const out = ssr ? settings.config.build.client : getOutDirWithinCwd(settings.config.outDir);
179
182
  if (!input.size) {
180
183
  if (ssr) {
181
184
  await copyFiles(settings.config.publicDir, out, true);
@@ -226,9 +229,9 @@ ${bgGreen(black(" building client "))}`);
226
229
  async function runPostBuildHooks(container, ssrReturn, clientReturn) {
227
230
  const mutations = await container.runPostHook(ssrReturn, clientReturn);
228
231
  const config = container.options.settings.config;
229
- const buildConfig = container.options.settings.config.build;
232
+ const build = container.options.settings.config.build;
230
233
  for (const [fileName, mutation] of mutations) {
231
- const root = isServerLikeOutput(config) ? mutation.build === "server" ? buildConfig.server : buildConfig.client : config.outDir;
234
+ const root = isServerLikeOutput(config) ? mutation.build === "server" ? build.server : build.client : config.outDir;
232
235
  const fileURL = new URL(fileName, root);
233
236
  await fs.promises.mkdir(new URL("./", fileURL), { recursive: true });
234
237
  await fs.promises.writeFile(fileURL, mutation.code, "utf-8");
@@ -241,7 +244,7 @@ async function cleanStaticOutput(opts, internals) {
241
244
  allStaticFiles.add(internals.pageToBundleMap.get(pageData.moduleSpecifier));
242
245
  }
243
246
  const ssr = isServerLikeOutput(opts.settings.config);
244
- const out = ssr ? opts.buildConfig.server : getOutDirWithinCwd(opts.settings.config.outDir);
247
+ const out = ssr ? opts.settings.config.build.server : getOutDirWithinCwd(opts.settings.config.outDir);
245
248
  const files = await glob("**/*.mjs", {
246
249
  cwd: fileURLToPath(out)
247
250
  });
@@ -302,8 +305,8 @@ async function copyFiles(fromFolder, toFolder, includeDotfiles = false) {
302
305
  }
303
306
  async function ssrMoveAssets(opts) {
304
307
  info(opts.logging, "build", "Rearranging server assets...");
305
- const serverRoot = opts.settings.config.output === "static" ? opts.buildConfig.client : opts.buildConfig.server;
306
- const clientRoot = opts.buildConfig.client;
308
+ const serverRoot = opts.settings.config.output === "static" ? opts.settings.config.build.client : opts.settings.config.build.server;
309
+ const clientRoot = opts.settings.config.build.client;
307
310
  const assets = opts.settings.config.build.assets;
308
311
  const serverAssets = new URL(`./${assets}/`, appendForwardSlash(serverRoot.toString()));
309
312
  const clientAssets = new URL(`./${assets}/`, appendForwardSlash(clientRoot.toString()));
@@ -324,15 +327,43 @@ async function ssrMoveAssets(opts) {
324
327
  removeEmptyDirs(serverAssets);
325
328
  }
326
329
  }
327
- function makeAstroPageEntryPointFileName(facadeModuleId, pages) {
328
- var _a, _b;
329
- const pageModuleId = facadeModuleId.replace(ASTRO_PAGE_RESOLVED_MODULE_ID, "").replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".");
330
- let name = ((_b = (_a = pages[pageModuleId]) == null ? void 0 : _a.route) == null ? void 0 : _b.route) ?? pageModuleId;
330
+ function makeAstroPageEntryPointFileName(prefix, facadeModuleId, routes) {
331
+ const pageModuleId = facadeModuleId.replace(prefix, "").replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".");
332
+ let route = routes.find((routeData) => {
333
+ return routeData.route === pageModuleId;
334
+ });
335
+ let name = pageModuleId;
336
+ if (route) {
337
+ name = route.route;
338
+ }
331
339
  if (name.endsWith("/"))
332
340
  name += "index";
333
- return `pages${name.replaceAll("[", "_").replaceAll("]", "_").replaceAll("...", "---")}.mjs`;
341
+ const fileName = `${name.replaceAll("[", "_").replaceAll("]", "_").replaceAll("...", "---")}.mjs`;
342
+ if (name.startsWith("..")) {
343
+ return `pages${fileName}`;
344
+ }
345
+ return fileName;
346
+ }
347
+ function makeSplitEntryPointFileName(facadeModuleId, routes) {
348
+ const filePath = `${makeAstroPageEntryPointFileName(
349
+ RESOLVED_SPLIT_MODULE_ID,
350
+ facadeModuleId,
351
+ routes
352
+ )}`;
353
+ const pathComponents = filePath.split(path.sep);
354
+ const lastPathComponent = pathComponents.pop();
355
+ if (lastPathComponent) {
356
+ const extension = extname(lastPathComponent);
357
+ if (extension.length > 0) {
358
+ const newFileName = `entry.${lastPathComponent}`;
359
+ return [...pathComponents, newFileName].join(path.sep);
360
+ }
361
+ }
362
+ return filePath;
334
363
  }
335
364
  export {
365
+ makeAstroPageEntryPointFileName,
366
+ makeSplitEntryPointFileName,
336
367
  staticBuild,
337
368
  viteBuild
338
369
  };