summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2022-06-07 11:41:32 -0400
committerGravatar GitHub <noreply@github.com> 2022-06-07 11:41:32 -0400
commitf3ab822e328725c3905b0adad9889ad37653c24a (patch)
treea4e7a117de3680483222bd18d89e414a90164298
parentab11179ba71b813a850dcd5f776d3b06d373df91 (diff)
downloadastro-f3ab822e328725c3905b0adad9889ad37653c24a.tar.gz
astro-f3ab822e328725c3905b0adad9889ad37653c24a.tar.zst
astro-f3ab822e328725c3905b0adad9889ad37653c24a.zip
Allow dynamic imports when using Netlify Edge Functions (#3535)
* Allow dynamic imports when using Netlify Edge Functions * Update deno test script and changeset
-rw-r--r--.changeset/spicy-planes-drum.md5
-rw-r--r--packages/integrations/deno/package.json4
-rw-r--r--packages/integrations/netlify/package.json3
-rw-r--r--packages/integrations/netlify/src/integration-edge-functions.ts35
-rw-r--r--packages/integrations/netlify/test/edge-functions/deps.ts1
-rw-r--r--packages/integrations/netlify/test/edge-functions/dynamic-import.test.js27
-rw-r--r--packages/integrations/netlify/test/edge-functions/fixtures/dynimport/astro.config.mjs11
-rw-r--r--packages/integrations/netlify/test/edge-functions/fixtures/dynimport/package.json9
-rw-r--r--packages/integrations/netlify/test/edge-functions/fixtures/dynimport/prod.js11
-rw-r--r--packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/components/Thing.astro4
-rw-r--r--packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/pages/index.astro11
-rw-r--r--packages/integrations/netlify/test/edge-functions/test-utils.ts20
-rw-r--r--pnpm-lock.yaml10
13 files changed, 144 insertions, 7 deletions
diff --git a/.changeset/spicy-planes-drum.md b/.changeset/spicy-planes-drum.md
new file mode 100644
index 000000000..7f758e4b4
--- /dev/null
+++ b/.changeset/spicy-planes-drum.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/netlify': patch
+---
+
+Fixes Netlify Edge Function and Astro.glob
diff --git a/packages/integrations/deno/package.json b/packages/integrations/deno/package.json
index 6a94327e8..54cf23d2c 100644
--- a/packages/integrations/deno/package.json
+++ b/packages/integrations/deno/package.json
@@ -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"
diff --git a/packages/integrations/netlify/package.json b/packages/integrations/netlify/package.json
index 9b2f197ad..ff30831e4 100644
--- a/packages/integrations/netlify/package.json
+++ b/packages/integrations/netlify/package.json
@@ -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",
diff --git a/packages/integrations/netlify/src/integration-edge-functions.ts b/packages/integrations/netlify/src/integration-edge-functions.ts
index e43a7f482..3ef39eecb 100644
--- a/packages/integrations/netlify/src/integration-edge-functions.ts
+++ b/packages/integrations/netlify/src/integration-edge-functions.ts
@@ -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 {
@@ -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: {
@@ -80,6 +108,7 @@ 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);
@@ -87,6 +116,7 @@ export function netlifyEdgeFunctions({ dist }: NetlifyEdgeFunctionsOptions = {})
},
'astro:build:setup': ({ vite, target }) => {
if (target === 'server') {
+ _vite = vite;
vite.resolve = vite.resolve || {};
vite.resolve.alias = vite.resolve.alias || {};
@@ -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);
},
diff --git a/packages/integrations/netlify/test/edge-functions/deps.ts b/packages/integrations/netlify/test/edge-functions/deps.ts
index 1b23a94f7..498b7e09e 100644
--- a/packages/integrations/netlify/test/edge-functions/deps.ts
+++ b/packages/integrations/netlify/test/edge-functions/deps.ts
@@ -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';
diff --git a/packages/integrations/netlify/test/edge-functions/dynamic-import.test.js b/packages/integrations/netlify/test/edge-functions/dynamic-import.test.js
new file mode 100644
index 000000000..d4c61fb1f
--- /dev/null
+++ b/packages/integrations/netlify/test/edge-functions/dynamic-import.test.js
@@ -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();
+ }
+ },
+});
diff --git a/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/astro.config.mjs b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/astro.config.mjs
new file mode 100644
index 000000000..c55135e43
--- /dev/null
+++ b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/astro.config.mjs
@@ -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
+ }
+})
diff --git a/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/package.json b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/package.json
new file mode 100644
index 000000000..201a243d0
--- /dev/null
+++ b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/netlify-edge-astro-dynimport",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*",
+ "@astrojs/netlify": "workspace:*"
+ }
+}
diff --git a/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/prod.js b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/prod.js
new file mode 100644
index 000000000..3e7d6e64d
--- /dev/null
+++ b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/prod.js
@@ -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`);
diff --git a/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/components/Thing.astro b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/components/Thing.astro
new file mode 100644
index 000000000..8d8ef929a
--- /dev/null
+++ b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/components/Thing.astro
@@ -0,0 +1,4 @@
+---
+
+---
+<div id="thing">testing</div>
diff --git a/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/pages/index.astro b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/pages/index.astro
new file mode 100644
index 000000000..852cb6201
--- /dev/null
+++ b/packages/integrations/netlify/test/edge-functions/fixtures/dynimport/src/pages/index.astro
@@ -0,0 +1,11 @@
+---
+const { default: Thing } = await import('../components/Thing.astro');
+---
+<html>
+ <head>
+ <title>testing</title>
+ </head>
+ <body>
+ <Thing />
+ </body>
+</html>
diff --git a/packages/integrations/netlify/test/edge-functions/test-utils.ts b/packages/integrations/netlify/test/edge-functions/test-utils.ts
index 826f64d37..72b411d38 100644
--- a/packages/integrations/netlify/test/edge-functions/test-utils.ts
+++ b/packages/integrations/netlify/test/edge-functions/test-utils.ts
@@ -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) {
@@ -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();
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e3ed897d2..b726e6ca0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1702,14 +1702,24 @@ importers:
'@netlify/functions': ^1.0.0
astro: workspace:*
astro-scripts: workspace:*
+ esbuild: ^0.14.42
dependencies:
'@astrojs/webapi': link:../../webapi
+ esbuild: 0.14.42
devDependencies:
'@netlify/edge-handler-types': 0.34.1
'@netlify/functions': 1.0.0
astro: link:../../astro
astro-scripts: link:../../../scripts
+ packages/integrations/netlify/test/edge-functions/fixtures/dynimport:
+ specifiers:
+ '@astrojs/netlify': workspace:*
+ astro: workspace:*
+ dependencies:
+ '@astrojs/netlify': link:../../../..
+ astro: link:../../../../../../astro
+
packages/integrations/netlify/test/edge-functions/fixtures/edge-basic:
specifiers:
'@astrojs/netlify': workspace:*