From de42719619ae69fbd88e445100f15701f6e1e100 Mon Sep 17 00:00:00 2001 From: Janicklas Ralph Date: Wed, 19 May 2021 03:05:12 -0700 Subject: [PATCH] Fix font optimization failing on some builds (#25071) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../font-stylesheet-gathering-plugin.ts | 34 +++++++++++++++++-- .../font-optimization/test/index.test.js | 21 ++++++++---- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts index c3964989acff3..043c09ca91b29 100644 --- a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts +++ b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts @@ -114,7 +114,19 @@ export class FontStylesheetGatheringPlugin { } this.gatheredStylesheets.push(props.href) + + if (isWebpack5) { + const buildInfo = parser?.state?.module?.buildInfo + + if (buildInfo) { + buildInfo.valueDependencies.set( + FONT_MANIFEST, + this.gatheredStylesheets + ) + } + } } + // React JSX transform: parser.hooks.call .for('_jsx') @@ -161,8 +173,24 @@ export class FontStylesheetGatheringPlugin { } compilation.hooks.finishModules.tapAsync( this.constructor.name, - async (_: any, modulesFinished: Function) => { - const fontDefinitionPromises = this.gatheredStylesheets.map((url) => + async (modules: any, modulesFinished: Function) => { + let fontStylesheets = this.gatheredStylesheets + + if (isWebpack5) { + const fontUrls = new Set() + modules.forEach((module: any) => { + const fontDependencies = module?.buildInfo?.valueDependencies?.get( + FONT_MANIFEST + ) + if (fontDependencies) { + fontDependencies.forEach((v: string) => fontUrls.add(v)) + } + }) + + fontStylesheets = Array.from(fontUrls) + } + + const fontDefinitionPromises = fontStylesheets.map((url) => getFontDefinitionFromNetwork(url) ) @@ -173,7 +201,7 @@ export class FontStylesheetGatheringPlugin { if (css) { const content = await minifyCss(css) this.manifestContent.push({ - url: this.gatheredStylesheets[promiseIndex], + url: fontStylesheets[promiseIndex], content, }) } diff --git a/test/integration/font-optimization/test/index.test.js b/test/integration/font-optimization/test/index.test.js index aa4a5f775ebec..da01c47350f83 100644 --- a/test/integration/font-optimization/test/index.test.js +++ b/test/integration/font-optimization/test/index.test.js @@ -210,15 +210,22 @@ describe('Font Optimization', () => { expect(testCss).toStrictEqual(snapshotCss) }) + + // Re-run build to check if it works when build is cached + it('should work when build is cached', async () => { + await nextBuild(appDir) + const testJson = JSON.parse( + await fs.readFile(builtPage('font-manifest.json'), { + encoding: 'utf-8', + }) + ) + expect(testJson.length).toBeGreaterThan(0) + }) } describe('Font optimization for SSR apps', () => { beforeAll(async () => { - await fs.writeFile( - nextConfig, - `module.exports = { experimental: {optimizeFonts: true} }`, - 'utf8' - ) + await fs.writeFile(nextConfig, `module.exports = { }`, 'utf8') if (fs.pathExistsSync(join(appDir, '.next'))) { await fs.remove(join(appDir, '.next')) @@ -237,7 +244,7 @@ describe('Font Optimization', () => { beforeAll(async () => { await fs.writeFile( nextConfig, - `module.exports = { target: 'serverless', experimental: {optimizeFonts: true} }`, + `module.exports = { target: 'serverless' }`, 'utf8' ) await nextBuild(appDir) @@ -254,7 +261,7 @@ describe('Font Optimization', () => { beforeAll(async () => { await fs.writeFile( nextConfig, - `module.exports = { target: 'experimental-serverless-trace', experimental: {optimizeFonts: true} }`, + `module.exports = { target: 'experimental-serverless-trace' }`, 'utf8' ) await nextBuild(appDir)