Skip to content

Commit

Permalink
Turbopack: Fail when next/font is used in _document (#63788)
Browse files Browse the repository at this point in the history
  • Loading branch information
wbinnssmith authored Mar 28, 2024
1 parent d0ea289 commit e519634
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 11 deletions.
10 changes: 8 additions & 2 deletions packages/next-swc/crates/next-core/src/next_font/google/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ use self::{
use super::{
font_fallback::FontFallback,
util::{
get_request_hash, get_request_id, get_scoped_font_family, FontCssProperties, FontFamilyType,
can_use_next_font, get_request_hash, get_request_id, get_scoped_font_family,
FontCssProperties, FontFamilyType,
},
};
use crate::{
Expand Down Expand Up @@ -163,7 +164,12 @@ impl ImportMappingReplacement for NextFontGoogleReplacer {
return Ok(ImportMapResult::NoEntry.into());
};

Ok(self.import_map_result(query.await?.to_string()))
let this = &*self.await?;
if can_use_next_font(this.project_path, *query).await? {
Ok(self.import_map_result(query.await?.to_string()))
} else {
Ok(ImportMapResult::NoEntry.into())
}
}
}

Expand Down
12 changes: 10 additions & 2 deletions packages/next-swc/crates/next-core/src/next_font/local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ use self::{
stylesheet::build_stylesheet,
util::build_font_family_string,
};
use super::{font_fallback::FontFallbacks, util::FontCssProperties};
use super::{
font_fallback::FontFallbacks,
util::{can_use_next_font, FontCssProperties},
};
use crate::{
next_app::metadata::split_extension,
next_font::{
Expand Down Expand Up @@ -134,7 +137,12 @@ impl ImportMappingReplacement for NextFontLocalReplacer {
return Ok(ImportMapResult::NoEntry.into());
};

Ok(self.import_map_result(context, query_vc.await?.to_string()))
let this = &*self.await?;
if can_use_next_font(this.project_path, *query_vc).await? {
Ok(self.import_map_result(context, query_vc.await?.to_string()))
} else {
Ok(ImportMapResult::NoEntry.into())
}
}
}

Expand Down
53 changes: 51 additions & 2 deletions packages/next-swc/crates/next-core/src/next_font/util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use anyhow::Result;
use anyhow::{Context, Result};
use serde::Deserialize;
use turbo_tasks::Vc;
use turbopack_binding::turbo::tasks_hash::hash_xxh3_hash64;
use turbo_tasks_fs::{json::parse_json_with_source_context, FileSystemPath};
use turbopack_binding::{
turbo::tasks_hash::hash_xxh3_hash64,
turbopack::core::issue::{IssueExt, IssueSeverity, StyledString},
};

use super::issue::NextFontIssue;

/// CSS properties and values for a given font variation. These are rendered as
/// values in both the returned JavaScript object and in the referenced css
Expand Down Expand Up @@ -72,3 +79,45 @@ pub async fn get_request_id(font_family: Vc<String>, request_hash: u32) -> Resul
request_hash
)))
}

#[derive(Debug, Deserialize)]
struct HasPath {
path: String,
}

pub(crate) async fn can_use_next_font(
project_path: Vc<FileSystemPath>,
query: Vc<String>,
) -> Result<bool> {
let query_map = qstring::QString::from(&**query.await?);
let request: HasPath = parse_json_with_source_context(
query_map
.to_pairs()
.first()
.context("expected one entry")?
.0,
)?;

let document_re = lazy_regex::regex!("^(src/)?_document\\.[^/]+$");
let path = project_path.join(request.path.clone());
let can_use = !document_re.is_match(&request.path);
if !can_use {
NextFontIssue {
path,
title: StyledString::Line(vec![
StyledString::Code("next/font:".to_string()),
StyledString::Text(" error:".to_string()),
])
.cell(),
description: StyledString::Line(vec![
StyledString::Text("Cannot be used within ".to_string()),
StyledString::Code(request.path),
])
.cell(),
severity: IssueSeverity::Error.into(),
}
.cell()
.emit();
}
Ok(can_use)
}
19 changes: 14 additions & 5 deletions test/development/next-font/font-loader-in-document-error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,19 @@ describe('font-loader-in-document-error', () => {
test('next/font inside _document', async () => {
const browser = await webdriver(next.url, '/')
expect(await hasRedbox(browser)).toBeTrue()
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"pages/_document.js
\`next/font\` error:
Cannot be used within pages/_document.js."
`)
if (process.env.TURBOPACK) {
// TODO: Turbopack doesn't include pages/
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"./_document.js
next/font: error:
Cannot be used within _document.js"
`)
} else {
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"pages/_document.js
\`next/font\` error:
Cannot be used within pages/_document.js."
`)
}
})
})

0 comments on commit e519634

Please sign in to comment.