Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(deploy): aws-lambda serve #882

Merged
merged 12 commits into from
Sep 27, 2024
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ deployctl deploy --prod dist/serve-deno.js --exclude node_modules
npm run build -- --with-aws-lambda
```

The handler entrypoint is `dist/serve.js`: see [Hono AWS Lambda Deploy Docs](https://hono.dev/getting-started/aws-lambda#_3-deploy).
The handler entrypoint is `dist/serve-asw-lambda.js`: see [Hono AWS Lambda Deploy Docs](https://hono.dev/getting-started/aws-lambda#_3-deploy).

## Community

Expand Down
6 changes: 3 additions & 3 deletions docs/builder/aws-lambda.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: Deploy a WAKU application to AWS.
# AWS Lambda Builder

The WAKU builder for AWS Lambda will provide the bundled output in the `dist` folder.
The entry handler for the Lambda is `dist/serve.handler`.
The entry handler for the Lambda is `dist/serve-aws-lambda.handler`.

> Folder which require directly access - eg. `fs.readFile("./private/data.json")` needs to be manual added to the deployment configuration.

Expand Down Expand Up @@ -50,7 +50,7 @@ package:

functions:
ssr:
handler: dist/serve.handler
handler: dist/serve-aws-lambda.handler
events:
- httpApi: '*'

Expand Down Expand Up @@ -211,7 +211,7 @@ export class WakuStack extends cdk.Stack {
},
},
}),
handler: 'serve.handler',
handler: 'serve-aws-lambda.handler',
architecture: lambda.Architecture.ARM_64,
runtime: lambda.Runtime.NODEJS_20_X,
});
Expand Down
26 changes: 0 additions & 26 deletions packages/waku/src/lib/builder/serve-aws-lambda.ts

This file was deleted.

98 changes: 61 additions & 37 deletions packages/waku/src/lib/plugins/vite-plugin-deploy-aws-lambda.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,87 @@
import path from 'node:path';
import { existsSync, writeFileSync } from 'node:fs';
import { normalizePath } from 'vite';
import { writeFileSync } from 'node:fs';
import type { Plugin } from 'vite';

import { unstable_getPlatformObject } from '../../server.js';
import { EXTENSIONS, SRC_ENTRIES } from '../constants.js';
import {
decodeFilePathFromAbsolute,
extname,
fileURLToFilePath,
joinPath,
} from '../utils/path.js';
import { DIST_SERVE_JS, DIST_PUBLIC } from '../builder/constants.js';
import { SRC_ENTRIES } from '../constants.js';
import { DIST_PUBLIC } from '../builder/constants.js';

const resolveFileName = (fname: string) => {
for (const ext of EXTENSIONS) {
const resolvedName = fname.slice(0, -extname(fname).length) + ext;
if (existsSync(resolvedName)) {
return resolvedName;
}
const SERVE_JS = 'serve-aws-lambda.js';

const getServeJsContent = (
distDir: string,
distPublic: string,
srcEntriesFile: string,
) => `
import path from 'node:path';
import { existsSync, readFileSync } from 'node:fs';
import { runner, importHono, importHonoNodeServerServeStatic, importHonoAwsLambda } from 'waku/unstable_hono';

const { Hono } = await importHono();
const { serveStatic } = await importHonoNodeServerServeStatic();
const { handle } = await importHonoAwsLambda();
let contextStorage;
try {
({ contextStorage } = await import('hono/context-storage'));
} catch {}

const distDir = '${distDir}';
const publicDir = '${distPublic}';
const loadEntries = () => import('${srcEntriesFile}');

const app = new Hono();
if (contextStorage) {
app.use(contextStorage());
}
app.use('*', serveStatic({ root: distDir + '/' + publicDir }));
app.use('*', runner({ cmd: 'start', loadEntries, env: process.env }));
app.notFound(async (c) => {
const file = path.join(distDir, publicDir, '404.html');
if (existsSync(file)) {
return c.html(readFileSync(file, 'utf8'), 404);
}
return fname; // returning the default one
};
return c.text('404 Not Found', 404);
});

const srcServeFile = decodeFilePathFromAbsolute(
joinPath(
fileURLToFilePath(import.meta.url),
'../../builder/serve-aws-lambda.js',
),
);
export const handler = handle(app);
`;

export function deployAwsLambdaPlugin(opts: {
srcDir: string;
distDir: string;
}): Plugin {
const platformObject = unstable_getPlatformObject();
let entriesFile: string;
return {
name: 'deploy-aws-lambda-plugin',
config(viteConfig) {
const { deploy, unstable_phase } = platformObject.buildOptions || {};
if (unstable_phase !== 'buildServerBundle' || deploy !== 'aws-lambda') {
return;
}

// FIXME This seems too hacky (The use of viteConfig.root, '.', path.resolve and resolveFileName)
const entriesFile = normalizePath(
resolveFileName(
path.resolve(viteConfig.root || '.', opts.srcDir, SRC_ENTRIES),
),
);
const { input } = viteConfig.build?.rollupOptions ?? {};
if (input && !(typeof input === 'string') && !(input instanceof Array)) {
input[DIST_SERVE_JS.replace(/\.js$/, '')] = srcServeFile;
input[SERVE_JS.replace(/\.js$/, '')] = `${opts.srcDir}/${SERVE_JS}`;
}
},
configResolved(config) {
entriesFile = `${config.root}/${opts.srcDir}/${SRC_ENTRIES}`;
const { deploy } = platformObject.buildOptions || {};
if (deploy === 'aws-lambda' && Array.isArray(config.ssr.external)) {
config.ssr.external = config.ssr.external.filter(
(item) => item !== 'hono/context-storage',
);
}
},
resolveId(source) {
if (source === `${opts.srcDir}/${SERVE_JS}`) {
return source;
}
},
load(id) {
if (id === `${opts.srcDir}/${SERVE_JS}`) {
return getServeJsContent(opts.distDir, DIST_PUBLIC, entriesFile);
}
viteConfig.define = {
...viteConfig.define,
'import.meta.env.WAKU_ENTRIES_FILE': JSON.stringify(entriesFile),
'import.meta.env.WAKU_CONFIG_PUBLIC_DIR': JSON.stringify(DIST_PUBLIC),
};
},
closeBundle() {
const { deploy, unstable_phase } = platformObject.buildOptions || {};
Expand Down
1 change: 1 addition & 0 deletions packages/waku/src/unstable_hono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export const importHono = () => import('hono');
export const importHonoNodeServer: any = () => import('@hono/node-server');
export const importHonoNodeServerServeStatic = () =>
import('@hono/node-server/serve-static');
export const importHonoAwsLambda: any = () => import('hono/aws-lambda');
Loading