Skip to content

Commit

Permalink
Fix use of dynamic imports / Astro.glob with Deno Deploy (#3532)
Browse files Browse the repository at this point in the history
* Fix use of dynamic imports / Astro.glob with Deno Deploy

* Adds a changeset

* Mark the markdown package as external
  • Loading branch information
matthewp committed Jun 6, 2022
1 parent 9029c43 commit c22a07d
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/swift-pigs-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/deno': patch
---

Fix for using Astro.glob when using the Deno Deploy adapter
7 changes: 6 additions & 1 deletion packages/integrations/deno/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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:*",
Expand Down
32 changes: 32 additions & 0 deletions packages/integrations/deno/src/index.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 || {};

Expand All @@ -41,6 +51,28 @@ 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,
external: [ "@astrojs/markdown-remark"]
});

// 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 {}
}
},
};
}
6 changes: 4 additions & 2 deletions packages/integrations/deno/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions packages/integrations/deno/test/deps.js
Original file line number Diff line number Diff line change
@@ -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';
21 changes: 21 additions & 0 deletions packages/integrations/deno/test/dynamic-import.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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();
assert(html);
const doc = new DOMParser().parseFromString(html, `text/html`);
const div = doc.querySelector('#thing');
assert(div, 'div exists');
});
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'astro/config';
import deno from '@astrojs/deno';

export default defineConfig({
adapter: deno(),
experimental: {
ssr: true
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "@test/deno-astro-dynimport",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*",
"@astrojs/deno": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---
<div id="thing">testing</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
const { default: Thing } = await import('../components/Thing.astro');
---
<html>
<head>
<title>testing</title>
</head>
<body>
<Thing />
</body>
</html>
50 changes: 44 additions & 6 deletions packages/integrations/deno/test/helpers.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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();
}
11 changes: 11 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c22a07d

Please sign in to comment.