Skip to content

Commit

Permalink
Font loaders next config shape (vercel#41219)
Browse files Browse the repository at this point in the history
Changes how font loaders are configured in next config, makes more sense since options can be optional. Also adds error for when font loaders are used from within node_modules.

## 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)
  • Loading branch information
Hannes Bornö authored and Kikobeats committed Oct 24, 2022
1 parent ea466c4 commit 766fd8e
Show file tree
Hide file tree
Showing 15 changed files with 92 additions and 46 deletions.
2 changes: 1 addition & 1 deletion packages/font/google/index.js
@@ -1 +1 @@
throw new Error('@next/font/google is not correctly setup')
throw new Error('@next/font/google is not correctly configured')
2 changes: 1 addition & 1 deletion packages/font/local/index.js
@@ -1 +1 @@
throw new Error('@next/font/local is not correctly setup')
throw new Error('@next/font/local is not correctly configured')
4 changes: 3 additions & 1 deletion packages/next/build/swc/options.js
Expand Up @@ -134,7 +134,9 @@ function getBaseSWCOptions({
fontLoaders:
nextConfig?.experimental?.fontLoaders && relativeFilePathFromRoot
? {
fontLoaders: Object.keys(nextConfig.experimental.fontLoaders),
fontLoaders: nextConfig.experimental.fontLoaders.map(
({ loader }) => loader
),
relativeFilePathFromRoot,
}
: null,
Expand Down
4 changes: 2 additions & 2 deletions packages/next/build/webpack-config.ts
Expand Up @@ -1202,8 +1202,8 @@ export default async function getBaseWebpackConfig(

const fontLoaderTargets =
config.experimental.fontLoaders &&
Object.keys(config.experimental.fontLoaders).map((fontLoader) => {
const resolved = require.resolve(fontLoader)
config.experimental.fontLoaders.map(({ loader }) => {
const resolved = require.resolve(loader)
return path.join(resolved, '../target.css')
})

Expand Down
27 changes: 21 additions & 6 deletions packages/next/build/webpack/config/blocks/css/index.ts
Expand Up @@ -11,6 +11,7 @@ import {
getGlobalModuleImportError,
getLocalModuleImportError,
getFontLoaderDocumentImportError,
getFontLoaderImportError,
} from './messages'
import { getPostCssPlugins } from './plugins'

Expand Down Expand Up @@ -183,12 +184,10 @@ export const css = curry(async function css(

// Resolve the configured font loaders, the resolved files are noop files that next-font-loader will match
let fontLoaders: [string, string][] | undefined = ctx.experimental.fontLoaders
? Object.entries(ctx.experimental.fontLoaders).map(
([fontLoader, fontLoaderOptions]: any) => [
path.join(require.resolve(fontLoader), '../target.css'),
fontLoaderOptions,
]
)
? ctx.experimental.fontLoaders.map(({ loader: fontLoader, options }) => [
path.join(require.resolve(fontLoader), '../target.css'),
options,
])
: undefined

// Font loaders cannot be imported in _document.
Expand Down Expand Up @@ -232,6 +231,22 @@ export const css = curry(async function css(
],
})
)

fns.push(
loader({
oneOf: [
markRemovable({
test: fontLoaderPath,
use: {
loader: 'error-loader',
options: {
reason: getFontLoaderImportError(),
},
},
}),
],
})
)
})

// CSS cannot be imported in _document. This comes before everything because
Expand Down
12 changes: 9 additions & 3 deletions packages/next/build/webpack/config/blocks/css/messages.ts
Expand Up @@ -33,7 +33,13 @@ export function getCustomDocumentError() {
}

export function getFontLoaderDocumentImportError() {
return `Font loaders ${chalk.bold('cannot')} be used within ${chalk.cyan(
'pages/_document.js'
)}.`
return `Font loader error:\nFont loaders ${chalk.bold(
'cannot'
)} be used within ${chalk.cyan('pages/_document.js')}.`
}

export function getFontLoaderImportError() {
return `Font loader error:\nFont loaders ${chalk.bold(
'cannot'
)} be used from within ${chalk.bold('node_modules')}.`
}
15 changes: 13 additions & 2 deletions packages/next/server/config-schema.ts
Expand Up @@ -406,8 +406,19 @@ const configSchema = {
type: 'boolean',
},
fontLoaders: {
type: 'object',
},
items: {
additionalProperties: false,
properties: {
loader: {
type: 'string',
},
options: {},
},
type: 'object',
required: ['loader'],
},
type: 'array',
} as any,
webVitalsAttribution: {
type: 'array',
items: {
Expand Down
2 changes: 1 addition & 1 deletion packages/next/server/config-shared.ts
Expand Up @@ -159,7 +159,7 @@ export interface ExperimentalConfig {
// A list of packages that should be treated as external in the RSC server build
serverComponentsExternalPackages?: string[]

fontLoaders?: { [fontLoader: string]: any }
fontLoaders?: [{ loader: string; options?: any }]

webVitalsAttribution?: Array<typeof WEB_VITALS[number]>
}
Expand Down
8 changes: 5 additions & 3 deletions test/e2e/app-dir/next-font/next.config.js
Expand Up @@ -3,8 +3,10 @@ module.exports = {
appDir: true,
legacyBrowsers: false,
browsersListForSwc: true,
fontLoaders: {
'@next/font/local': {},
},
fontLoaders: [
{
loader: '@next/font/local',
},
],
},
}
13 changes: 8 additions & 5 deletions test/e2e/next-font/app/next.config.js
@@ -1,10 +1,13 @@
module.exports = {
experimental: {
fontLoaders: {
'@next/font/google': {
subsets: ['latin'],
fontLoaders: [
{
loader: '@next/font/google',
options: { subsets: ['latin'] },
},
'@next/font/local': {},
},
{
loader: '@next/font/local',
},
],
},
}
9 changes: 5 additions & 4 deletions test/e2e/next-font/babel/next.config.js
@@ -1,9 +1,10 @@
module.exports = {
experimental: {
fontLoaders: {
'@next/font/google': {
subsets: ['latin'],
fontLoaders: [
{
loader: '@next/font/google',
options: { subsets: ['latin'] },
},
},
],
},
}
9 changes: 5 additions & 4 deletions test/e2e/next-font/basepath/next.config.js
@@ -1,10 +1,11 @@
module.exports = {
basePath: '/dashboard',
experimental: {
fontLoaders: {
'@next/font/google': {
subsets: ['latin'],
fontLoaders: [
{
loader: '@next/font/google',
options: { subsets: ['latin'] },
},
},
],
},
}
9 changes: 5 additions & 4 deletions test/e2e/next-font/font-loader-in-document/next.config.js
@@ -1,9 +1,10 @@
module.exports = {
experimental: {
fontLoaders: {
'@next/font/google': {
subsets: ['latin'],
fontLoaders: [
{
loader: '@next/font/google',
options: { subsets: ['latin'] },
},
},
],
},
}
13 changes: 8 additions & 5 deletions test/e2e/next-font/with-font-declarations-file/next.config.js
@@ -1,10 +1,13 @@
module.exports = {
experimental: {
fontLoaders: {
'@next/font/google': {
subsets: ['latin'],
fontLoaders: [
{
loader: '@next/font/google',
options: { subsets: ['latin'] },
},
'@next/font/local': {},
},
{
loader: '@next/font/local',
},
],
},
}
9 changes: 5 additions & 4 deletions test/e2e/next-font/without-preloaded-fonts/next.config.js
@@ -1,9 +1,10 @@
module.exports = {
experimental: {
fontLoaders: {
'@next/font/google': {
subsets: ['latin'],
fontLoaders: [
{
loader: '@next/font/google',
options: { subsets: ['latin'] },
},
},
],
},
}

0 comments on commit 766fd8e

Please sign in to comment.