diff --git a/.changeset/funny-seahorses-compare.md b/.changeset/funny-seahorses-compare.md new file mode 100644 index 000000000000..4ae565a82490 --- /dev/null +++ b/.changeset/funny-seahorses-compare.md @@ -0,0 +1,6 @@ +--- +'astro': patch +'@astrojs/deno': patch +--- + +Deno SSR with prerender=true complains about invalid URL scheme diff --git a/packages/astro/src/core/build/plugins/plugin-ssr.ts b/packages/astro/src/core/build/plugins/plugin-ssr.ts index d4536b92c8ab..58548c0bb677 100644 --- a/packages/astro/src/core/build/plugins/plugin-ssr.ts +++ b/packages/astro/src/core/build/plugins/plugin-ssr.ts @@ -36,7 +36,7 @@ export function vitePluginSSR(internals: BuildInternals, adapter: AstroAdapter): }, load(id) { if (id === resolvedVirtualModuleId) { - return `import * as adapter from '${adapter.serverEntrypoint}'; + return `import * as _adapter from '${adapter.serverEntrypoint}'; import * as _main from '${pagesVirtualModuleId}'; import { deserializeManifest as _deserializeManifest } from 'astro/app'; const _manifest = Object.assign(_deserializeManifest('${manifestReplace}'), { @@ -47,7 +47,7 @@ const _args = ${adapter.args ? JSON.stringify(adapter.args) : 'undefined'}; export * from '${pagesVirtualModuleId}'; ${ adapter.exports - ? `const _exports = adapter.createExports(_manifest, _args); + ? `const _exports = _adapter.createExports(_manifest, _args); ${adapter.exports .map((name) => { if (name === 'default') { @@ -61,11 +61,13 @@ export { _default as default };`; ` : '' } +export const adapter = _adapter +${adapter.name !== '@astrojs/deno' ? ` const _start = 'start'; -if(_start in adapter) { - adapter[_start](_manifest, _args); -}`; - } +if(_start in _adapter) { + _adapter[_start](_manifest, _args); +}`: ''}`; + } return void 0; }, async generateBundle(_opts, bundle) { diff --git a/packages/integrations/deno/src/code-constant.ts b/packages/integrations/deno/src/code-constant.ts new file mode 100644 index 000000000000..bf272e397080 --- /dev/null +++ b/packages/integrations/deno/src/code-constant.ts @@ -0,0 +1,2 @@ +export const DEFAULTIMPORT = `import { Server } from "https://deno.land/std@0.167.0/http/server.ts"; \n import { fetch } from "https://deno.land/x/file_fetch/mod.ts";\nimport { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts";` +export const DEFAULTSTART = `const _start = 'start'; \n if(_start in adapter) { \nadapter[_start](_manifest, _args);}` diff --git a/packages/integrations/deno/src/index.ts b/packages/integrations/deno/src/index.ts index 82da151888cd..891623ead537 100644 --- a/packages/integrations/deno/src/index.ts +++ b/packages/integrations/deno/src/index.ts @@ -3,6 +3,7 @@ import esbuild from 'esbuild'; import * as fs from 'fs'; import * as npath from 'path'; import { fileURLToPath } from 'url'; +import * as CONSTANT from './code-constant' interface BuildConfig { server: URL; @@ -70,6 +71,8 @@ export default function createIntegration(args?: Options): AstroIntegration { 'astro:build:done': async () => { const entryUrl = new URL(_buildConfig.serverEntry, _buildConfig.server); const pth = fileURLToPath(entryUrl); + const content = await fs.readFileSync(pth, 'utf8') + await fs.writeFileSync(pth, `${CONSTANT.DEFAULTIMPORT}${content}${CONSTANT.DEFAULTSTART}`); await esbuild.build({ target: 'es2020', platform: 'browser', diff --git a/packages/integrations/deno/src/server.ts b/packages/integrations/deno/src/server.ts index 00e1c43db5cf..ed358f2f09dc 100644 --- a/packages/integrations/deno/src/server.ts +++ b/packages/integrations/deno/src/server.ts @@ -1,10 +1,7 @@ // Normal Imports import type { SSRManifest } from 'astro'; import { App } from 'astro/app'; -// @ts-ignore -import { Server } from 'https://deno.land/std@0.167.0/http/server.ts'; -// @ts-ignore -import { fetch } from 'https://deno.land/x/file_fetch/mod.ts'; + interface Options { port?: number; @@ -12,6 +9,7 @@ interface Options { start?: boolean; } +// @ts-ignore let _server: Server | undefined = undefined; let _startPromise: Promise | undefined = undefined; @@ -39,8 +37,19 @@ export function start(manifest: SSRManifest, options: Options) { // try to fetch a static file instead const url = new URL(request.url); const localPath = new URL('./' + app.removeBase(url.pathname), clientRoot); - const fileResp = await fetch(localPath.toString()); - + const stringLocalPath = localPath.toString(); + // @ts-ignore + const extendName = fileExtension(stringLocalPath); + const fileResp = await fetch( + !extendName + ? `${ + stringLocalPath.endsWith('/') + ? `${stringLocalPath}index.html` + : `${stringLocalPath}/index.html` + }` + : stringLocalPath + ); + // If the static file can't be found if (fileResp.status == 404) { // Render the astro custom 404 page @@ -60,6 +69,7 @@ export function start(manifest: SSRManifest, options: Options) { }; const port = options.port ?? 8085; + // @ts-ignore _server = new Server({ port, hostname: options.hostname ?? '0.0.0.0', diff --git a/packages/integrations/deno/test/basics.test.ts b/packages/integrations/deno/test/basics.test.ts index d1f8907cb3c7..e61dbd3f7a35 100644 --- a/packages/integrations/deno/test/basics.test.ts +++ b/packages/integrations/deno/test/basics.test.ts @@ -143,3 +143,24 @@ Deno.test({ sanitizeResources: false, sanitizeOps: false, }); + +Deno.test({ + name: 'perendering', + permissions: defaultTestPermissions, + async fn() { + await startApp(async (baseUrl: URL) => { + const resp = await fetch(new URL('perendering', baseUrl)); + assertEquals(resp.status, 200); + + + const html = await resp.text(); + assert(html); + + const doc = new DOMParser().parseFromString(html, `text/html`); + const h1 = doc!.querySelector('h1'); + assertEquals(h1!.innerText, 'test'); + }); + }, + sanitizeResources: false, + sanitizeOps: false, +}); diff --git a/packages/integrations/deno/test/fixtures/basics/src/pages/perendering.astro b/packages/integrations/deno/test/fixtures/basics/src/pages/perendering.astro new file mode 100644 index 000000000000..ca317d38d296 --- /dev/null +++ b/packages/integrations/deno/test/fixtures/basics/src/pages/perendering.astro @@ -0,0 +1,9 @@ +--- +export const prerender = true; +--- + + + +

test

+ +