diff --git a/packages/next/build/webpack/loaders/next-serverless-loader.ts b/packages/next/build/webpack/loaders/next-serverless-loader.ts index e905a6500695b..364bd279943dc 100644 --- a/packages/next/build/webpack/loaders/next-serverless-loader.ts +++ b/packages/next/build/webpack/loaders/next-serverless-loader.ts @@ -6,7 +6,6 @@ import { loader } from 'webpack' import { API_ROUTE } from '../../../lib/constants' import { BUILD_MANIFEST, - FONT_MANIFEST, REACT_LOADABLE_MANIFEST, ROUTES_MANIFEST, } from '../../../next-server/lib/constants' @@ -59,10 +58,6 @@ const nextServerlessLoader: loader.Loader = function () { '/' ) const routesManifest = join(distDir, ROUTES_MANIFEST).replace(/\\/g, '/') - const fontManifest = join(distDir, 'serverless', FONT_MANIFEST).replace( - /\\/g, - '/' - ) const escapedBuildId = escapeRegexp(buildId) const pageIsDynamicRoute = isDynamicRoute(page) @@ -441,7 +436,11 @@ const nextServerlessLoader: loader.Loader = function () { if (process.env.__NEXT_OPTIMIZE_FONTS) { renderOpts.optimizeFonts = true - renderOpts.fontManifest = require('${fontManifest}') + /** + * __webpack_require__.__NEXT_FONT_MANIFEST__ is added by + * font-stylesheet-gathering-plugin + */ + renderOpts.fontManifest = __webpack_require__.__NEXT_FONT_MANIFEST__; process.env['__NEXT_OPTIMIZE_FONT'+'S'] = true } let result = await renderToHTML(req, res, "${page}", Object.assign({}, getStaticProps ? { ...(parsedUrl.query.amp ? { amp: '1' } : {}) } : parsedUrl.query, nowParams ? nowParams : params, _params, isFallback ? { __nextFallback: 'true' } : {}), renderOpts) 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 7ffe92c0c309b..eaa224852d156 100644 --- a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts +++ b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts @@ -18,6 +18,7 @@ interface VisitorMap { export class FontStylesheetGatheringPlugin { compiler?: Compiler gatheredStylesheets: Array = [] + manifestContent: FontManifest = [] private parserHandler = ( factory: CompilationType.NormalModuleFactory @@ -102,22 +103,42 @@ export class FontStylesheetGatheringPlugin { this.parserHandler ) compiler.hooks.make.tapAsync(this.constructor.name, (compilation, cb) => { + // @ts-ignore + if (compilation.options.output.path.endsWith('serverless')) { + /** + * Inline font manifest for serverless case only. + * For target: server drive the manifest through physical file and less of webpack magic. + */ + const mainTemplate = compilation.mainTemplate + mainTemplate.hooks.requireExtensions.tap( + this.constructor.name, + (source: string) => { + return `${source} + // Font manifest declaration + ${ + mainTemplate.requireFn + }.__NEXT_FONT_MANIFEST__ = ${JSON.stringify( + this.manifestContent + )};` + } + ) + } compilation.hooks.finishModules.tapAsync( this.constructor.name, async (_: any, modulesFinished: Function) => { const fontDefinitionPromises = this.gatheredStylesheets.map((url) => getFontDefinitionFromNetwork(url) ) - let manifestContent: FontManifest = [] + this.manifestContent = [] for (let promiseIndex in fontDefinitionPromises) { - manifestContent.push({ + this.manifestContent.push({ url: this.gatheredStylesheets[promiseIndex], content: await fontDefinitionPromises[promiseIndex], }) } compilation.assets['font-manifest.json'] = new RawSource( - JSON.stringify(manifestContent, null, ' ') + JSON.stringify(this.manifestContent, null, ' ') ) modulesFinished() } diff --git a/test/integration/font-optimization/test/index.test.js b/test/integration/font-optimization/test/index.test.js index 49d66ee869f88..d1aa9fd66af5c 100644 --- a/test/integration/font-optimization/test/index.test.js +++ b/test/integration/font-optimization/test/index.test.js @@ -82,6 +82,10 @@ describe('Font optimization for SSR apps', () => { `module.exports = { experimental: {optimizeFonts: true} }`, 'utf8' ) + + if (fs.pathExistsSync(join(appDir, '.next'))) { + await fs.remove(join(appDir, '.next')) + } await nextBuild(appDir) appPort = await findPort() app = await nextStart(appDir, appPort) diff --git a/yarn.lock b/yarn.lock index 98be228a82242..d60891083747e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7807,6 +7807,11 @@ he@1.1.1: resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + header-case@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d"