From 9ec041efbf7c3e0ee0fb12bc0f6b0cd97786792c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Mon, 26 Sep 2022 21:59:38 +0200 Subject: [PATCH] Update font loader output path (#40868) Updates the output path so it's the same as when font files are imported in CSS: `url(./font.woff2)` Also adds missing font types to next package. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) --- .../webpack/loaders/next-font-loader/index.ts | 2 +- packages/next/package.json | 3 +- test/e2e/next-font/basepath.test.ts | 2 +- test/e2e/next-font/index.test.ts | 82 +++++++++---------- .../with-font-declarations-file.test.ts | 12 +-- test/unit/local-font-loader.test.ts | 32 ++++---- 6 files changed, 67 insertions(+), 66 deletions(-) diff --git a/packages/next/build/webpack/loaders/next-font-loader/index.ts b/packages/next/build/webpack/loaders/next-font-loader/index.ts index 7ca2455227b68..9ab979e69e4a3 100644 --- a/packages/next/build/webpack/loaders/next-font-loader/index.ts +++ b/packages/next/build/webpack/loaders/next-font-loader/index.ts @@ -22,7 +22,7 @@ export default async function nextFontLoader(this: any) { const interpolatedName = loaderUtils.interpolateName( this, // Font files ending with .p.(woff|woff2|eot|ttf|otf) are preloaded - `static/fonts/[hash]${preload ? '.p' : ''}.${ext}`, + `static/media/[hash]${preload ? '.p' : ''}.${ext}`, opts ) const outputPath = `${assetPrefix}/_next/${interpolatedName}` diff --git a/packages/next/package.json b/packages/next/package.json index e2cd9feec3862..f90ba894c2a53 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -47,7 +47,8 @@ "types/index.d.ts", "types/global.d.ts", "types/compiled.d.ts", - "image-types/global.d.ts" + "image-types/global.d.ts", + "font" ], "bin": { "next": "./dist/bin/next" diff --git a/test/e2e/next-font/basepath.test.ts b/test/e2e/next-font/basepath.test.ts index 0b6d242fc138a..bff516e58b6b0 100644 --- a/test/e2e/next-font/basepath.test.ts +++ b/test/e2e/next-font/basepath.test.ts @@ -46,7 +46,7 @@ describe('@next/font/google basepath', () => { expect($('link[as="font"]').get(0).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/dashboard/_next/static/fonts/0812efcfaefec5ea.p.woff2', + href: '/dashboard/_next/static/media/0812efcfaefec5ea.p.woff2', rel: 'preload', type: 'font/woff2', }) diff --git a/test/e2e/next-font/index.test.ts b/test/e2e/next-font/index.test.ts index 8795d7ead1e19..026d74fa5bedc 100644 --- a/test/e2e/next-font/index.test.ts +++ b/test/e2e/next-font/index.test.ts @@ -42,39 +42,39 @@ describe('@next/font/google', () => { // _app.js expect(JSON.parse($('#app-open-sans').text())).toEqual({ - className: '__className_bbc724', - variable: '__variable_bbc724', + className: '__className_f32d04', + variable: '__variable_f32d04', style: { - fontFamily: "'__Open_Sans_bbc724', '__open-sans-fallback_bbc724'", + fontFamily: "'__Open_Sans_f32d04', '__open-sans-fallback_f32d04'", fontStyle: 'normal', }, }) // with-fonts.js expect(JSON.parse($('#with-fonts-open-sans').text())).toEqual({ - className: '__className_bbc724', - variable: '__variable_bbc724', + className: '__className_f32d04', + variable: '__variable_f32d04', style: { - fontFamily: "'__Open_Sans_bbc724', '__open-sans-fallback_bbc724'", + fontFamily: "'__Open_Sans_f32d04', '__open-sans-fallback_f32d04'", fontStyle: 'normal', }, }) // CompWithFonts.js expect(JSON.parse($('#comp-with-fonts-inter').text())).toEqual({ - className: '__className_17e98a', - variable: '__variable_17e98a', + className: '__className_55e413', + variable: '__variable_55e413', style: { - fontFamily: "'__Inter_17e98a', '__inter-fallback_17e98a'", + fontFamily: "'__Inter_55e413', '__inter-fallback_55e413'", fontStyle: 'normal', fontWeight: 900, }, }) expect(JSON.parse($('#comp-with-fonts-roboto').text())).toEqual({ - className: '__className_72084b', - variable: '__variable_72084b', + className: '__className_29a3c6', + variable: '__variable_29a3c6', style: { - fontFamily: "'__Roboto_72084b', '__roboto-fallback_72084b'", + fontFamily: "'__Roboto_29a3c6', '__roboto-fallback_29a3c6'", fontStyle: 'italic', fontWeight: 100, }, @@ -87,29 +87,29 @@ describe('@next/font/google', () => { // _app.js expect(JSON.parse($('#app-open-sans').text())).toEqual({ - className: expect.any(String), - variable: expect.any(String), + className: '__className_f32d04', + variable: '__variable_f32d04', style: { - fontFamily: "'__Open_Sans_bbc724', '__open-sans-fallback_bbc724'", + fontFamily: "'__Open_Sans_f32d04', '__open-sans-fallback_f32d04'", fontStyle: 'normal', }, }) // with-local-fonts.js expect(JSON.parse($('#first-local-font').text())).toEqual({ - className: expect.any(String), - variable: expect.any(String), + className: '__className_410624', + variable: '__variable_410624', style: { - fontFamily: "'__my-font_2cddd5'", + fontFamily: "'__my-font_410624'", fontStyle: 'italic', fontWeight: 100, }, }) expect(JSON.parse($('#second-local-font').text())).toEqual({ - className: expect.any(String), - variable: expect.any(String), + className: '__className_3ff726', + variable: '__variable_3ff726', style: { - fontFamily: "'__my-other-font_0a2813'", + fontFamily: "'__my-other-font_3ff726'", }, }) }) @@ -124,7 +124,7 @@ describe('@next/font/google', () => { await browser.eval( 'getComputedStyle(document.querySelector("#app-open-sans")).fontFamily' ) - ).toBe('__Open_Sans_bbc724, __open-sans-fallback_bbc724') + ).toBe('__Open_Sans_f32d04, __open-sans-fallback_f32d04') expect( await browser.eval( 'getComputedStyle(document.querySelector("#app-open-sans")).fontWeight' @@ -141,7 +141,7 @@ describe('@next/font/google', () => { await browser.eval( 'getComputedStyle(document.querySelector("#with-fonts-open-sans")).fontFamily' ) - ).toBe('__Open_Sans_bbc724, __open-sans-fallback_bbc724') + ).toBe('__Open_Sans_f32d04, __open-sans-fallback_f32d04') expect( await browser.eval( 'getComputedStyle(document.querySelector("#with-fonts-open-sans")).fontWeight' @@ -168,7 +168,7 @@ describe('@next/font/google', () => { await browser.eval( 'getComputedStyle(document.querySelector("#comp-with-fonts-inter")).fontFamily' ) - ).toBe('__Inter_17e98a, __inter-fallback_17e98a') + ).toBe('__Inter_55e413, __inter-fallback_55e413') expect( await browser.eval( 'getComputedStyle(document.querySelector("#comp-with-fonts-inter")).fontWeight' @@ -184,7 +184,7 @@ describe('@next/font/google', () => { await browser.eval( 'getComputedStyle(document.querySelector("#comp-with-fonts-roboto")).fontFamily' ) - ).toBe('__Roboto_72084b, __roboto-fallback_72084b') + ).toBe('__Roboto_29a3c6, __roboto-fallback_29a3c6') expect( await browser.eval( 'getComputedStyle(document.querySelector("#comp-with-fonts-roboto")).fontWeight' @@ -205,48 +205,48 @@ describe('@next/font/google', () => { await browser.eval( 'getComputedStyle(document.querySelector("#variables-fira-code")).fontFamily' ) - ).toBe('__Fira_Code_a1dc08, __fira-code-fallback_a1dc08') + ).toBe('__Fira_Code_8d0076, __fira-code-fallback_8d0076') expect( await browser.eval( 'getComputedStyle(document.querySelector("#without-variables-fira-code")).fontFamily' ) - ).not.toBe('__Fira_Code_a1dc08, __fira-code-fallback_a1dc08') + ).not.toBe('__Fira_Code_8d0076, __fira-code-fallback_8d0076') // Albert Sant Variable Italic expect( await browser.eval( 'getComputedStyle(document.querySelector("#variables-albert-sans-italic")).fontFamily' ) - ).toBe('__Albert_Sans_2b85d2') + ).toBe('__Albert_Sans_3a491b') expect( await browser.eval( 'getComputedStyle(document.querySelector("#without-variables-albert-sans-italic")).fontFamily' ) - ).not.toBe('__Albert_Sans_2b85d2') + ).not.toBe('__Albert_Sans_3a491b') // Inter 900 expect( await browser.eval( 'getComputedStyle(document.querySelector("#variables-inter-900")).fontFamily' ) - ).toBe('__Inter_ea3712, __inter-fallback_ea3712') + ).toBe('__Inter_09d70c, __inter-fallback_09d70c') expect( await browser.eval( 'getComputedStyle(document.querySelector("#without-variables-inter-900")).fontFamily' ) - ).not.toBe('__Inter_ea3712, __inter-fallback_ea3712') + ).not.toBe('__Inter_09d70c, __inter-fallback_09d70c') // Roboto 100 Italic expect( await browser.eval( 'getComputedStyle(document.querySelector("#variables-roboto-100-italic")).fontFamily' ) - ).toBe('__Roboto_72084b, __roboto-fallback_72084b') + ).toBe('__Roboto_29a3c6, __roboto-fallback_29a3c6') expect( await browser.eval( 'getComputedStyle(document.querySelector("#without-variables-roboto-100-italic")).fontFamily' ) - ).not.toBe('__Roboto_72084b') + ).not.toBe('__Roboto_29a3c6, __roboto-fallback_29a3c6') }) test('page using fallback fonts', async () => { @@ -258,7 +258,7 @@ describe('@next/font/google', () => { 'getComputedStyle(document.querySelector("#with-fallback-fonts-classname")).fontFamily' ) ).toBe( - '__Open_Sans_bbc724, system-ui, Arial, __open-sans-fallback_bbc724' + '__Open_Sans_f32d04, system-ui, Arial, __open-sans-fallback_f32d04' ) // .style @@ -267,7 +267,7 @@ describe('@next/font/google', () => { 'getComputedStyle(document.querySelector("#with-fallback-fonts-style")).fontFamily' ) ).toBe( - '__Open_Sans_bbc724, system-ui, Arial, __open-sans-fallback_bbc724' + '__Open_Sans_f32d04, system-ui, Arial, __open-sans-fallback_f32d04' ) // .variable @@ -276,7 +276,7 @@ describe('@next/font/google', () => { 'getComputedStyle(document.querySelector("#with-fallback-fonts-variable")).fontFamily' ) ).toBe( - '__Open_Sans_bbc724, system-ui, Arial, __open-sans-fallback_bbc724' + '__Open_Sans_f32d04, system-ui, Arial, __open-sans-fallback_f32d04' ) }) }) @@ -294,14 +294,14 @@ describe('@next/font/google', () => { expect($('link[as="font"]').get(0).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/0812efcfaefec5ea.p.woff2', + href: '/_next/static/media/0812efcfaefec5ea.p.woff2', rel: 'preload', type: 'font/woff2', }) expect($('link[as="font"]').get(1).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/4f3dcdf40b3ca86d.p.woff2', + href: '/_next/static/media/4f3dcdf40b3ca86d.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -319,7 +319,7 @@ describe('@next/font/google', () => { expect($('link[as="font"]').get(0).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/0812efcfaefec5ea.p.woff2', + href: '/_next/static/media/0812efcfaefec5ea.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -338,7 +338,7 @@ describe('@next/font/google', () => { expect($('link[as="font"]').get(0).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/0812efcfaefec5ea.p.woff2', + href: '/_next/static/media/0812efcfaefec5ea.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -346,7 +346,7 @@ describe('@next/font/google', () => { expect($('link[as="font"]').get(1).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/7be88d77534e80fd.p.woff2', + href: '/_next/static/media/7be88d77534e80fd.p.woff2', rel: 'preload', type: 'font/woff2', }) diff --git a/test/e2e/next-font/with-font-declarations-file.test.ts b/test/e2e/next-font/with-font-declarations-file.test.ts index ef62aad0fb9b9..80b3130178af1 100644 --- a/test/e2e/next-font/with-font-declarations-file.test.ts +++ b/test/e2e/next-font/with-font-declarations-file.test.ts @@ -64,7 +64,7 @@ describe('@next/font/google with-font-declarations-file', () => { expect($('link[as="font"]').get(0).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/0812efcfaefec5ea.p.woff2', + href: '/_next/static/media/0812efcfaefec5ea.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -72,7 +72,7 @@ describe('@next/font/google with-font-declarations-file', () => { expect($('link[as="font"]').get(1).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/4a7f86e553ee7e51.p.woff2', + href: '/_next/static/media/4a7f86e553ee7e51.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -96,7 +96,7 @@ describe('@next/font/google with-font-declarations-file', () => { expect($('link[as="font"]').get(0).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/0812efcfaefec5ea.p.woff2', + href: '/_next/static/media/0812efcfaefec5ea.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -104,7 +104,7 @@ describe('@next/font/google with-font-declarations-file', () => { expect($('link[as="font"]').get(1).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/9a7e84b4dd095b33.p.woff2', + href: '/_next/static/media/9a7e84b4dd095b33.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -128,7 +128,7 @@ describe('@next/font/google with-font-declarations-file', () => { expect($('link[as="font"]').get(0).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/0812efcfaefec5ea.p.woff2', + href: '/_next/static/media/0812efcfaefec5ea.p.woff2', rel: 'preload', type: 'font/woff2', }) @@ -136,7 +136,7 @@ describe('@next/font/google with-font-declarations-file', () => { expect($('link[as="font"]').get(1).attribs).toEqual({ as: 'font', crossorigin: 'anonymous', - href: '/_next/static/fonts/2a931eed088772c9.p.woff2', + href: '/_next/static/media/2a931eed088772c9.p.woff2', rel: 'preload', type: 'font/woff2', }) diff --git a/test/unit/local-font-loader.test.ts b/test/unit/local-font-loader.test.ts index 892ce9aa00dcf..b314024d8de38 100644 --- a/test/unit/local-font-loader.test.ts +++ b/test/unit/local-font-loader.test.ts @@ -7,7 +7,7 @@ describe('@next/font/local', () => { functionName: '', data: [{ src: './my-font.woff2' }], config: {}, - emitFontFile: () => '/_next/static/fonts/my-font.woff2', + emitFontFile: () => '/_next/static/media/my-font.woff2', resolve: jest.fn(), fs: { readFile: (_, cb) => cb(null, 'fontdata'), @@ -17,7 +17,7 @@ describe('@next/font/local', () => { expect(css).toMatchInlineSnapshot(` "@font-face { font-family: 'my-font'; -src: url(/_next/static/fonts/my-font.woff2) format('woff2'); +src: url(/_next/static/media/my-font.woff2) format('woff2'); font-display: optional; }" `) @@ -30,7 +30,7 @@ font-display: optional; { src: [{ file: './my-font.woff2', unicodeRange: 'unicode-range' }] }, ], config: {}, - emitFontFile: () => '/_next/static/fonts/my-font.woff2', + emitFontFile: () => '/_next/static/media/my-font.woff2', resolve: jest.fn(), fs: { readFile: (_, cb) => cb(null, 'fontdata'), @@ -40,7 +40,7 @@ font-display: optional; expect(css).toMatchInlineSnapshot(` "@font-face { font-family: 'my-font'; -src: url(/_next/static/fonts/my-font.woff2) format('woff2'); +src: url(/_next/static/media/my-font.woff2) format('woff2'); font-display: optional; unicode-range: unicode-range; }" @@ -52,7 +52,7 @@ unicode-range: unicode-range; functionName: '', data: [{ src: [{ file: './my-font.woff2' }] }], config: {}, - emitFontFile: () => '/_next/static/fonts/my-font.woff2', + emitFontFile: () => '/_next/static/media/my-font.woff2', resolve: jest.fn(), fs: { readFile: (_, cb) => cb(null, 'fontdata'), @@ -62,7 +62,7 @@ unicode-range: unicode-range; expect(css).toMatchInlineSnapshot(` "@font-face { font-family: 'my-font'; -src: url(/_next/static/fonts/my-font.woff2) format('woff2'); +src: url(/_next/static/media/my-font.woff2) format('woff2'); font-display: optional; }" `) @@ -73,7 +73,7 @@ font-display: optional; functionName: '', data: [{ src: './my-font.woff2', weight: '100 900', style: 'italic' }], config: {}, - emitFontFile: () => '/_next/static/fonts/my-font.woff2', + emitFontFile: () => '/_next/static/media/my-font.woff2', resolve: jest.fn(), fs: { readFile: (_, cb) => cb(null, 'fontdata'), @@ -83,7 +83,7 @@ font-display: optional; expect(css).toMatchInlineSnapshot(` "@font-face { font-family: 'my-font'; -src: url(/_next/static/fonts/my-font.woff2) format('woff2'); +src: url(/_next/static/media/my-font.woff2) format('woff2'); font-display: optional; font-weight: 100 900; font-style: italic; @@ -108,7 +108,7 @@ font-style: italic; }, ], config: {}, - emitFontFile: () => '/_next/static/fonts/my-font.woff2', + emitFontFile: () => '/_next/static/media/my-font.woff2', resolve: jest.fn(), fs: { readFile: (_, cb) => cb(null, 'fontdata'), @@ -118,7 +118,7 @@ font-style: italic; expect(css).toMatchInlineSnapshot(` "@font-face { font-family: 'my-font'; -src: url(/_next/static/fonts/my-font.woff2) format('woff2'); +src: url(/_next/static/media/my-font.woff2) format('woff2'); font-display: optional; font-weight: 100 900; font-style: italic; @@ -147,7 +147,7 @@ size-adjust: sizeAdjust; }, ], config: {}, - emitFontFile: () => `/_next/static/fonts/font-file`, + emitFontFile: () => `/_next/static/media/font-file`, resolve: jest.fn(), fs: { readFile: (_, cb) => cb(null, 'fontdata'), @@ -157,31 +157,31 @@ size-adjust: sizeAdjust; expect(css).toMatchInlineSnapshot(` "@font-face { font-family: 'my-font1'; -src: url(/_next/static/fonts/font-file) format('woff'); +src: url(/_next/static/media/font-file) format('woff'); font-display: optional; unicode-range: 1; } @font-face { font-family: 'my-font1'; -src: url(/_next/static/fonts/font-file) format('woff2'); +src: url(/_next/static/media/font-file) format('woff2'); font-display: optional; unicode-range: 2; } @font-face { font-family: 'my-font1'; -src: url(/_next/static/fonts/font-file) format('embedded-opentype'); +src: url(/_next/static/media/font-file) format('embedded-opentype'); font-display: optional; unicode-range: 3; } @font-face { font-family: 'my-font1'; -src: url(/_next/static/fonts/font-file) format('truetype'); +src: url(/_next/static/media/font-file) format('truetype'); font-display: optional; unicode-range: 4; } @font-face { font-family: 'my-font1'; -src: url(/_next/static/fonts/font-file) format('opentype'); +src: url(/_next/static/media/font-file) format('opentype'); font-display: optional; unicode-range: 5; }"