Skip to content
This repository was archived by the owner on Feb 1, 2025. It is now read-only.

Commit f4a79a7

Browse files
committed
doc: polished and updated documentation
1 parent 0274bff commit f4a79a7

File tree

2 files changed

+58
-59
lines changed

2 files changed

+58
-59
lines changed

README.md

+56-58
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,28 @@ It includes a wrapper for `next/server/image-optimizer` allowing to use S3.
55
And includes CLI and custom server handler to integrate with ApiGw.
66

77
- [NextJS Lambda Utils](#nextjs-lambda-utils)
8+
- [TL;DR](#tldr)
89
- [Usage](#usage)
910
- [next.config.js](#nextconfigjs)
1011
- [Server handler](#server-handler)
1112
- [Image handler](#image-handler)
1213
- [Via CDK](#via-cdk)
13-
- [Sharp](#sharp)
14+
- [Sharp layer](#sharp-layer)
15+
- [Next layer](#next-layer)
1416
- [Packaging](#packaging)
1517
- [Server handler](#server-handler-1)
1618
- [Static assets](#static-assets)
1719
- [Versioning](#versioning)
1820
- [Guess](#guess)
1921
- [Shipit](#shipit)
20-
- [TODO](#todo)
2122
- [Disclaimer](#disclaimer)
2223

24+
## TL;DR
25+
- In your NextJS project, set output to standalone.
26+
- Run `npx @sladg/nextjs-lambda pack`
27+
- Prepare CDK ([see](#via-cdk))
28+
- Run `cdk deploy`
29+
2330
## Usage
2431

2532
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 +50,68 @@ See:
4350

4451
### Server handler
4552

46-
```
47-
next build
53+
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.
4854

49-
npx @sladg/nextjs-lambda pack
50-
```
55+
### Image handler
5156

52-
Create new lambda function with NODE_16 runtime in AWS.
57+
Lambda consumes Api Gateway requests, so we need to create ApiGw proxy (v2) that will trigger Lambda.
5358

54-
```
55-
const dependenciesLayer = new LayerVersion(this, 'DepsLayer', {
56-
code: Code.fromAsset(`next.out/dependenciesLayer.zip`),
57-
})
58-
59-
const requestHandlerFn = new Function(this, 'LambdaFunction', {
60-
code: Code.fromAsset(`next.out/code.zip`, { followSymlinks: SymlinkFollowMode.NEVER }),
61-
runtime: Runtime.NODEJS_16_X,
62-
handler: 'server-handler.handler',
63-
layers: [dependenciesLayer],
64-
memorySize: 512,
65-
timeout: Duration.seconds(10),
66-
})
67-
```
59+
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.
6860

69-
### Image handler
61+
### Via CDK
7062

71-
Create new lambda function with NODE_16 runtime in AWS.
63+
See `NextStandaloneStack` construct in `lib/construct.ts`.
7264

65+
You can easily create `cdk/app.ts` and use following code:
7366
```
74-
const sharpLayer: LayerVersion
75-
const assetsBucket: Bucket
76-
77-
const imageHandlerZip = require.resolve('@sladg/nextjs-lambda/image-handler/zip')
78-
79-
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-
```
67+
#!/usr/bin/env node
68+
import 'source-map-support/register'
69+
import * as cdk from 'aws-cdk-lib'
70+
import * as path from 'path'
9171
92-
Lambda consumes Api Gateway requests, so we need to create ApiGw proxy (v2) that will trigger Lambda.
72+
import { NextStandaloneStack } from '@sladg/nextjs-lambda'
9373
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.
74+
const assetsZipPath = path.resolve(__dirname, '../next.out/assetsLayer.zip')
75+
const codeZipPath = path.resolve(__dirname, '../next.out/code.zip')
76+
const dependenciesZipPath = path.resolve(__dirname, '../next.out/dependenciesLayer.zip')
9577
96-
### Via CDK
78+
const app = new cdk.App()
79+
80+
new NextStandaloneStack(app, 'StandaloneNextjsStack-2', {
81+
assetsZipPath,
82+
codeZipPath,
83+
dependenciesZipPath,
84+
})
85+
```
9786

98-
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.
87+
This imports pre-made construct, you only need to worry about paths to outputed zip files from CLI `pack` command.
10088

89+
> More granular CDK construct coming soon.
10190
102-
### Sharp
91+
92+
### Sharp layer
10393

10494
Besides handler (wrapper) itself, underlying NextJS also requires sharp binaries.
10595
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.
10696

10797
```
108-
const code = require.resolve('@sladg/nextjs-lambda/sharp-layer')
98+
import { sharpLayerZipPath } from '@sladg/nextjs-lambda'
10999
110-
const sharpLayer = new LayerVersion(this, 'SharpLayer', {
111-
code: Code.fromAsset(code)
100+
const sharpLayer = new LayerVersion(this, 'SharpDependenciesLayer', {
101+
code: Code.fromAsset(sharpLayerZipPath)
102+
})
103+
```
104+
105+
### Next layer
106+
107+
To provide both image and server handlers with all depdencies (next is using `require.resolve` inside, so it cannot be bundled standalone for now).
108+
109+
We pre-package this layer so it can be included in Lambda without hasle.
110+
```
111+
import { nextLayerZipPath } from '@sladg/nextjs-lambda'
112+
113+
const nextLayer = new LayerVersion(this, 'NextDependenciesLayer', {
114+
code: Code.fromAsset(nextLayerZipPath)
112115
})
113116
```
114117

@@ -147,6 +150,8 @@ Cloudfront paths used:
147150
- `_next/*`
148151
- `assets/*`
149152

153+
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.
154+
150155
# Versioning
151156

152157
This package exposes two CLI functions intended to deal with versioning your application and releasing.
@@ -164,15 +169,6 @@ Similar to guess command, however, it automatically tags a commit on current bra
164169
Simply call `@sladg/next-lambda shipit` on any branch and be done.
165170

166171

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-
176172
# Disclaimer
177173

178174
At this point, advanced features were not tested with this setup. This includes:
@@ -184,3 +180,5 @@ At this point, advanced features were not tested with this setup. This includes:
184180
- custom babel configuration.
185181

186182
I am looking for advanced projects implementing those features, so we can test them out! Reach out to me!
183+
184+

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"next-utils": "./dist/cli.js"
1515
},
1616
"files": [
17-
"dist"
17+
"dist",
18+
"scripts"
1819
],
1920
"scripts": {
2021
"prebuild": "rm -rf dist",

0 commit comments

Comments
 (0)