You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Feb 1, 2025. It is now read-only.
* refactor(rollup): properly bundle different entry points, upgrade to node18
* ref(layers): nextjs layer to be pre-build so it can be used by server and image handler
* doc: polished and updated documentation
* doc: improved description of the project
Co-authored-by: Jan Soukup <[email protected]>
This is a set of utils needed for deploying NextJS into AWS Lambda.
4
-
It includes a wrapper for `next/server/image-optimizer` allowing to use S3.
5
-
And includes CLI and custom server handler to integrate with ApiGw.
3
+
This is a project allowing to deploy Next applications (standalone options turned on) to AWS Lambda without hassle.
4
+
5
+
This is an alternative to existing Lambda@Edge implementation ([see](https://www.npmjs.com/package/@sls-next/lambda-at-edge)) as it has too many limitations (primarily inability to use env vars) and deployments take too long.
6
+
7
+
This library uses Cloudfront, S3, ApiGateway and Lambdas to deploy easily in seconds (hotswap supported).
8
+
6
9
7
10
-[NextJS Lambda Utils](#nextjs-lambda-utils)
11
+
-[TL;DR](#tldr)
8
12
-[Usage](#usage)
9
13
-[next.config.js](#nextconfigjs)
10
14
-[Server handler](#server-handler)
11
15
-[Image handler](#image-handler)
12
16
-[Via CDK](#via-cdk)
13
-
-[Sharp](#sharp)
17
+
-[Sharp layer](#sharp-layer)
18
+
-[Next layer](#next-layer)
14
19
-[Packaging](#packaging)
15
20
-[Server handler](#server-handler-1)
16
21
-[Static assets](#static-assets)
17
22
-[Versioning](#versioning)
18
23
-[Guess](#guess)
19
24
-[Shipit](#shipit)
20
-
-[TODO](#todo)
21
25
-[Disclaimer](#disclaimer)
22
26
27
+
## TL;DR
28
+
- In your NextJS project, set output to standalone.
29
+
- Run `npx @sladg/nextjs-lambda pack`
30
+
- Prepare CDK ([see](#via-cdk))
31
+
- Run `cdk deploy`
32
+
23
33
## Usage
24
34
25
35
We need to create 2 lambdas in order to use NextJS. First one is handling pages/api rendering, second is solving image optimization.
@@ -43,72 +53,68 @@ See:
43
53
44
54
### Server handler
45
55
46
-
```
47
-
next build
56
+
This is a Lambda entrypoint to handle non-asset requests. We need a way to start Next in lambda-friendly way and translate ApiGateway event into typical HTTP event. This is handled by server-handler, which sits alongside of next's `server.js` in standalone output.
48
57
49
-
npx @sladg/nextjs-lambda pack
50
-
```
58
+
### Image handler
51
59
52
-
Create new lambda function with NODE_16 runtime in AWS.
60
+
Lambda consumes Api Gateway requests, so we need to create ApiGw proxy (v2) that will trigger Lambda.
53
61
54
-
```
55
-
const dependenciesLayer = new LayerVersion(this, 'DepsLayer', {
Lambda is designed to serve `_next/image*` route in NextJS stack and replaces the default handler so we can optimize caching and memory limits for page renders and image optimization.
68
63
69
-
### Image handler
64
+
### Via CDK
70
65
71
-
Create new lambda function with NODE_16 runtime in AWS.
66
+
See `NextStandaloneStack` construct in `lib/construct.ts`.
72
67
68
+
You can easily create `cdk/app.ts` and use following code:
const imageOptimizerFn = new Function(this, 'LambdaFunction', {
80
-
code: Code.fromAsset(imageHandlerZip),
81
-
runtime: Runtime.NODEJS_16_X,
82
-
handler: 'image-handler.handler',
83
-
layers: [sharpLayer],
84
-
memorySize: 1024,
85
-
timeout: Duration.seconds(15),
86
-
environment: {
87
-
S3_BUCKET_SOURCE: assetsBucket.bucketName
88
-
}
89
-
})
90
-
```
70
+
#!/usr/bin/env node
71
+
import 'source-map-support/register'
72
+
import * as cdk from 'aws-cdk-lib'
73
+
import * as path from 'path'
91
74
92
-
Lambda consumes Api Gateway requests, so we need to create ApiGw proxy (v2) that will trigger Lambda.
75
+
import { NextStandaloneStack } from '@sladg/nextjs-lambda'
93
76
94
-
Lambda is designed to serve `_next/image*` route in NextJS stack and replaces the default handler so we can optimize caching and memory limits for page renders and image optimization.
See `NextStandaloneLambda` construct in `lib/construct.ts`.
99
-
This is a complete definition which consumes output of `pack` CLI command. It requires 3 zips (assets, dependencies and code) and exposes get methods for all resources to provide a way to set custom routes, set environment variables, etc.
83
+
new NextStandaloneStack(app, 'StandaloneNextjsStack-2', {
84
+
assetsZipPath,
85
+
codeZipPath,
86
+
dependenciesZipPath,
87
+
})
88
+
```
89
+
90
+
This imports pre-made construct, you only need to worry about paths to outputed zip files from CLI `pack` command.
91
+
92
+
> More granular CDK construct coming soon.
100
93
101
94
102
-
### Sharp
95
+
### Sharp layer
103
96
104
97
Besides handler (wrapper) itself, underlying NextJS also requires sharp binaries.
105
98
To build those, we use `npm install` with some extra parametes. Then we zip all sharp dependencies and compress it to easily importable zip file.
import { sharpLayerZipPath } from '@sladg/nextjs-lambda'
102
+
103
+
const sharpLayer = new LayerVersion(this, 'SharpDependenciesLayer', {
104
+
code: Code.fromAsset(sharpLayerZipPath)
105
+
})
106
+
```
107
+
108
+
### Next layer
109
+
110
+
To provide both image and server handlers with all depdencies (next is using `require.resolve` inside, so it cannot be bundled standalone for now).
111
+
112
+
We pre-package this layer so it can be included in Lambda without hassle.
113
+
```
114
+
import { nextLayerZipPath } from '@sladg/nextjs-lambda'
109
115
110
-
const sharpLayer = new LayerVersion(this, 'SharpLayer', {
111
-
code: Code.fromAsset(code)
116
+
const nextLayer = new LayerVersion(this, 'NextDependenciesLayer', {
117
+
code: Code.fromAsset(nextLayerZipPath)
112
118
})
113
119
```
114
120
@@ -147,6 +153,8 @@ Cloudfront paths used:
147
153
-`_next/*`
148
154
-`assets/*`
149
155
156
+
Keep in minda, Cloudfront does not allow for multiple regex patterns in single origin, so using extensions to distinguish image/server handlers is not doable.
157
+
150
158
# Versioning
151
159
152
160
This package exposes two CLI functions intended to deal with versioning your application and releasing.
@@ -164,15 +172,6 @@ Similar to guess command, however, it automatically tags a commit on current bra
164
172
Simply call `@sladg/next-lambda shipit` on any branch and be done.
165
173
166
174
167
-
# TODO
168
-
169
-
- Explain scripts used for packaging Next app,
170
-
- Add CDK examples on how to set it up,
171
-
- Export CDK contruct for simple plug-n-play use,
172
-
- Use lib/index.ts as single entry and export all paths/functions from it (including zip paths).
173
-
- Consider using \*.svg, \*.png, \*.jpeg etc. as routing rule for Cloudfront to distinguish between assets and pages.
174
-
- Add command for guessing version bumps from git commits & keywords, existing solutions are horendously huge, we just need a simple version bumping.
175
-
176
175
# Disclaimer
177
176
178
177
At this point, advanced features were not tested with this setup. This includes:
@@ -184,3 +183,5 @@ At this point, advanced features were not tested with this setup. This includes:
184
183
- custom babel configuration.
185
184
186
185
I am looking for advanced projects implementing those features, so we can test them out! Reach out to me!
0 commit comments