Skip to content

Commit

Permalink
Allow dynamic imports when using Netlify Edge Functions (#3535)
Browse files Browse the repository at this point in the history
* Allow dynamic imports when using Netlify Edge Functions

* Update deno test script and changeset
  • Loading branch information
matthewp committed Jun 7, 2022
1 parent ab11179 commit f3ab822
Show file tree
Hide file tree
Showing 13 changed files with 144 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-planes-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/netlify': patch
---

Fixes Netlify Edge Function and Astro.glob
4 changes: 1 addition & 3 deletions packages/integrations/deno/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
"dev": "astro-scripts dev \"src/**/*.ts\"",
"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"
"test": "deno test --allow-run --allow-env --allow-read --allow-net ./test/"
},
"dependencies": {
"esbuild": "^0.14.42"
Expand Down
3 changes: 2 additions & 1 deletion packages/integrations/netlify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"test": "npm run test-fn"
},
"dependencies": {
"@astrojs/webapi": "^0.12.0"
"@astrojs/webapi": "^0.12.0",
"esbuild": "^0.14.42"
},
"devDependencies": {
"@netlify/edge-handler-types": "^0.34.1",
Expand Down
35 changes: 33 additions & 2 deletions packages/integrations/netlify/src/integration-edge-functions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'astro';
import * as fs from 'fs';
import type { AstroAdapter, AstroIntegration, AstroConfig, RouteData, BuildConfig } from 'astro';
import { createRedirects } from './shared.js';
import esbuild from 'esbuild';
import * as fs from 'fs';
import { fileURLToPath } from 'url';
import * as npath from 'path';

export function getAdapter(): AstroAdapter {
return {
Expand Down Expand Up @@ -62,9 +65,34 @@ async function createEdgeManifest(routes: RouteData[], entryFile: string, dir: U
await fs.promises.writeFile(manifestURL, _manifest, 'utf-8');
}

async function bundleServerEntry(buildConfig: BuildConfig, vite: any) {
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 {}
}

export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {}): AstroIntegration {
let _config: AstroConfig;
let entryFile: string;
let _buildConfig: BuildConfig;
let _vite: any;
return {
name: '@astrojs/netlify/edge-functions',
hooks: {
Expand All @@ -80,13 +108,15 @@ export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {})
_config = config;
},
'astro:build:start': async ({ buildConfig }) => {
_buildConfig = buildConfig;
entryFile = buildConfig.serverEntry.replace(/\.m?js/, '');
buildConfig.client = _config.outDir;
buildConfig.server = new URL('./.netlify/edge-functions/', _config.root);
buildConfig.serverEntry = 'entry.js';
},
'astro:build:setup': ({ vite, target }) => {
if (target === 'server') {
_vite = vite;
vite.resolve = vite.resolve || {};
vite.resolve.alias = vite.resolve.alias || {};

Expand All @@ -106,6 +136,7 @@ export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {})
}
},
'astro:build:done': async ({ routes, dir }) => {
await bundleServerEntry(_buildConfig, _vite);
await createEdgeManifest(routes, entryFile, _config.root);
await createRedirects(routes, dir, entryFile, true);
},
Expand Down
1 change: 1 addition & 0 deletions packages/integrations/netlify/test/edge-functions/deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
export { fromFileUrl } from 'https://deno.land/std@0.110.0/path/mod.ts';
export { assertEquals, assert } 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';
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// @ts-ignore
import { runBuild, runApp } from './test-utils.ts';
// @ts-ignore
import { assertEquals, assert, DOMParser } from './deps.ts';

// @ts-ignore
Deno.test({
name: 'Dynamic imports',
async fn() {
let close = await runBuild('./fixtures/dynimport/');
let stop = await runApp('./fixtures/dynimport/prod.js');

try {
const response = await fetch('http://127.0.0.1:8085/');
assertEquals(response.status, 200);
const html = await response.text();

assert(html, 'got some html');
const doc = new DOMParser().parseFromString(html, `text/html`);
const div = doc.querySelector('#thing');
assert(div, 'div exists')
} finally {
await close();
await stop();
}
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from 'astro/config';
import { netlifyEdgeFunctions } from '@astrojs/netlify';

export default defineConfig({
adapter: netlifyEdgeFunctions({
dist: new URL('./dist/', import.meta.url),
}),
experimental: {
ssr: true
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "@test/netlify-edge-astro-dynimport",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*",
"@astrojs/netlify": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import handler from './.netlify/edge-functions/entry.js';
import { Server } from 'https://deno.land/std@0.132.0/http/server.ts';

const _server = new Server({
port: 8085,
hostname: '0.0.0.0',
handler,
});

_server.listenAndServe();
console.error(`Server running on port 8085`);
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>
20 changes: 19 additions & 1 deletion packages/integrations/netlify/test/edge-functions/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @ts-ignore
import { fromFileUrl } from './deps.ts';
import { fromFileUrl, readableStreamFromReader } from './deps.ts';
const dir = new URL('./', import.meta.url);

export async function runBuild(fixturePath: string) {
Expand All @@ -11,3 +11,21 @@ export async function runBuild(fixturePath: string) {
await proc.status();
return async () => await proc.close();
}

export async function runApp(entryPath: string) {
const entryUrl = new URL(entryPath, dir)
let proc = Deno.run({
cmd: ['deno', 'run', '--allow-env', '--allow-net', fromFileUrl(entryUrl)],
//cwd: fromFileUrl(entryUrl),
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();
}
10 changes: 10 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 f3ab822

Please sign in to comment.