From 00023c24b66f7813cacb81e0ee2412636da04e00 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Wed, 18 Jan 2023 13:19:07 -0500 Subject: [PATCH] fix(core): avoid hash collision when generating chunk names (#8538) --- .../src/server/__tests__/routes.test.ts | 34 +++++++++++++++++++ packages/docusaurus/src/server/routes.ts | 8 ++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/docusaurus/src/server/__tests__/routes.test.ts b/packages/docusaurus/src/server/__tests__/routes.test.ts index 3f8197c990..f302b3c450 100644 --- a/packages/docusaurus/src/server/__tests__/routes.test.ts +++ b/packages/docusaurus/src/server/__tests__/routes.test.ts @@ -56,6 +56,40 @@ describe('genChunkName', () => { }); expect(genChunkName('d', undefined, undefined, true)).toBe('8277e091'); }); + + // https://github.com/facebook/docusaurus/issues/8536 + it('avoids hash collisions', () => { + expect( + genChunkName( + '@site/blog/2022-11-18-bye-medium/index.mdx?truncated=true', + 'content', + 'blog', + false, + ), + ).not.toBe( + genChunkName( + '@site/blog/2019-10-05-react-nfc/index.mdx?truncated=true', + 'content', + 'blog', + false, + ), + ); + expect( + genChunkName( + '@site/blog/2022-11-18-bye-medium/index.mdx?truncated=true', + 'content', + 'blog', + true, + ), + ).not.toBe( + genChunkName( + '@site/blog/2019-10-05-react-nfc/index.mdx?truncated=true', + 'content', + 'blog', + true, + ), + ); + }); }); describe('handleDuplicateRoutes', () => { diff --git a/packages/docusaurus/src/server/routes.ts b/packages/docusaurus/src/server/routes.ts index 6b731b7586..6a63fa71ca 100644 --- a/packages/docusaurus/src/server/routes.ts +++ b/packages/docusaurus/src/server/routes.ts @@ -51,6 +51,7 @@ function indent(str: string) { } const chunkNameCache = new Map(); +const chunkNameCount = new Map(); /** * Generates a unique chunk name that can be used in the chunk registry. @@ -79,10 +80,15 @@ export function genChunkName( const shortHash = simpleHash(modulePath, 3); str = `${preferredName}${shortHash}`; } - const name = str === '/' ? 'index' : docuHash(str); + const name = docuHash(str); chunkName = prefix ? `${prefix}---${name}` : name; } + const seenCount = (chunkNameCount.get(chunkName) ?? 0) + 1; + if (seenCount > 1) { + chunkName += seenCount.toString(36); + } chunkNameCache.set(modulePath, chunkName); + chunkNameCount.set(chunkName, seenCount); } return chunkName; }