Skip to content

Commit

Permalink
Turbopack: don't generate CSS for Node.js (#75117)
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic authored Jan 22, 2025
1 parent ab87453 commit 73efa18
Show file tree
Hide file tree
Showing 16 changed files with 456 additions and 187 deletions.
286 changes: 185 additions & 101 deletions crates/next-api/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use next_core::{
get_client_runtime_entries, ClientContextType, RuntimeEntries,
},
next_client_reference::{
find_server_entries, ClientReferenceGraphResult, NextEcmascriptClientReferenceTransition,
ServerEntries,
find_server_entries, ClientReferenceGraphResult, NextCssClientReferenceTransition,
NextEcmascriptClientReferenceTransition, ServerEntries,
},
next_config::NextConfig,
next_dynamic::NextDynamicTransition,
Expand Down Expand Up @@ -64,6 +64,7 @@ use turbopack_core::{
module_graph::{ModuleGraph, SingleModuleGraph, VisitedModules},
output::{OutputAsset, OutputAssets},
raw_output::RawOutput,
reference_type::{CssReferenceSubType, ReferenceType},
resolve::{origin::PlainResolveOrigin, parse::Request, pattern::Pattern},
source::Source,
virtual_output::VirtualOutputAsset,
Expand Down Expand Up @@ -101,9 +102,25 @@ pub(crate) const ECMASCRIPT_CLIENT_TRANSITION_NAME: &str = "next-ecmascript-clie

fn styles_rule_condition() -> RuleCondition {
RuleCondition::any(vec![
RuleCondition::ResourcePathEndsWith(".css".into()),
RuleCondition::ResourcePathEndsWith(".scss".into()),
RuleCondition::ResourcePathEndsWith(".sass".into()),
RuleCondition::all(vec![
RuleCondition::ResourcePathEndsWith(".css".into()),
RuleCondition::not(RuleCondition::ResourcePathEndsWith(".module.css".into())),
]),
RuleCondition::all(vec![
RuleCondition::ResourcePathEndsWith(".scss".into()),
RuleCondition::not(RuleCondition::ResourcePathEndsWith(".module.scss".into())),
]),
RuleCondition::all(vec![
RuleCondition::ResourcePathEndsWith(".sass".into()),
RuleCondition::not(RuleCondition::ResourcePathEndsWith(".module.sass".into())),
]),
])
}
fn module_styles_rule_condition() -> RuleCondition {
RuleCondition::any(vec![
RuleCondition::ResourcePathEndsWith(".module.css".into()),
RuleCondition::ResourcePathEndsWith(".module.scss".into()),
RuleCondition::ResourcePathEndsWith(".module.sass".into()),
])
}

Expand Down Expand Up @@ -306,65 +323,104 @@ impl AppProject {
}

#[turbo_tasks::function]
pub fn client_reference_transition(self: Vc<Self>) -> Vc<Box<dyn Transition>> {
pub fn ecmascript_client_reference_transition(self: Vc<Self>) -> Vc<Box<dyn Transition>> {
Vc::upcast(NextEcmascriptClientReferenceTransition::new(
Vc::upcast(self.client_transition()),
self.ssr_transition(),
Vc::upcast(self.ssr_transition()),
))
}

#[turbo_tasks::function]
pub fn edge_client_reference_transition(self: Vc<Self>) -> Vc<Box<dyn Transition>> {
pub fn edge_ecmascript_client_reference_transition(self: Vc<Self>) -> Vc<Box<dyn Transition>> {
Vc::upcast(NextEcmascriptClientReferenceTransition::new(
Vc::upcast(self.client_transition()),
self.edge_ssr_transition(),
Vc::upcast(self.edge_ssr_transition()),
))
}

#[turbo_tasks::function]
async fn rsc_module_context(self: Vc<Self>) -> Result<Vc<ModuleAssetContext>> {
let transitions = [
(
ECMASCRIPT_CLIENT_TRANSITION_NAME.into(),
self.client_reference_transition().to_resolved().await?,
),
(
"next-dynamic".into(),
ResolvedVc::upcast(NextDynamicTransition::new_marker().to_resolved().await?),
),
(
"next-dynamic-client".into(),
ResolvedVc::upcast(
NextDynamicTransition::new_client(Vc::upcast(self.client_transition()))
.to_resolved()
.await?,
pub fn css_client_reference_transition(self: Vc<Self>) -> Vc<Box<dyn Transition>> {
Vc::upcast(NextCssClientReferenceTransition::new(Vc::upcast(
self.client_transition(),
)))
}

#[turbo_tasks::function]
async fn get_rsc_transitions(
self: Vc<Self>,
ecmascript_client_reference_transition: Vc<Box<dyn Transition>>,
ssr_transition: Vc<Box<dyn Transition>>,
shared_transition: Vc<Box<dyn Transition>>,
) -> Result<Vc<TransitionOptions>> {
Ok(TransitionOptions {
named_transitions: [
(
ECMASCRIPT_CLIENT_TRANSITION_NAME.into(),
ecmascript_client_reference_transition.to_resolved().await?,
),
),
(
"next-ssr".into(),
ResolvedVc::upcast(self.ssr_transition().to_resolved().await?),
),
(
"next-shared".into(),
ResolvedVc::upcast(self.shared_transition().to_resolved().await?),
),
(
"next-server-utility".into(),
ResolvedVc::upcast(NextServerUtilityTransition::new().to_resolved().await?),
),
]
.into_iter()
.collect();
Ok(ModuleAssetContext::new(
TransitionOptions {
named_transitions: transitions,
transition_rules: vec![TransitionRule::new(
styles_rule_condition(),
(
"next-dynamic".into(),
ResolvedVc::upcast(NextDynamicTransition::new_marker().to_resolved().await?),
),
(
"next-dynamic-client".into(),
ResolvedVc::upcast(
NextDynamicTransition::new_client(Vc::upcast(self.client_transition()))
.to_resolved()
.await?,
),
),
("next-ssr".into(), ssr_transition.to_resolved().await?),
("next-shared".into(), shared_transition.to_resolved().await?),
(
"next-server-utility".into(),
ResolvedVc::upcast(NextServerUtilityTransition::new().to_resolved().await?),
),
]
.into_iter()
.collect(),
transition_rules: vec![
// Mark as client reference (and exclude from RSC chunking) the edge from the
// CSS Module to the actual CSS
TransitionRule::new_internal(
RuleCondition::all(vec![
RuleCondition::ReferenceType(ReferenceType::Css(
CssReferenceSubType::Internal,
)),
module_styles_rule_condition(),
]),
ResolvedVc::upcast(self.css_client_reference_transition().to_resolved().await?),
),
// Don't wrap in marker module but change context, this is used to determine
// the list of CSS module classes.
TransitionRule::new(
RuleCondition::all(vec![
RuleCondition::ReferenceType(ReferenceType::Css(
CssReferenceSubType::Analyze,
)),
module_styles_rule_condition(),
]),
ResolvedVc::upcast(self.client_transition().to_resolved().await?),
)],
..Default::default()
}
.cell(),
),
// Mark as client reference all regular CSS imports
TransitionRule::new(
styles_rule_condition(),
ResolvedVc::upcast(self.css_client_reference_transition().to_resolved().await?),
),
],
..Default::default()
}
.cell())
}

#[turbo_tasks::function]
async fn rsc_module_context(self: Vc<Self>) -> Result<Vc<ModuleAssetContext>> {
Ok(ModuleAssetContext::new(
self.get_rsc_transitions(
self.ecmascript_client_reference_transition(),
Vc::upcast(self.ssr_transition()),
Vc::upcast(self.shared_transition()),
),
self.project().server_compile_time_info(),
self.rsc_module_options_context(),
self.rsc_resolve_options_context(),
Expand All @@ -374,50 +430,12 @@ impl AppProject {

#[turbo_tasks::function]
async fn edge_rsc_module_context(self: Vc<Self>) -> Result<Vc<ModuleAssetContext>> {
let transitions = [
(
ECMASCRIPT_CLIENT_TRANSITION_NAME.into(),
self.edge_client_reference_transition()
.to_resolved()
.await?,
),
(
"next-dynamic".into(),
ResolvedVc::upcast(NextDynamicTransition::new_marker().to_resolved().await?),
),
(
"next-dynamic-client".into(),
ResolvedVc::upcast(
NextDynamicTransition::new_client(Vc::upcast(self.client_transition()))
.to_resolved()
.await?,
),
),
(
"next-ssr".into(),
ResolvedVc::upcast(self.edge_ssr_transition().to_resolved().await?),
),
(
"next-shared".into(),
ResolvedVc::upcast(self.edge_shared_transition().to_resolved().await?),
),
(
"next-server-utility".into(),
ResolvedVc::upcast(NextServerUtilityTransition::new().to_resolved().await?),
),
]
.into_iter()
.collect();
Ok(ModuleAssetContext::new(
TransitionOptions {
named_transitions: transitions,
transition_rules: vec![TransitionRule::new(
styles_rule_condition(),
ResolvedVc::upcast(self.client_transition().to_resolved().await?),
)],
..Default::default()
}
.cell(),
self.get_rsc_transitions(
self.edge_ecmascript_client_reference_transition(),
Vc::upcast(self.edge_ssr_transition()),
Vc::upcast(self.edge_shared_transition()),
),
self.project().edge_compile_time_info(),
self.edge_rsc_module_options_context(),
self.edge_rsc_resolve_options_context(),
Expand All @@ -430,7 +448,9 @@ impl AppProject {
let transitions = [
(
ECMASCRIPT_CLIENT_TRANSITION_NAME.into(),
self.client_reference_transition().to_resolved().await?,
self.ecmascript_client_reference_transition()
.to_resolved()
.await?,
),
(
"next-dynamic".into(),
Expand Down Expand Up @@ -462,6 +482,7 @@ impl AppProject {

Ok(ModuleAssetContext::new(
TransitionOptions {
// TODO use get_rsc_transitions as well?
named_transitions: transitions,
..Default::default()
}
Expand All @@ -478,7 +499,7 @@ impl AppProject {
let transitions = [
(
ECMASCRIPT_CLIENT_TRANSITION_NAME.into(),
self.edge_client_reference_transition()
self.edge_ecmascript_client_reference_transition()
.to_resolved()
.await?,
),
Expand Down Expand Up @@ -511,6 +532,7 @@ impl AppProject {
.collect();
Ok(ModuleAssetContext::new(
TransitionOptions {
// TODO use get_rsc_transitions as well?
named_transitions: transitions,
..Default::default()
}
Expand Down Expand Up @@ -598,13 +620,44 @@ impl AppProject {
}

#[turbo_tasks::function]
fn ssr_transition(self: Vc<Self>) -> Vc<ContextTransition> {
ContextTransition::new(
async fn ssr_module_context(self: Vc<Self>) -> Result<Vc<ModuleAssetContext>> {
let transitions = [
(
"next-dynamic".into(),
ResolvedVc::upcast(NextDynamicTransition::new_marker().to_resolved().await?),
),
(
"next-dynamic-client".into(),
ResolvedVc::upcast(
NextDynamicTransition::new_client(Vc::upcast(self.client_transition()))
.to_resolved()
.await?,
),
),
(
"next-shared".into(),
ResolvedVc::upcast(self.shared_transition().to_resolved().await?),
),
]
.into_iter()
.collect();
Ok(ModuleAssetContext::new(
TransitionOptions {
named_transitions: transitions,
..Default::default()
}
.cell(),
self.project().server_compile_time_info(),
self.ssr_module_options_context(),
self.ssr_resolve_options_context(),
Vc::cell("app-ssr".into()),
)
))
}

#[turbo_tasks::function]
fn ssr_transition(self: Vc<Self>) -> Vc<FullContextTransition> {
let module_context = self.ssr_module_context();
FullContextTransition::new(module_context)
}

#[turbo_tasks::function]
Expand All @@ -618,13 +671,44 @@ impl AppProject {
}

#[turbo_tasks::function]
fn edge_ssr_transition(self: Vc<Self>) -> Vc<ContextTransition> {
ContextTransition::new(
async fn edge_ssr_module_context(self: Vc<Self>) -> Result<Vc<ModuleAssetContext>> {
let transitions = [
(
"next-dynamic".into(),
ResolvedVc::upcast(NextDynamicTransition::new_marker().to_resolved().await?),
),
(
"next-dynamic-client".into(),
ResolvedVc::upcast(
NextDynamicTransition::new_client(Vc::upcast(self.client_transition()))
.to_resolved()
.await?,
),
),
(
"next-shared".into(),
ResolvedVc::upcast(self.edge_shared_transition().to_resolved().await?),
),
]
.into_iter()
.collect();
Ok(ModuleAssetContext::new(
TransitionOptions {
named_transitions: transitions,
..Default::default()
}
.cell(),
self.project().edge_compile_time_info(),
self.edge_ssr_module_options_context(),
self.edge_ssr_resolve_options_context(),
Vc::cell("app-edge-ssr".into()),
)
))
}

#[turbo_tasks::function]
fn edge_ssr_transition(self: Vc<Self>) -> Vc<FullContextTransition> {
let module_context = self.edge_ssr_module_context();
FullContextTransition::new(module_context)
}

#[turbo_tasks::function]
Expand Down
Loading

0 comments on commit 73efa18

Please sign in to comment.