Skip to content

Commit

Permalink
Local font family name (#42286)
Browse files Browse the repository at this point in the history
Use the name of the assigned const as the family name instead of trying
to get it from the font file. That way we know we won't get any invalid
characters in the font-family name.

fixes #42264

## 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 build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)

Co-authored-by: JJ Kasper <jj@jjsweb.site>
  • Loading branch information
Hannes Bornö and ijjk committed Nov 2, 2022
1 parent 6d7c4c7 commit f0e768e
Show file tree
Hide file tree
Showing 23 changed files with 103 additions and 69 deletions.
4 changes: 2 additions & 2 deletions packages/font/src/local/loader.ts
Expand Up @@ -53,13 +53,13 @@ function getDistanceFromNormalWeight(weight?: string) {

const fetchFonts: FontLoader = async ({
functionName,
variableName,
data,
emitFontFile,
resolve,
fs,
}) => {
const {
family,
src,
display,
fallback,
Expand Down Expand Up @@ -88,7 +88,7 @@ const fetchFonts: FontLoader = async ({
...(declarations
? declarations.map(({ prop, value }) => [prop, value])
: []),
['font-family', `'${fontMetadata?.familyName ?? family}'`],
['font-family', variableName],
['src', `url(${fontUrl}) format('${format}')`],
['font-display', display],
...(weight ?? defaultWeight
Expand Down
6 changes: 0 additions & 6 deletions packages/font/src/local/utils.ts
Expand Up @@ -12,7 +12,6 @@ const extToFormat = {
}

type FontOptions = {
family: string
src: Array<{
path: string
weight?: string
Expand Down Expand Up @@ -65,15 +64,11 @@ export function validateData(functionName: string, fontData: any): FontOptions {
}
}

let family: string | undefined
src = src.map((fontFile: any) => {
const ext = /\.(woff|woff2|eot|ttf|otf)$/.exec(fontFile.path)?.[1]
if (!ext) {
throw new Error(`Unexpected file \`${fontFile.path}\``)
}
if (!family) {
family = /(.*\/)?(.+?)\.(woff|woff2|eot|ttf|otf)$/.exec(fontFile.path)![2]
}

return {
...fontFile,
Expand All @@ -99,7 +94,6 @@ export function validateData(functionName: string, fontData: any): FontOptions {
}

return {
family: family!,
src,
display,
weight,
Expand Down
Expand Up @@ -11,7 +11,11 @@ pub struct FontImportsGenerator<'a> {
}

impl<'a> FontImportsGenerator<'a> {
fn check_call_expr(&mut self, call_expr: &CallExpr) -> Option<ImportDecl> {
fn check_call_expr(
&mut self,
call_expr: &CallExpr,
variable_name: &Result<Ident, &Pat>,
) -> Option<ImportDecl> {
if let Callee::Expr(callee_expr) = &call_expr.callee {
if let Expr::Ident(ident) = &**callee_expr {
if let Some(font_function) = self.state.font_functions.get(&ident.to_id()) {
Expand Down Expand Up @@ -48,6 +52,12 @@ impl<'a> FontImportsGenerator<'a> {
query_json_values
.insert(String::from("import"), Value::String(function_name));
query_json_values.insert(String::from("arguments"), Value::Array(json));
if let Ok(ident) = variable_name {
query_json_values.insert(
String::from("variableName"),
Value::String(ident.sym.to_string()),
);
}

let query_json = Value::Object(query_json_values);

Expand Down Expand Up @@ -81,7 +91,7 @@ impl<'a> FontImportsGenerator<'a> {
};
if let Some(expr) = &decl.init {
if let Expr::Call(call_expr) = &**expr {
let import_decl = self.check_call_expr(call_expr);
let import_decl = self.check_call_expr(call_expr, &ident);

if let Some(mut import_decl) = import_decl {
match var_decl.kind {
Expand Down
@@ -1,5 +1,5 @@
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Abel","arguments":[]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[]}';
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Abel","arguments":[],"variableName":"firaCode"}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[],"variableName":"inter"}';
import React from 'react';
export { firaCode };
export { inter };
@@ -1,4 +1,4 @@
import inter1 from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"400"}]}';
import inter2 from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"400"}]}';
import inter1 from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"400"}],"variableName":"inter1"}';
import inter2 from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"400"}],"variableName":"inter2"}';
var i = 10;
var i2 = 20;
@@ -1,7 +1,7 @@
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}]}';
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}]}';
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}]}';
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}]}';
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}],"variableName":"a"}';
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}],"variableName":"a"}';
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}],"variableName":"a"}';
import a from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"ABeeZee","arguments":[{}],"variableName":"a"}';
const a = fn({
10: 'hello'
});
Expand Down
@@ -1,2 +1,2 @@
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{},[]]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{},[]],"variableName":"inter"}';
const a = fn(...{}, ...[]);
@@ -1 +1 @@
import font from 'cool-fonts/target.css?{"path":"pages/test.tsx","import":"","arguments":[{"prop":true}]}';
import font from 'cool-fonts/target.css?{"path":"pages/test.tsx","import":"","arguments":[{"prop":true}],"variableName":"font"}';
@@ -1,5 +1,5 @@
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Abel","arguments":[]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[]}';
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Abel","arguments":[],"variableName":"firaCode"}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[],"variableName":"inter"}';
import React from 'react';
export { firaCode };
export { inter };
@@ -1,5 +1,5 @@
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Abel","arguments":[]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[]}';
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Abel","arguments":[],"variableName":"firaCode"}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[],"variableName":"inter"}';
import React from 'react';
export { firaCode };
export default inter;
@@ -1,3 +1,3 @@
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","fallback":["system-ui",{"key":false},[]],"preload":true,"key":{"key2":{}}}]}';
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","fallback":["system-ui",{"key":false},[]],"preload":true,"key":{"key2":{}}}],"variableName":"firaCode"}';
import React from 'react';
console.log(firaCode);
@@ -1,2 +1,2 @@
import acme1 from 'cool-fonts/target.css?{"path":"pages/test.tsx","import":"Acme","arguments":[{"variant":"400"}]}';
import acme1 from 'cool-fonts/target.css?{"path":"pages/test.tsx","import":"Acme","arguments":[{"variant":"400"}],"variableName":"acme1"}';
import React from 'react';
@@ -1 +1 @@
import geo from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Geo","arguments":["test",[1.0],{"a":2.0},3.0]}';
import geo from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Geo","arguments":["test",[1.0],{"a":2.0},3.0],"variableName":"geo"}';
@@ -1,3 +1,3 @@
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900","display":"swap"}]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900","display":"swap"}]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900","display":"swap"}],"variableName":"inter"}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900","display":"swap"}],"variableName":"inter"}';
import React from 'react';
@@ -1,3 +1,3 @@
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900"}]}';
import fira from 'cool-fonts/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","display":"swap"}]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900"}],"variableName":"inter"}';
import fira from 'cool-fonts/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","display":"swap"}],"variableName":"fira"}';
import React from 'react';
@@ -1,3 +1,3 @@
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","fallback":["system-ui"]}]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900","display":"swap"}]}';
import firaCode from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","fallback":["system-ui"]}],"variableName":"firaCode"}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900","display":"swap"}],"variableName":"inter"}';
import React from 'react';
@@ -1,3 +1,3 @@
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900"}]}';
import fira from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","display":"swap"}]}';
import inter from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Inter","arguments":[{"variant":"900"}],"variableName":"inter"}';
import fira from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[{"variant":"400","display":"swap"}],"variableName":"fira"}';
import React from 'react';
@@ -1 +1 @@
import fira from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[]}';
import fira from '@next/font/google/target.css?{"path":"pages/test.tsx","import":"Fira_Code","arguments":[],"variableName":"fira"}';
2 changes: 2 additions & 0 deletions packages/next/build/webpack/loaders/next-font-loader/index.ts
Expand Up @@ -57,6 +57,7 @@ export default async function nextFontLoader(this: any) {
path: relativeFilePathFromRoot,
import: functionName,
arguments: data,
variableName,
} = JSON.parse(this.resourceQuery.slice(1))

try {
Expand All @@ -67,6 +68,7 @@ export default async function nextFontLoader(this: any) {
let { css, fallbackFonts, adjustFontFallback, weight, style, variable } =
await fontLoader({
functionName,
variableName,
data,
config: fontLoaderOptions,
emitFontFile,
Expand Down
1 change: 1 addition & 0 deletions packages/next/font/index.d.ts
Expand Up @@ -14,6 +14,7 @@ export type AdjustFontFallback = {

export type FontLoader = (options: {
functionName: string
variableName: string
data: any[]
config: any
emitFontFile: (content: Buffer, ext: string, preload: boolean) => string
Expand Down

0 comments on commit f0e768e

Please sign in to comment.