From 203b53f310add10c6c7626029fe607b96e674675 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 6 Mar 2023 13:32:03 -0500 Subject: [PATCH 1/3] Expose the ssr manifest --- .../src/core/build/plugins/plugin-ssr.ts | 2 ++ packages/astro/src/core/create-vite.ts | 2 ++ .../src/vite-plugin-astro-server/plugin.ts | 3 +- .../src/vite-plugin-ssr-manifest/index.ts | 26 ++++++++++++++++ .../test/fixtures/ssr-manifest/package.json | 8 +++++ .../ssr-manifest/src/pages/index.astro | 17 +++++++++++ packages/astro/test/ssr-manifest.test.js | 30 +++++++++++++++++++ pnpm-lock.yaml | 6 ++++ 8 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 packages/astro/src/vite-plugin-ssr-manifest/index.ts create mode 100644 packages/astro/test/fixtures/ssr-manifest/package.json create mode 100644 packages/astro/test/fixtures/ssr-manifest/src/pages/index.astro create mode 100644 packages/astro/test/ssr-manifest.test.js diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts index d4536b92c8ab..a07b30a2d56f 100644 --- a/packages/astro/src/core/build/plugins/plugin-ssr.ts +++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts @@ -39,10 +39,12 @@ export function vitePluginSSR(internals: BuildInternals, adapter: AstroAdapter): return `import * as adapter from '${adapter.serverEntrypoint}'; import * as _main from '${pagesVirtualModuleId}'; import { deserializeManifest as _deserializeManifest } from 'astro/app'; +import { _privateSetManifestDontUseThis } from 'astro:ssr-manifest'; const _manifest = Object.assign(_deserializeManifest('${manifestReplace}'), { pageMap: _main.pageMap, renderers: _main.renderers }); +_privateSetManifestDontUseThis(_manifest); const _args = ${adapter.args ? JSON.stringify(adapter.args) : 'undefined'}; export * from '${pagesVirtualModuleId}'; ${ diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index 385b8a9f0804..52401ebe9918 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -25,6 +25,7 @@ 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'; interface CreateViteOptions { settings: AstroSettings; @@ -115,6 +116,7 @@ export async function createVite( astroContentVirtualModPlugin({ settings }), astroContentImportPlugin({ fs, settings }), astroContentAssetPropagationPlugin({ mode }), + vitePluginSSRManifest(), ], publicDir: fileURLToPath(settings.config.publicDir), root: fileURLToPath(settings.config.root), diff --git a/packages/astro/src/vite-plugin-astro-server/plugin.ts b/packages/astro/src/vite-plugin-astro-server/plugin.ts index 9fd2a164583f..b15f98fa8b74 100644 --- a/packages/astro/src/vite-plugin-astro-server/plugin.ts +++ b/packages/astro/src/vite-plugin-astro-server/plugin.ts @@ -50,7 +50,8 @@ export default function createVitePluginAstroServer({ handle: baseMiddleware(settings, logging), }); } - viteServer.middlewares.use(async (req, res) => { + // Note that this function has a name so other middleware can find it. + viteServer.middlewares.use(async function astroDevHandler(req, res) { if (req.url === undefined || !req.method) { res.writeHead(500, 'Incomplete request'); res.end(); diff --git a/packages/astro/src/vite-plugin-ssr-manifest/index.ts b/packages/astro/src/vite-plugin-ssr-manifest/index.ts new file mode 100644 index 000000000000..a6cb94915b0c --- /dev/null +++ b/packages/astro/src/vite-plugin-ssr-manifest/index.ts @@ -0,0 +1,26 @@ + +import type { Plugin as VitePlugin } from 'vite'; + +const manifestVirtualModuleId = 'astro:ssr-manifest'; +const resolvedManifestVirtualModuleId = '\0' + manifestVirtualModuleId; + +export function vitePluginSSRManifest(): VitePlugin { + return { + name: '@astrojs/vite-plugin-astro-ssr-manifest', + enforce: 'post', + resolveId(id, parent) { + if(id === manifestVirtualModuleId) { + return resolvedManifestVirtualModuleId; + } + }, + load(id) { + if (id === resolvedManifestVirtualModuleId) { + return `export let manifest = {}; +export function _privateSetManifestDontUseThis(ssrManifest) { + manifest = ssrManifest; +}`; + } + return void 0; + }, + }; +} diff --git a/packages/astro/test/fixtures/ssr-manifest/package.json b/packages/astro/test/fixtures/ssr-manifest/package.json new file mode 100644 index 000000000000..95e82614f10c --- /dev/null +++ b/packages/astro/test/fixtures/ssr-manifest/package.json @@ -0,0 +1,8 @@ +{ + "name": "@test/ssr-manifest", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*" + } +} diff --git a/packages/astro/test/fixtures/ssr-manifest/src/pages/index.astro b/packages/astro/test/fixtures/ssr-manifest/src/pages/index.astro new file mode 100644 index 000000000000..f189e711c19a --- /dev/null +++ b/packages/astro/test/fixtures/ssr-manifest/src/pages/index.astro @@ -0,0 +1,17 @@ +--- +import { manifest } from 'astro:ssr-manifest'; +--- + + + Testing + + + +

Testing

+
+ + diff --git a/packages/astro/test/ssr-manifest.test.js b/packages/astro/test/ssr-manifest.test.js new file mode 100644 index 000000000000..cb24e02eacdd --- /dev/null +++ b/packages/astro/test/ssr-manifest.test.js @@ -0,0 +1,30 @@ + +import { expect } from 'chai'; +import { loadFixture } from './test-utils.js'; +import testAdapter from './test-adapter.js'; +import * as cheerio from 'cheerio'; + +describe('astro:ssr-manifest', () => { + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/ssr-manifest/', + output: 'server', + adapter: testAdapter(), + }); + await fixture.build(); + }); + + it('works', async () => { + const app = await fixture.loadTestAdapterApp(); + const request = new Request('http://example.com/'); + const response = await app.render(request); + const html = await response.text(); + + const $ = cheerio.load(html); + expect($('#assets').text()).to.equal('["/_astro/index.1bad7273.css"]'); + + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9f21215fb06e..4d68e14dc861 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2363,6 +2363,12 @@ importers: dependencies: astro: link:../../.. + packages/astro/test/fixtures/ssr-manifest: + specifiers: + astro: workspace:* + dependencies: + astro: link:../../.. + packages/astro/test/fixtures/ssr-markdown: specifiers: astro: workspace:* From 5f8159c6a5da76b047b864c16e33300950033568 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 6 Mar 2023 13:35:02 -0500 Subject: [PATCH 2/3] Add changeset --- .changeset/heavy-kids-heal.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/heavy-kids-heal.md diff --git a/.changeset/heavy-kids-heal.md b/.changeset/heavy-kids-heal.md new file mode 100644 index 000000000000..41a1f5824d8d --- /dev/null +++ b/.changeset/heavy-kids-heal.md @@ -0,0 +1,5 @@ +--- +'astro': minor +--- + +Expose the manifest to plugins via the astro:ssr-manifest virtual module From 3bfa856d9d928e49123f10f5001922da46d14687 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 6 Mar 2023 16:29:14 -0500 Subject: [PATCH 3/3] Add types for virtual mod --- packages/astro/client-base.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/astro/client-base.d.ts b/packages/astro/client-base.d.ts index fb440995f11f..5f8a7a7273eb 100644 --- a/packages/astro/client-base.d.ts +++ b/packages/astro/client-base.d.ts @@ -117,6 +117,10 @@ declare module '*.mdx' { export default load; } +declare module 'astro:ssr-manifest' { + export const manifest: import('./dist/@types/astro').SSRManifest; +} + // Everything below are Vite's types (apart from image types, which are in `client.d.ts`) // CSS modules