Skip to content

Commit 5baace9

Browse files
Merge pull request #57 from DBB-Software/feat/PLATFORM-1978
feat: enabled compression and uploading public assets
2 parents 3556ccf + b272431 commit 5baace9

File tree

6 files changed

+66
-16
lines changed

6 files changed

+66
-16
lines changed

src/build/next.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const copyAssets = async (outputPath: string, appPath: string, appRelativePath:
3939
recursive: true
4040
}
4141
)
42+
await fs.cp(path.join(appPath, 'public'), path.join(outputPath, '.next', 'standalone', appRelativePath, 'public'), {
43+
recursive: true
44+
})
4245
}
4346

4447
const getRewritesConfig = (manifestRules: RoutesManifest['rewrites']): NextRewrites => {

src/cacheHandler/strategy/s3.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export class S3Cache implements CacheStrategy {
7878
})
7979
}
8080
const input: PutObjectCommandInput = { ...baseInput }
81+
const tagsValue = [headersTags, this.buildTagKeys(data.tags)].filter(Boolean).join('&')
8182

8283
const promises = [
8384
this.#dynamoDBClient.putItem({
@@ -86,8 +87,9 @@ export class S3Cache implements CacheStrategy {
8687
pageKey: { S: pageKey },
8788
cacheKey: { S: cacheKey },
8889
s3Key: { S: baseInput.Key! },
89-
tags: { S: [headersTags, this.buildTagKeys(data.tags)].filter(Boolean).join('&') },
90-
createdAt: { S: new Date().toISOString() }
90+
createdAt: { S: new Date().toISOString() },
91+
// TODO: check for empty tags
92+
...(tagsValue && { tags: { S: tagsValue } })
9193
}
9294
})
9395
]

src/cdk/constructs/CloudFrontDistribution.ts

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as cloudfront from 'aws-cdk-lib/aws-cloudfront'
44
import * as s3 from 'aws-cdk-lib/aws-s3'
55
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins'
66
import { addOutput } from '../../common/cdk'
7-
import { CacheConfig } from '../../types'
7+
import { DeployConfig } from '../../types'
88
import { HEADER_DEVICE_TYPE } from '../../constants'
99

1010
interface CloudFrontPropsDistribution {
@@ -13,7 +13,7 @@ interface CloudFrontPropsDistribution {
1313
requestEdgeFunction: cloudfront.experimental.EdgeFunction
1414
viewerResponseEdgeFunction: cloudfront.experimental.EdgeFunction
1515
viewerRequestLambdaEdge: cloudfront.experimental.EdgeFunction
16-
cacheConfig: CacheConfig
16+
deployConfig: DeployConfig
1717
imageTTL?: number
1818
}
1919

@@ -35,25 +35,27 @@ export class CloudFrontDistribution extends Construct {
3535
requestEdgeFunction,
3636
viewerResponseEdgeFunction,
3737
viewerRequestLambdaEdge,
38-
cacheConfig,
38+
deployConfig,
3939
renderServerDomain,
4040
imageTTL
4141
} = props
4242

4343
const splitCachePolicy = new cloudfront.CachePolicy(this, 'SplitCachePolicy', {
4444
cachePolicyName: `${id}-SplitCachePolicy`,
4545
queryStringBehavior: cloudfront.CacheQueryStringBehavior.allowList(
46-
...defaultNextQueries.concat(cacheConfig.cacheQueries ?? [])
46+
...defaultNextQueries.concat(deployConfig.cache.cacheQueries ?? [])
4747
),
48-
cookieBehavior: cacheConfig.cacheCookies?.length
49-
? cloudfront.CacheCookieBehavior.allowList(...cacheConfig.cacheCookies)
48+
cookieBehavior: deployConfig.cache.cacheCookies?.length
49+
? cloudfront.CacheCookieBehavior.allowList(...deployConfig.cache.cacheCookies)
5050
: cloudfront.CacheCookieBehavior.none(),
5151
headerBehavior: cloudfront.CacheHeaderBehavior.allowList(
5252
...defaultNextHeaders,
5353
...Object.values(HEADER_DEVICE_TYPE)
5454
),
5555
minTtl: NoCache,
56-
defaultTtl: NoCache // no caching by default, cache value is going to be used from Cache-Control header.
56+
defaultTtl: NoCache, // no caching by default, cache value is going to be used from Cache-Control header.
57+
enableAcceptEncodingBrotli: true,
58+
enableAcceptEncodingGzip: true
5759
})
5860

5961
const longCachePolicy = new cloudfront.CachePolicy(this, 'LongCachePolicy', {
@@ -63,7 +65,9 @@ export class CloudFrontDistribution extends Construct {
6365
headerBehavior: cloudfront.CacheHeaderBehavior.none(),
6466
defaultTtl: OneMonthCache,
6567
maxTtl: OneMonthCache,
66-
minTtl: OneMonthCache
68+
minTtl: OneMonthCache,
69+
enableAcceptEncodingBrotli: true,
70+
enableAcceptEncodingGzip: true
6771
})
6872

6973
const imageTTLValue = imageTTL ? Duration.seconds(imageTTL) : OneDayCache
@@ -75,10 +79,24 @@ export class CloudFrontDistribution extends Construct {
7579
headerBehavior: cloudfront.CacheHeaderBehavior.allowList(...defaultNextHeaders),
7680
defaultTtl: imageTTLValue,
7781
maxTtl: imageTTLValue,
78-
minTtl: imageTTLValue
82+
minTtl: imageTTLValue,
83+
enableAcceptEncodingBrotli: true,
84+
enableAcceptEncodingGzip: true
85+
})
86+
87+
const publicAssetsCachePolicy = new cloudfront.CachePolicy(this, 'PublicAssetsCachePolicy', {
88+
cachePolicyName: `${id}-PublicAssetsCachePolicy`,
89+
defaultTtl: deployConfig.publicAssets?.ttl ? Duration.seconds(deployConfig.publicAssets.ttl) : NoCache,
90+
maxTtl: deployConfig.publicAssets?.ttl ? Duration.seconds(deployConfig.publicAssets.ttl) : NoCache,
91+
minTtl: deployConfig.publicAssets?.ttl ? Duration.seconds(deployConfig.publicAssets.ttl) : NoCache,
92+
enableAcceptEncodingBrotli: true,
93+
enableAcceptEncodingGzip: true
7994
})
8095

8196
const s3Origin = new origins.S3Origin(staticBucket)
97+
const publicFolderS3Origin = new origins.S3Origin(staticBucket, {
98+
originPath: '/public'
99+
})
82100
const nextServerOrigin = new origins.HttpOrigin(renderServerDomain, {
83101
protocolPolicy: cloudfront.OriginProtocolPolicy.HTTP_ONLY,
84102
httpPort: 80
@@ -101,7 +119,8 @@ export class CloudFrontDistribution extends Construct {
101119
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST
102120
}
103121
],
104-
cachePolicy: splitCachePolicy
122+
cachePolicy: splitCachePolicy,
123+
compress: true
105124
},
106125
defaultRootObject: '',
107126
additionalBehaviors: {
@@ -113,16 +132,26 @@ export class CloudFrontDistribution extends Construct {
113132
eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST
114133
}
115134
],
116-
cachePolicy: splitCachePolicy
135+
cachePolicy: splitCachePolicy,
136+
compress: true
117137
},
118138
'/_next/image*': {
119139
origin: nextServerOrigin,
120140
cachePolicy: imageCachePolicy
121141
},
122142
'/_next/*': {
123143
origin: s3Origin,
124-
cachePolicy: longCachePolicy
125-
}
144+
cachePolicy: longCachePolicy,
145+
compress: true
146+
},
147+
...(deployConfig.publicAssets
148+
? {
149+
[`${deployConfig.publicAssets.prefix}/*`]: {
150+
origin: publicFolderS3Origin,
151+
cachePolicy: publicAssetsCachePolicy
152+
}
153+
}
154+
: {})
126155
}
127156
})
128157

src/cdk/stacks/NextCloudfrontStack.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class NextCloudfrontStack extends Stack {
7777
requestEdgeFunction: this.originRequestLambdaEdge.lambdaEdge,
7878
viewerResponseEdgeFunction: this.viewerResponseLambdaEdge.lambdaEdge,
7979
viewerRequestLambdaEdge: this.viewerRequestLambdaEdge.lambdaEdge,
80-
cacheConfig: deployConfig.cache,
80+
deployConfig: deployConfig,
8181
imageTTL
8282
})
8383

src/commands/deploy.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,18 @@ export const deploy = async (config: DeployConfig) => {
208208
folderRootPath: path.join(outputPath, '.next', 'static')
209209
})
210210

211+
await uploadFolderToS3(s3Client, {
212+
Bucket: nextRenderServerStackOutput.StaticBucketName,
213+
Key: 'public',
214+
folderRootPath: path.join(
215+
outputPath,
216+
'.next',
217+
'standalone',
218+
path.relative(projectSettings.root, projectSettings.projectPath),
219+
'public'
220+
)
221+
})
222+
211223
// upload code version to bucket.
212224
await uploadFileToS3(s3Client, {
213225
Bucket: nextRenderServerStackOutput.RenderServerVersionsBucketName,

src/types/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export interface CacheConfig {
1010

1111
export interface DeployConfig {
1212
cache: CacheConfig
13+
publicAssets?: {
14+
prefix: string
15+
ttl?: number
16+
}
1317
}
1418

1519
export type NextRedirects = Awaited<ReturnType<Required<NextConfig>['redirects']>>

0 commit comments

Comments
 (0)