Skip to content

Commit

Permalink
Netlify Edge: forward requests for static assets (#3170)
Browse files Browse the repository at this point in the history
* Netlify Edge: forward requests for static assets

* Adds a changeset

* Don't run edge tests, yet
  • Loading branch information
matthewp authored Apr 22, 2022
1 parent e632c09 commit 19667c4
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changeset/smooth-tables-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'astro': patch
'@astrojs/netlify': patch
---

Netlify Edge: Forward requests for static assets
3 changes: 3 additions & 0 deletions packages/astro/src/core/app/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ export function deserializeManifest(serializedManifest: SerializedSSRManifest):
route.routeData = deserializeRouteData(serializedRoute.routeData);
}

const assets = new Set<string>(serializedManifest.assets);

return {
...serializedManifest,
assets,
routes,
};
}
4 changes: 3 additions & 1 deletion packages/astro/src/core/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ export interface SSRManifest {
pageMap: Map<ComponentPath, ComponentInstance>;
renderers: SSRLoadedRenderer[];
entryModules: Record<string, string>;
assets: Set<string>;
}

export type SerializedSSRManifest = Omit<SSRManifest, 'routes'> & {
export type SerializedSSRManifest = Omit<SSRManifest, 'routes' | 'assets'> & {
routes: SerializedRouteInfo[];
assets: string[];
};

export type AdapterCreateExports<T = any> = (
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/static-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { fileURLToPath } from 'url';
import * as vite from 'vite';
import { createBuildInternals } from '../../core/build/internal.js';
import { info } from '../logger/core.js';
import { appendForwardSlash, prependForwardSlash } from '../../core/path.js';
import { prependForwardSlash } from '../../core/path.js';
import { emptyDir, removeDir } from '../../core/util.js';
import { rollupPluginAstroBuildCSS } from '../../vite-plugin-build-css/index.js';
import { vitePluginHoistedScripts } from './vite-plugin-hoisted-scripts.js';
Expand Down
19 changes: 15 additions & 4 deletions packages/astro/src/core/build/vite-plugin-ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import type { SerializedRouteInfo, SerializedSSRManifest } from '../app/types';
import { serializeRouteData } from '../routing/index.js';
import { eachPageData } from './internal.js';
import { addRollupInput } from './add-rollup-input.js';
import { fileURLToPath } from 'url';
import glob from 'fast-glob';
import { virtualModuleId as pagesVirtualModuleId } from './vite-plugin-pages.js';
import { BEFORE_HYDRATION_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';

Expand Down Expand Up @@ -65,11 +67,19 @@ if(_start in adapter) {
}
return void 0;
},
generateBundle(_opts, bundle) {
const manifest = buildManifest(buildOpts, internals);
async generateBundle(_opts, bundle) {
const staticFiles = await glob('**/*', {
cwd: fileURLToPath(buildOpts.buildConfig.client),
});

const manifest = buildManifest(buildOpts, internals, staticFiles);



for (const [_chunkName, chunk] of Object.entries(bundle)) {
if (chunk.type === 'asset') continue;
if (chunk.type === 'asset') {
continue;
};
if (chunk.modules[resolvedVirtualModuleId]) {
const code = chunk.code;
chunk.code = code.replace(replaceExp, () => {
Expand All @@ -81,7 +91,7 @@ if(_start in adapter) {
};
}

function buildManifest(opts: StaticBuildOptions, internals: BuildInternals): SerializedSSRManifest {
function buildManifest(opts: StaticBuildOptions, internals: BuildInternals, staticFiles: string[]): SerializedSSRManifest {
const { astroConfig } = opts;

const routes: SerializedRouteInfo[] = [];
Expand Down Expand Up @@ -112,6 +122,7 @@ function buildManifest(opts: StaticBuildOptions, internals: BuildInternals): Ser
pageMap: null as any,
renderers: [],
entryModules,
assets: staticFiles.map(s => '/' + s)
};

return ssrManifest;
Expand Down
1 change: 1 addition & 0 deletions packages/integrations/netlify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@astrojs/webapi": "^0.11.1"
},
"devDependencies": {
"@netlify/edge-handler-types": "^0.34.1",
"@netlify/functions": "^1.0.0",
"astro": "workspace:*",
"astro-scripts": "workspace:*"
Expand Down
9 changes: 8 additions & 1 deletion packages/integrations/netlify/src/netlify-edge-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { App } from 'astro/app';
export function createExports(manifest: SSRManifest) {
const app = new App(manifest);

const handler = async (request: Request): Promise<Response> => {
const handler = async (request: Request): Promise<Response | void> => {
const url = new URL(request.url);

// If this matches a static asset, just return and Netlify will forward it
// to its static asset handler.
if(manifest.assets.has(url.pathname)) {
return;
}
if (app.match(request)) {
return app.render(request);
}
Expand Down
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-root-dynamic",
"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,3 @@
body {
background: blue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<head>
<title>Testing</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<h1>Testing</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// @ts-ignore
import { runBuild } from './test-utils.ts';
// @ts-ignore
import { assertEquals, assert, DOMParser } from './deps.ts';

// @ts-ignore
Deno.test({
name: 'Assets are preferred over HTML routes',
async fn() {
let close = await runBuild('./fixtures/root-dynamic/');
const { default: handler } = await import('./fixtures/root-dynamic/dist/edge-functions/entry.js');
const response = await handler(new Request('http://example.com/styles.css'));
assertEquals(response, undefined, 'No response because this is an asset');
await close();
},
});
6 changes: 5 additions & 1 deletion packages/integrations/netlify/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
"allowJs": true,
"module": "ES2020",
"outDir": "./dist",
"target": "ES2020"
"target": "ES2020",
"typeRoots": [
"node_modules/@types",
"node_modules/@netlify"
]
}
}
16 changes: 16 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 19667c4

Please sign in to comment.