From 9fee2fa559c804d680005680fe2bb091f7b00fef Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 3 Jun 2022 13:38:05 -0400 Subject: [PATCH 1/3] Fix use of dynamic imports / Astro.glob with Deno Deploy --- packages/integrations/deno/package.json | 7 ++- packages/integrations/deno/src/index.ts | 31 ++++++++++++ packages/integrations/deno/src/server.ts | 6 ++- packages/integrations/deno/test/deps.js | 1 + .../deno/test/dynamic-import.test.js | 22 ++++++++ .../test/fixtures/dynimport/astro.config.mjs | 9 ++++ .../deno/test/fixtures/dynimport/package.json | 9 ++++ .../dynimport/src/components/Thing.astro | 4 ++ .../fixtures/dynimport/src/pages/index.astro | 11 ++++ packages/integrations/deno/test/helpers.js | 50 ++++++++++++++++--- pnpm-lock.yaml | 11 ++++ 11 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 packages/integrations/deno/test/dynamic-import.test.js create mode 100644 packages/integrations/deno/test/fixtures/dynimport/astro.config.mjs create mode 100644 packages/integrations/deno/test/fixtures/dynimport/package.json create mode 100644 packages/integrations/deno/test/fixtures/dynimport/src/components/Thing.astro create mode 100644 packages/integrations/deno/test/fixtures/dynimport/src/pages/index.astro diff --git a/packages/integrations/deno/package.json b/packages/integrations/deno/package.json index f1b65d62bf74..6a94327e8e23 100644 --- a/packages/integrations/deno/package.json +++ b/packages/integrations/deno/package.json @@ -22,7 +22,12 @@ "build": "astro-scripts build \"src/**/*.ts\" && tsc", "build:ci": "astro-scripts build \"src/**/*.ts\"", "dev": "astro-scripts dev \"src/**/*.ts\"", - "test": "deno test --allow-run --allow-read --allow-env --allow-net ./test/" + "test:import": "deno test --allow-run --allow-env --allow-read --allow-net --ignore=test/dynamic-import.test.js ./test/", + "test:subprocess": "deno test --allow-run --allow-env --allow-net ./test/dynamic-import.test.js", + "test": "npm run test:import && npm run test:subprocess" + }, + "dependencies": { + "esbuild": "^0.14.42" }, "devDependencies": { "astro": "workspace:*", diff --git a/packages/integrations/deno/src/index.ts b/packages/integrations/deno/src/index.ts index aef1f8383655..d1fc5cc58132 100644 --- a/packages/integrations/deno/src/index.ts +++ b/packages/integrations/deno/src/index.ts @@ -1,4 +1,8 @@ import type { AstroAdapter, AstroIntegration } from 'astro'; +import { fileURLToPath } from 'url'; +import esbuild from 'esbuild'; +import * as npath from 'path'; +import * as fs from 'fs'; interface Options { port?: number; @@ -15,14 +19,20 @@ export function getAdapter(args?: Options): AstroAdapter { } export default function createIntegration(args?: Options): AstroIntegration { + let _buildConfig: any; + let _vite: any; return { name: '@astrojs/deno', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter(getAdapter(args)); }, + 'astro:build:start': ({ buildConfig }) => { + _buildConfig = buildConfig; + }, 'astro:build:setup': ({ vite, target }) => { if (target === 'server') { + _vite = vite; vite.resolve = vite.resolve || {}; vite.resolve.alias = vite.resolve.alias || {}; @@ -41,6 +51,27 @@ export default function createIntegration(args?: Options): AstroIntegration { }; } }, + 'astro:build:done': async () => { + const entryUrl = new URL(_buildConfig.serverEntry, _buildConfig.server); + const pth = fileURLToPath(entryUrl); + await esbuild.build({ + target: 'es2020', + platform: 'browser', + entryPoints: [pth], + outfile: pth, + allowOverwrite: true, + format: 'esm', + bundle: true + }); + + // Remove chunks, if they exist. Since we have bundled via esbuild these chunks are trash. + try { + const chunkFileNames = _vite?.build?.rollupOptions?.output?.chunkFileNames ?? 'chunks/chunk.[hash].mjs'; + const chunkPath = npath.dirname(chunkFileNames); + const chunksDirUrl = new URL(chunkPath + '/', _buildConfig.server); + await fs.promises.rm(chunksDirUrl, { recursive: true, force: true }); + } catch {} + } }, }; } diff --git a/packages/integrations/deno/src/server.ts b/packages/integrations/deno/src/server.ts index 157d06751ca6..d1bed9aec95f 100644 --- a/packages/integrations/deno/src/server.ts +++ b/packages/integrations/deno/src/server.ts @@ -32,13 +32,15 @@ export function start(manifest: SSRManifest, options: Options) { return fetch(localPath.toString()); }; + const port = options.port ?? 8085; _server = new Server({ - port: options.port ?? 8085, + port, hostname: options.hostname ?? '0.0.0.0', handler, }); - _startPromise = _server.listenAndServe(); + _startPromise = Promise.resolve(_server.listenAndServe()); + console.error(`Server running on port ${port}`); } export function createExports(manifest: SSRManifest, options: Options) { diff --git a/packages/integrations/deno/test/deps.js b/packages/integrations/deno/test/deps.js index 80410a338b95..0fd0a66735e5 100644 --- a/packages/integrations/deno/test/deps.js +++ b/packages/integrations/deno/test/deps.js @@ -1,3 +1,4 @@ export * from 'https://deno.land/std@0.110.0/path/mod.ts'; export * from 'https://deno.land/std@0.132.0/testing/asserts.ts'; export * from 'https://deno.land/x/deno_dom/deno-dom-wasm.ts'; +export * from 'https://deno.land/std@0.142.0/streams/conversion.ts'; diff --git a/packages/integrations/deno/test/dynamic-import.test.js b/packages/integrations/deno/test/dynamic-import.test.js new file mode 100644 index 000000000000..2f1a10051529 --- /dev/null +++ b/packages/integrations/deno/test/dynamic-import.test.js @@ -0,0 +1,22 @@ +import { runBuildAndStartAppFromSubprocess } from './helpers.js'; +import { assertEquals, assert, DOMParser } from './deps.js'; + +async function startApp(cb) { + await runBuildAndStartAppFromSubprocess('./fixtures/dynimport/', cb); +} + +Deno.test({ + name: 'Dynamic import', + async fn() { + await startApp(async () => { + const resp = await fetch('http://127.0.0.1:8085/'); + assertEquals(resp.status, 200); + const html = await resp.text(); + console.log(html); + assert(html); + const doc = new DOMParser().parseFromString(html, `text/html`); + const div = doc.querySelector('#thing'); + assert(div, 'div exists'); + }); + }, +}); diff --git a/packages/integrations/deno/test/fixtures/dynimport/astro.config.mjs b/packages/integrations/deno/test/fixtures/dynimport/astro.config.mjs new file mode 100644 index 000000000000..e56fe2e985fd --- /dev/null +++ b/packages/integrations/deno/test/fixtures/dynimport/astro.config.mjs @@ -0,0 +1,9 @@ +import { defineConfig } from 'astro/config'; +import deno from '@astrojs/deno'; + +export default defineConfig({ + adapter: deno(), + experimental: { + ssr: true + } +}) diff --git a/packages/integrations/deno/test/fixtures/dynimport/package.json b/packages/integrations/deno/test/fixtures/dynimport/package.json new file mode 100644 index 000000000000..5dcf7da6e856 --- /dev/null +++ b/packages/integrations/deno/test/fixtures/dynimport/package.json @@ -0,0 +1,9 @@ +{ + "name": "@test/deno-astro-dynimport", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*", + "@astrojs/deno": "workspace:*" + } +} diff --git a/packages/integrations/deno/test/fixtures/dynimport/src/components/Thing.astro b/packages/integrations/deno/test/fixtures/dynimport/src/components/Thing.astro new file mode 100644 index 000000000000..8d8ef929a003 --- /dev/null +++ b/packages/integrations/deno/test/fixtures/dynimport/src/components/Thing.astro @@ -0,0 +1,4 @@ +--- + +--- +
testing
diff --git a/packages/integrations/deno/test/fixtures/dynimport/src/pages/index.astro b/packages/integrations/deno/test/fixtures/dynimport/src/pages/index.astro new file mode 100644 index 000000000000..852cb62019a0 --- /dev/null +++ b/packages/integrations/deno/test/fixtures/dynimport/src/pages/index.astro @@ -0,0 +1,11 @@ +--- +const { default: Thing } = await import('../components/Thing.astro'); +--- + + + testing + + + + + diff --git a/packages/integrations/deno/test/helpers.js b/packages/integrations/deno/test/helpers.js index 3a3fb0c17eab..74c7f9fca5f4 100644 --- a/packages/integrations/deno/test/helpers.js +++ b/packages/integrations/deno/test/helpers.js @@ -1,4 +1,4 @@ -import { fromFileUrl } from './deps.js'; +import { readableStreamFromReader, fromFileUrl } from './deps.js'; const dir = new URL('./', import.meta.url); export async function runBuild(fixturePath) { @@ -10,14 +10,52 @@ export async function runBuild(fixturePath) { return async () => await proc.close(); } -export async function runBuildAndStartApp(fixturePath, cb) { - const url = new URL(fixturePath, dir); - const close = await runBuild(fixturePath); - const mod = await import(new URL('./dist/server/entry.mjs', url)); +export async function startModFromImport(baseUrl) { + const entryUrl = new URL('./dist/server/entry.mjs', baseUrl); + const mod = await import(entryUrl); + if (!mod.running()) { mod.start(); } + + return () => mod.stop(); +} + +export async function startModFromSubprocess(baseUrl) { + const entryUrl = new URL('./dist/server/entry.mjs', baseUrl); + let proc = Deno.run({ + cmd: ['deno', 'run', '--allow-env', '--allow-net', fromFileUrl(entryUrl)], + cwd: fromFileUrl(baseUrl), + stderr: 'piped' + }); + const stderr = readableStreamFromReader(proc.stderr); + const dec = new TextDecoder(); + for await(let bytes of stderr) { + let msg = dec.decode(bytes); + if(msg.includes(`Server running`)) { + break; + } + } + return () => proc.close(); +} + +export async function runBuildAndStartApp(fixturePath, cb) { + const url = new URL(fixturePath, dir); + const close = await runBuild(fixturePath); + const stop = await startModFromImport(url); + + await cb(); + await stop(); + await close(); +} + + +export async function runBuildAndStartAppFromSubprocess(fixturePath, cb) { + const url = new URL(fixturePath, dir); + const close = await runBuild(fixturePath); + const stop = await startModFromSubprocess(url); + await cb(); - await mod.stop(); + await stop(); await close(); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f835923e20af..6dd78d3245d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1645,6 +1645,9 @@ importers: specifiers: astro: workspace:* astro-scripts: workspace:* + esbuild: ^0.14.42 + dependencies: + esbuild: 0.14.42 devDependencies: astro: link:../../astro astro-scripts: link:../../../scripts @@ -1659,6 +1662,14 @@ importers: '@astrojs/react': link:../../../../react astro: link:../../../../../astro + packages/integrations/deno/test/fixtures/dynimport: + specifiers: + '@astrojs/deno': workspace:* + astro: workspace:* + dependencies: + '@astrojs/deno': link:../../.. + astro: link:../../../../../astro + packages/integrations/lit: specifiers: '@lit-labs/ssr': ^2.2.0 From cacaeafb9b079b37283a0143fba6ac21a6d9a994 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 6 Jun 2022 09:45:32 -0400 Subject: [PATCH 2/3] Adds a changeset --- .changeset/swift-pigs-shave.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/swift-pigs-shave.md diff --git a/.changeset/swift-pigs-shave.md b/.changeset/swift-pigs-shave.md new file mode 100644 index 000000000000..f07f5c5e985c --- /dev/null +++ b/.changeset/swift-pigs-shave.md @@ -0,0 +1,5 @@ +--- +'@astrojs/deno': patch +--- + +Fix for using Astro.glob when using the Deno Deploy adapter From 3e97151734bf20ad2b610b2b203cda12f5aa9ef4 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Jun 2022 10:15:04 -0400 Subject: [PATCH 3/3] Mark the markdown package as external --- packages/integrations/deno/src/index.ts | 3 ++- packages/integrations/deno/test/dynamic-import.test.js | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/integrations/deno/src/index.ts b/packages/integrations/deno/src/index.ts index d1fc5cc58132..6fd19e53edfe 100644 --- a/packages/integrations/deno/src/index.ts +++ b/packages/integrations/deno/src/index.ts @@ -61,7 +61,8 @@ export default function createIntegration(args?: Options): AstroIntegration { outfile: pth, allowOverwrite: true, format: 'esm', - bundle: true + bundle: true, + external: [ "@astrojs/markdown-remark"] }); // Remove chunks, if they exist. Since we have bundled via esbuild these chunks are trash. diff --git a/packages/integrations/deno/test/dynamic-import.test.js b/packages/integrations/deno/test/dynamic-import.test.js index 2f1a10051529..56d7fe5a231b 100644 --- a/packages/integrations/deno/test/dynamic-import.test.js +++ b/packages/integrations/deno/test/dynamic-import.test.js @@ -12,7 +12,6 @@ Deno.test({ const resp = await fetch('http://127.0.0.1:8085/'); assertEquals(resp.status, 200); const html = await resp.text(); - console.log(html); assert(html); const doc = new DOMParser().parseFromString(html, `text/html`); const div = doc.querySelector('#thing');