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

Commit 8aa2d52

Browse files
author
Daniel Balogh
committed
Added support for public/static folder cache control
1 parent 0dc5881 commit 8aa2d52

File tree

19 files changed

+312
-93
lines changed

19 files changed

+312
-93
lines changed

package-lock.json

Lines changed: 120 additions & 60 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/s3-static-assets/package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/s3-static-assets/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"aws-sdk": "^2.664.0",
3636
"fs-extra": "^9.0.0",
3737
"klaw": "^3.0.0",
38-
"mime-types": "^2.1.27"
38+
"mime-types": "^2.1.27",
39+
"regex-parser": "^2.2.10"
3940
},
4041
"devDependencies": {
4142
"@types/fs-extra": "^8.1.0",

packages/s3-static-assets/src/index.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,29 @@ import filterOutDirectories from "./lib/filterOutDirectories";
66
import { IMMUTABLE_CACHE_CONTROL_HEADER } from "./lib/constants";
77
import S3ClientFactory, { Credentials } from "./lib/s3";
88
import pathToPosix from "./lib/pathToPosix";
9+
import getPublicAssetCacheControl, {
10+
PublicAssetCacheControl
11+
} from "./lib/getPublicAssetCacheControl";
12+
13+
type Options = {
14+
publicAssetCache?: PublicAssetCacheControl;
15+
};
916

1017
type UploadStaticAssetsOptions = {
1118
bucketName: string;
1219
nextConfigDir: string;
1320
nextStaticDir?: string;
1421
credentials: Credentials;
22+
options: Options;
1523
};
1624

1725
const uploadStaticAssets = async (
18-
options: UploadStaticAssetsOptions
26+
config: UploadStaticAssetsOptions
1927
): Promise<AWS.S3.ManagedUpload.SendData[]> => {
20-
const { bucketName, nextConfigDir, nextStaticDir = nextConfigDir } = options;
28+
const { bucketName, nextConfigDir, nextStaticDir = nextConfigDir } = config;
2129
const s3 = await S3ClientFactory({
2230
bucketName,
23-
credentials: options.credentials
31+
credentials: config.credentials
2432
});
2533

2634
const dotNextDirectory = path.join(nextConfigDir, ".next");
@@ -66,7 +74,8 @@ const uploadStaticAssets = async (
6674
});
6775

6876
const uploadPublicOrStaticDirectory = async (
69-
directory: "public" | "static"
77+
directory: "public" | "static",
78+
options: Options
7079
): Promise<Promise<AWS.S3.ManagedUpload.SendData>[]> => {
7180
const directoryPath = path.join(nextStaticDir, directory);
7281
if (!(await fse.pathExists(directoryPath))) {
@@ -80,13 +89,23 @@ const uploadStaticAssets = async (
8089
filePath: fileItem.path,
8190
s3Key: pathToPosix(
8291
path.relative(path.resolve(nextStaticDir), fileItem.path)
92+
),
93+
cacheControl: getPublicAssetCacheControl(
94+
fileItem.path,
95+
options.publicAssetCache
8396
)
8497
})
8598
);
8699
};
87100

88-
const publicDirUploads = await uploadPublicOrStaticDirectory("public");
89-
const staticDirUploads = await uploadPublicOrStaticDirectory("static");
101+
const publicDirUploads = await uploadPublicOrStaticDirectory(
102+
"public",
103+
config.options
104+
);
105+
const staticDirUploads = await uploadPublicOrStaticDirectory(
106+
"static",
107+
config.options
108+
);
90109

91110
const allUploads = [
92111
...buildStaticFileUploads, // .next/static
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
export const IMMUTABLE_CACHE_CONTROL_HEADER =
22
"public, max-age=31536000, immutable";
3+
4+
export const DEFAULT_ASSET_CACHE_CONTROL_HEADER = "public, max-age=31536000, must-revalidate";
5+
export const DEFAULT_ASSET_CACHE_REGEX = /\.(gif|jpe?g|jp2|tiff|png|webp|bmp|svg)$/i;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import path from "path";
2+
import regexParser from "regex-parser";
3+
import {
4+
DEFAULT_ASSET_CACHE_CONTROL_HEADER,
5+
DEFAULT_ASSET_CACHE_REGEX
6+
} from "./constants";
7+
8+
export type PublicAssetCacheControl =
9+
| boolean
10+
| {
11+
test?: string;
12+
value?: string;
13+
};
14+
15+
const getPublicAssetCacheControl = (
16+
filePath: string,
17+
options?: PublicAssetCacheControl
18+
): string | undefined => {
19+
if (!options) {
20+
return undefined;
21+
}
22+
23+
let value: string = DEFAULT_ASSET_CACHE_CONTROL_HEADER;
24+
let test: RegExp = DEFAULT_ASSET_CACHE_REGEX;
25+
26+
if (typeof options === "object") {
27+
if (options.value) {
28+
value = options.value;
29+
}
30+
31+
if (options.test) {
32+
test = regexParser(options.test);
33+
}
34+
}
35+
36+
if (test.test(path.basename(filePath))) {
37+
return value;
38+
}
39+
40+
return undefined;
41+
};
42+
43+
export default getPublicAssetCacheControl;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"/todos/terms": "pages/todos/terms.html",
3+
"/todos/terms/[section]": "pages/todos/terms/[section].html"
4+
}

packages/s3-static-assets/tests/fixtures/app-with-images/.next/serverless/pages/todos/terms.html

Whitespace-only changes.

packages/s3-static-assets/tests/fixtures/app-with-images/.next/serverless/pages/todos/terms/[section].html

Whitespace-only changes.

packages/s3-static-assets/tests/fixtures/app-with-images/.next/static/a_test_build_id/css/one.css

Whitespace-only changes.

0 commit comments

Comments
 (0)