Skip to content

Commit 385edb9

Browse files
authored
Add charset to contentType when supported (#226)
1 parent 0a8e09f commit 385edb9

File tree

4 files changed

+54
-28
lines changed

4 files changed

+54
-28
lines changed

packages/deploy-trigger/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
"postpack": "rm ./LICENSE ./third-party-licenses.txt"
1717
},
1818
"dependencies": {
19-
"mime": "^2.4.6"
19+
"mime-types": "^2.1.33"
2020
},
2121
"devDependencies": {
2222
"@types/archiver": "^5.1.0",
2323
"@types/aws-lambda": "^8.10.76",
24-
"@types/mime": "^2.0.2",
24+
"@types/mime-types": "^2.1.1",
2525
"@types/tmp": "^0.2.0",
2626
"@types/unzipper": "^0.10.3",
2727
"@vercel/ncc": "^0.27.0",

packages/deploy-trigger/src/__test__/deploy-trigger.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,17 @@ describe('deploy-trigger', () => {
9090
.getObject({ Bucket: targetBucket.bucketName, Key: staticRouteKey })
9191
.promise();
9292

93-
expect(staticRouteObject.ContentType).toBe('text/html');
93+
expect(staticRouteObject.ContentType).toBe('text/html; charset=utf-8');
9494
expect(staticRouteObject.CacheControl).toBe(
9595
'public,max-age=0,must-revalidate,s-maxage=31536000'
9696
);
9797

9898
const staticAssetObject = await s3
9999
.getObject({ Bucket: targetBucket.bucketName, Key: staticAssetKey })
100100
.promise();
101-
expect(staticAssetObject.ContentType).toBe('application/javascript');
101+
expect(staticAssetObject.ContentType).toBe(
102+
'application/javascript; charset=utf-8'
103+
);
102104
expect(staticAssetObject.CacheControl).toBe(
103105
'public,max-age=31536000,immutable'
104106
);

packages/deploy-trigger/src/deploy-trigger.ts

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
import { S3 } from 'aws-sdk';
22
import unzipper from 'unzipper';
3-
import { getType } from 'mime';
3+
import {
4+
lookup as mimeLookup,
5+
contentType as mimeContentType,
6+
} from 'mime-types';
47

58
import { deploymentConfigurationKey } from './constants';
69
import { generateRandomBuildId } from './utils';
710
import { FileResult } from './types';
811

912
// Metadata Key where the buildId is stored
1013
const BuildIdMetaDataKey = 'x-amz-meta-tf-next-build-id';
11-
// Immutable files like css, js, images with hashed file names
14+
15+
/**
16+
* Cache control header for immutable files that are stored in _next/static
17+
*/
1218
const CacheControlImmutable = 'public,max-age=31536000,immutable';
13-
// Static pre-rendered HTML routes
14-
// -
15-
// Must be refetched by the browser every time (max-age=0)
16-
// But CloudFront CDN can hold the copy infinite time until a invalidation
17-
// removes it (s-maxage=31536000)
18-
// https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html#ExpirationDownloadDist
19-
const CacheControlStaticHtml =
20-
'public,max-age=0,must-revalidate,s-maxage=31536000';
19+
20+
/**
21+
* Static files that have no hashed filenames
22+
*
23+
* Must be refetched by the browser every time (max-age=0).
24+
* But CloudFront CDN can hold the copy infinite time until a invalidation
25+
* removes it (s-maxage=31536000).
26+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html#ExpirationDownloadDist
27+
*/
28+
const CacheControlStatic = 'public,max-age=0,must-revalidate,s-maxage=31536000';
2129

2230
interface Props {
2331
s3: S3;
@@ -77,17 +85,26 @@ export async function deployTrigger({
7785
// Get ContentType
7886
// Static pre-rendered pages have no file extension,
7987
// files without extension get HTML mime type as fallback
80-
const ContentType = getType(fileName) || 'text/html';
88+
const mimeType = mimeLookup(fileName);
89+
const contentType =
90+
typeof mimeType === 'string' ? mimeContentType(mimeType) : false;
91+
92+
// When the file is static (served from /_next/*) then it has immutable
93+
// client - side caching).
94+
// Otherwise it is only immutable on the CDN
95+
const cacheControl = fileName.startsWith('_next/')
96+
? CacheControlImmutable
97+
: CacheControlStatic;
8198

8299
const uploadParams: S3.Types.PutObjectRequest = {
83100
Bucket: deployBucket,
84101
Key: fileName,
85102
Body: entry,
86-
ContentType,
87-
CacheControl:
88-
ContentType === 'text/html'
89-
? CacheControlStaticHtml
90-
: CacheControlImmutable,
103+
ContentType:
104+
typeof contentType === 'string'
105+
? contentType
106+
: 'text/html; charset=utf-8',
107+
CacheControl: cacheControl,
91108
};
92109

93110
// Sorry, but you cannot override the manifest

yarn.lock

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -956,10 +956,10 @@
956956
jest-diff "^27.0.0"
957957
pretty-format "^27.0.0"
958958

959-
"@types/mime@^2.0.2":
960-
version "2.0.2"
961-
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5"
962-
integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q==
959+
"@types/mime-types@^2.1.1":
960+
version "2.1.1"
961+
resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.1.tgz#d9ba43490fa3a3df958759adf69396c3532cf2c1"
962+
integrity sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==
963963

964964
"@types/minimatch@*":
965965
version "3.0.3"
@@ -3173,17 +3173,24 @@ mime-db@1.44.0:
31733173
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
31743174
integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
31753175

3176+
mime-db@1.50.0:
3177+
version "1.50.0"
3178+
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f"
3179+
integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==
3180+
31763181
mime-types@^2.1.12:
31773182
version "2.1.27"
31783183
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
31793184
integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
31803185
dependencies:
31813186
mime-db "1.44.0"
31823187

3183-
mime@^2.4.6:
3184-
version "2.4.6"
3185-
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1"
3186-
integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==
3188+
mime-types@^2.1.33:
3189+
version "2.1.33"
3190+
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb"
3191+
integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==
3192+
dependencies:
3193+
mime-db "1.50.0"
31873194

31883195
mimic-fn@^2.1.0:
31893196
version "2.1.0"

0 commit comments

Comments
 (0)