From 515ab59fafee3da2b819d482f65db9710e200bb7 Mon Sep 17 00:00:00 2001 From: Vio Date: Wed, 14 Feb 2024 22:11:52 +0100 Subject: [PATCH 1/2] feat(utils): Asset names - extract hash from nextjs manifest paths --- .../webpack/__tests__/utils-get-asset-name.ts | 11 ++++++++++- packages/utils/src/webpack/utils.ts | 16 ++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts b/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts index 4bef95ec06..5ffea71c5d 100644 --- a/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts +++ b/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts @@ -50,10 +50,19 @@ describe('Webpack/utils/getAssetName', () => { expect(getAssetName('login-abcde-chunk.js')).toBe('login-abcde-chunk.js'); }); - test('should remove the hash when it is provided as a slug', () => { + test('should remove the hash when it is provided as a slug inside a static folder', () => { expect(getAssetName('static/d2490/pages/app.js')).toBe('static/pages/app.js'); }); + test('should remove base64 hash when matching next manifests', () => { + expect(getAssetName('static/JyGdYu5ApqW15bVPkT0MK/_buildManifest.js')).toBe( + 'static/_buildManifest.js', + ); + expect(getAssetName('static/gzzXRvk7zbHlZFnyz0PfQ/_ssgManifest.js')).toBe( + 'static/_ssgManifest.js', + ); + }); + test('should not remove hash when it is provided as filename', () => { expect(getAssetName('static/chunks/d249062c08abb6b31a03.js')).toBe( 'static/chunks/d249062c08abb6b31a03.js', diff --git a/packages/utils/src/webpack/utils.ts b/packages/utils/src/webpack/utils.ts index 001523151d..070df68c3e 100644 --- a/packages/utils/src/webpack/utils.ts +++ b/packages/utils/src/webpack/utils.ts @@ -16,14 +16,22 @@ const BASE64URL_SEPARATOR_PATTERN = '[.~]'; const EXTENSION_PATTERN = /(?:\.[a-z0-9]{2,}){1,}/; const PATTERNS = [ - // Match path/name-HEXHASH.EXT, path/name.HEXHASH.EXT, path/name_HEXHASH.EXT, path/name-HEXHASH.chunk.EXT + // Match path/name-HEXHASH.EXT, + // path/name.HEXHASH.EXT, + // path/name_HEXHASH.EXT, + // path/name-HEXHASH.chunk.EXT `(.*)${HEX_HASH_SEPARATOR_PATTERN}${HEX_HASH_PATTERN}(${EXTENSION_PATTERN.source})$`, - // Match static/HASH.ext + // Match path/name-BASE64URLHASH.EXT, + // path/name.BASE64URLHASH.EXT, + // path/name_BASE64URLHASH.EXT, + // path/name-BASE64URLHASH.chunk.EXT + `(.*)${BASE64URL_SEPARATOR_PATTERN}${BASE64URL_HASH_PATTERN}(${EXTENSION_PATTERN.source})$`, + // Match static/HEXHASH.ext `(static)/${HEX_HASH_PATTERN}(.*${EXTENSION_PATTERN.source})$`, - // Match path/name-BASE64URLHASH.EXT, path/name.BASE64URLHASH.EXT, path/name_BASE64URLHASH.EXT, path/name-BASE64URLHASH.chunk.EXT - `(.*)${BASE64URL_SEPARATOR_PATTERN}${BASE64URL_HASH_PATTERN}(${EXTENSION_PATTERN.source})$`, + // Match static/HEXHASH/_name.ext + `(static)/${BASE64URL_HASH_PATTERN}(/_.*${EXTENSION_PATTERN.source})$`, ].map((pattern) => new RegExp(pattern)); const NO_BASENAME = /(^|.*\/)\..*$/; From 0c5f8624bdb0c0815de1e37cbece9d577dd62779 Mon Sep 17 00:00:00 2001 From: Vio Date: Wed, 14 Feb 2024 22:18:02 +0100 Subject: [PATCH 2/2] fix(utils: Asset names - output hashed directory --- .../webpack/__tests__/utils-get-asset-name.ts | 4 +-- packages/utils/src/webpack/utils.ts | 32 +++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts b/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts index 5ffea71c5d..d5ac71496f 100644 --- a/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts +++ b/packages/utils/src/webpack/__tests__/utils-get-asset-name.ts @@ -56,10 +56,10 @@ describe('Webpack/utils/getAssetName', () => { test('should remove base64 hash when matching next manifests', () => { expect(getAssetName('static/JyGdYu5ApqW15bVPkT0MK/_buildManifest.js')).toBe( - 'static/_buildManifest.js', + 'static/[hash]/_buildManifest.js', ); expect(getAssetName('static/gzzXRvk7zbHlZFnyz0PfQ/_ssgManifest.js')).toBe( - 'static/_ssgManifest.js', + 'static/[hash]/_ssgManifest.js', ); }); diff --git a/packages/utils/src/webpack/utils.ts b/packages/utils/src/webpack/utils.ts index 070df68c3e..9137a21bf4 100644 --- a/packages/utils/src/webpack/utils.ts +++ b/packages/utils/src/webpack/utils.ts @@ -20,19 +20,36 @@ const PATTERNS = [ // path/name.HEXHASH.EXT, // path/name_HEXHASH.EXT, // path/name-HEXHASH.chunk.EXT - `(.*)${HEX_HASH_SEPARATOR_PATTERN}${HEX_HASH_PATTERN}(${EXTENSION_PATTERN.source})$`, + { + pattern: new RegExp( + `(.*)${HEX_HASH_SEPARATOR_PATTERN}${HEX_HASH_PATTERN}(${EXTENSION_PATTERN.source})$`, + ), + replace: '$1$2', + }, // Match path/name-BASE64URLHASH.EXT, // path/name.BASE64URLHASH.EXT, // path/name_BASE64URLHASH.EXT, // path/name-BASE64URLHASH.chunk.EXT - `(.*)${BASE64URL_SEPARATOR_PATTERN}${BASE64URL_HASH_PATTERN}(${EXTENSION_PATTERN.source})$`, + { + pattern: new RegExp( + `(.*)${BASE64URL_SEPARATOR_PATTERN}${BASE64URL_HASH_PATTERN}(${EXTENSION_PATTERN.source})$`, + ), + replace: '$1$2', + }, + // Match static/HEXHASH.ext - `(static)/${HEX_HASH_PATTERN}(.*${EXTENSION_PATTERN.source})$`, + { + pattern: new RegExp(`(static)/${HEX_HASH_PATTERN}(.*${EXTENSION_PATTERN.source})$`), + replace: '$1$2', + }, // Match static/HEXHASH/_name.ext - `(static)/${BASE64URL_HASH_PATTERN}(/_.*${EXTENSION_PATTERN.source})$`, -].map((pattern) => new RegExp(pattern)); + { + pattern: new RegExp(`(static)/${BASE64URL_HASH_PATTERN}/(_.*${EXTENSION_PATTERN.source})$`), + replace: '$1/[hash]/$2', + }, +]; const NO_BASENAME = /(^|.*\/)\..*$/; @@ -45,8 +62,9 @@ export const getAssetName = (statsAssetPath?: string | null): string => { } for (let i = 0; i < PATTERNS.length; i += 1) { - const pattern = PATTERNS[i]; - const extracted: string = statsAssetPath.replace(pattern, '$1$2'); + const { pattern, replace } = PATTERNS[i]; + + const extracted: string = statsAssetPath.replace(pattern, replace); if (extracted && extracted !== statsAssetPath && !NO_BASENAME.test(extracted)) { return extracted;