Skip to content

Commit 87860f0

Browse files
committed
Turbopack: Remove undocumented legacy syntax for built-in conditions (e.g. foreign, browser)
1 parent 6c887b2 commit 87860f0

File tree

5 files changed

+78
-155
lines changed

5 files changed

+78
-155
lines changed

crates/next-core/src/next_config.rs

Lines changed: 43 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{collections::BTreeSet, str::FromStr, sync::LazyLock};
1+
use std::sync::LazyLock;
22

33
use anyhow::{Context, Result, bail};
44
use rustc_hash::FxHashSet;
@@ -670,7 +670,7 @@ impl TryFrom<ConfigConditionItem> for ConditionItem {
670670
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, NonLocalValue, OperationValue,
671671
)]
672672
#[serde(rename_all = "camelCase")]
673-
pub struct RuleConfigItemOptions {
673+
pub struct RuleConfigItem {
674674
pub loaders: Vec<LoaderItem>,
675675
#[serde(default, alias = "as")]
676676
pub rename_as: Option<RcStr>,
@@ -687,16 +687,6 @@ pub enum RuleConfigItemOrShortcut {
687687
Advanced(RuleConfigItem),
688688
}
689689

690-
#[derive(
691-
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, NonLocalValue, OperationValue,
692-
)]
693-
#[serde(rename_all = "camelCase", untagged)]
694-
pub enum RuleConfigItem {
695-
Options(RuleConfigItemOptions),
696-
LegacyConditional(FxIndexMap<RcStr, RuleConfigItem>),
697-
LegacyBoolean(bool),
698-
}
699-
700690
#[derive(
701691
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, NonLocalValue, OperationValue,
702692
)]
@@ -1378,7 +1368,6 @@ impl NextConfig {
13781368
#[turbo_tasks::function]
13791369
pub async fn webpack_rules(
13801370
&self,
1381-
active_conditions: BTreeSet<WebpackLoaderBuiltinCondition>,
13821371
project_path: FileSystemPath,
13831372
) -> Result<Vc<OptionWebpackRules>> {
13841373
let Some(turbo_rules) = self.turbopack.as_ref().and_then(|t| t.rules.as_ref()) else {
@@ -1403,43 +1392,6 @@ impl NextConfig {
14031392
.collect(),
14041393
)
14051394
}
1406-
enum FindRuleResult<'a> {
1407-
Found(&'a RuleConfigItemOptions),
1408-
NotFound,
1409-
Break,
1410-
}
1411-
// This logic is needed for the `LegacyConditional`/`LegacyBoolean` configuration
1412-
// syntax. This is technically public syntax, but was never documented and it is
1413-
// unlikely that anyone is depending on it (outside of some Next.js internals).
1414-
fn find_rule<'a>(
1415-
rule: &'a RuleConfigItem,
1416-
active_conditions: &BTreeSet<WebpackLoaderBuiltinCondition>,
1417-
) -> FindRuleResult<'a> {
1418-
match rule {
1419-
RuleConfigItem::Options(rule) => FindRuleResult::Found(rule),
1420-
RuleConfigItem::LegacyConditional(map) => {
1421-
for (condition, rule) in map.iter() {
1422-
let condition = WebpackLoaderBuiltinCondition::from_str(condition);
1423-
if let Ok(condition) = condition
1424-
&& (condition == WebpackLoaderBuiltinCondition::Default
1425-
|| active_conditions.contains(&condition))
1426-
{
1427-
match find_rule(rule, active_conditions) {
1428-
FindRuleResult::Found(rule) => {
1429-
return FindRuleResult::Found(rule);
1430-
}
1431-
FindRuleResult::Break => {
1432-
return FindRuleResult::Break;
1433-
}
1434-
FindRuleResult::NotFound => {}
1435-
}
1436-
}
1437-
}
1438-
FindRuleResult::NotFound
1439-
}
1440-
RuleConfigItem::LegacyBoolean(_) => FindRuleResult::Break,
1441-
}
1442-
}
14431395
let config_file_path = || project_path.join(&self.config_file_name);
14441396
match rule {
14451397
RuleConfigItemOrShortcut::Loaders(loaders) => {
@@ -1452,55 +1404,52 @@ impl NextConfig {
14521404
},
14531405
);
14541406
}
1455-
RuleConfigItemOrShortcut::Advanced(rule) => {
1456-
if let FindRuleResult::Found(RuleConfigItemOptions {
1457-
loaders,
1458-
rename_as,
1459-
condition,
1460-
}) = find_rule(rule, &active_conditions)
1407+
RuleConfigItemOrShortcut::Advanced(RuleConfigItem {
1408+
loaders,
1409+
rename_as,
1410+
condition,
1411+
}) => {
1412+
// If the extension contains a wildcard, and the rename_as does not,
1413+
// emit an issue to prevent users from encountering duplicate module names.
1414+
if glob.contains("*")
1415+
&& let Some(rename_as) = rename_as.as_ref()
1416+
&& !rename_as.contains("*")
14611417
{
1462-
// If the extension contains a wildcard, and the rename_as does not,
1463-
// emit an issue to prevent users from encountering duplicate module names.
1464-
if glob.contains("*")
1465-
&& let Some(rename_as) = rename_as.as_ref()
1466-
&& !rename_as.contains("*")
1467-
{
1468-
InvalidLoaderRuleRenameAsIssue {
1469-
glob: glob.clone(),
1418+
InvalidLoaderRuleRenameAsIssue {
1419+
glob: glob.clone(),
1420+
config_file_path: config_file_path()?,
1421+
rename_as: rename_as.clone(),
1422+
}
1423+
.resolved_cell()
1424+
.emit();
1425+
}
1426+
1427+
// convert from Next.js-specific condition type to internal Turbopack
1428+
// condition type
1429+
let condition = if let Some(condition) = condition {
1430+
if let Ok(cond) = ConditionItem::try_from(condition.clone()) {
1431+
Some(cond)
1432+
} else {
1433+
InvalidLoaderRuleConditionIssue {
1434+
condition: condition.clone(),
14701435
config_file_path: config_file_path()?,
1471-
rename_as: rename_as.clone(),
14721436
}
14731437
.resolved_cell()
14741438
.emit();
1439+
None
14751440
}
1441+
} else {
1442+
None
1443+
};
14761444

1477-
// convert from Next.js-specific condition type to internal Turbopack
1478-
// condition type
1479-
let condition = if let Some(condition) = condition {
1480-
if let Ok(cond) = ConditionItem::try_from(condition.clone()) {
1481-
Some(cond)
1482-
} else {
1483-
InvalidLoaderRuleConditionIssue {
1484-
condition: condition.clone(),
1485-
config_file_path: config_file_path()?,
1486-
}
1487-
.resolved_cell()
1488-
.emit();
1489-
None
1490-
}
1491-
} else {
1492-
None
1493-
};
1494-
1495-
rules.insert(
1496-
glob.clone(),
1497-
LoaderRuleItem {
1498-
loaders: transform_loaders(loaders),
1499-
rename_as: rename_as.clone(),
1500-
condition,
1501-
},
1502-
);
1503-
}
1445+
rules.insert(
1446+
glob.clone(),
1447+
LoaderRuleItem {
1448+
loaders: transform_loaders(loaders),
1449+
rename_as: rename_as.clone(),
1450+
condition,
1451+
},
1452+
);
15041453
}
15051454
}
15061455
}
@@ -1963,11 +1912,11 @@ mod tests {
19631912
}
19641913
});
19651914

1966-
let rule_config: RuleConfigItemOptions = serde_json::from_value(json_value).unwrap();
1915+
let rule_config: RuleConfigItem = serde_json::from_value(json_value).unwrap();
19671916

19681917
assert_eq!(
19691918
rule_config,
1970-
RuleConfigItemOptions {
1919+
RuleConfigItem {
19711920
loaders: vec![],
19721921
rename_as: Some(rcstr!("*.js")),
19731922
condition: Some(ConfigConditionItem::All(

crates/next-core/src/next_shared/webpack_rules/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,7 @@ pub async fn webpack_loader_options(
196196
next_config: Vc<NextConfig>,
197197
builtin_conditions: BTreeSet<WebpackLoaderBuiltinCondition>,
198198
) -> Result<Option<ResolvedVc<WebpackLoadersOptions>>> {
199-
let mut rules = *next_config
200-
.webpack_rules(builtin_conditions.clone(), project_path.clone())
201-
.await?;
199+
let mut rules = *next_config.webpack_rules(project_path.clone()).await?;
202200
rules = *maybe_add_sass_loader(next_config.sass_config(), rules.map(|v| *v)).await?;
203201
if !builtin_conditions.contains(&WebpackLoaderBuiltinCondition::Foreign) {
204202
rules = *maybe_add_babel_loader(project_path.clone(), rules.map(|v| *v)).await?;

packages/next/src/build/swc/index.ts

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import type {
1515
TurbopackLoaderItem,
1616
TurbopackRuleCondition,
1717
TurbopackRuleConfigItem,
18-
TurbopackRuleConfigItemOptions,
1918
TurbopackRuleConfigItemOrShortcut,
2019
} from '../../server/config-shared'
2120
import { isDeepStrictEqual } from 'util'
@@ -836,29 +835,32 @@ function bindingToApi(
836835

837836
for (const key of ruleKeys) {
838837
nextConfig.turbopack.conditions[`#reactCompiler/${key}`] = {
839-
path: key,
840-
content:
841-
options.compilationMode === 'annotation'
842-
? /['"]use memo['"]/
843-
: !options.compilationMode ||
844-
options.compilationMode === 'infer'
845-
? // Matches declaration or useXXX or </ (closing jsx) or /> (self closing jsx)
846-
/['"]use memo['"]|\Wuse[A-Z]|<\/|\/>/
847-
: undefined,
838+
all: [
839+
'browser',
840+
{ not: 'foreign' },
841+
{
842+
path: key,
843+
content:
844+
options.compilationMode === 'annotation'
845+
? /['"]use memo['"]/
846+
: !options.compilationMode ||
847+
options.compilationMode === 'infer'
848+
? // Matches declaration or useXXX or </ (closing jsx) or /> (self closing jsx)
849+
/['"]use memo['"]|\Wuse[A-Z]|<\/|\/>/
850+
: undefined,
851+
},
852+
],
848853
}
849854
nextConfig.turbopack.rules[`#reactCompiler/${key}`] = {
850-
browser: {
851-
foreign: false,
852-
loaders: [
853-
getReactCompilerLoader(
854-
reactCompilerOptions,
855-
projectPath,
856-
nextConfig.dev,
857-
/* isServer */ false,
858-
/* reactCompilerExclude */ undefined
859-
),
860-
],
861-
},
855+
loaders: [
856+
getReactCompilerLoader(
857+
reactCompilerOptions,
858+
projectPath,
859+
nextConfig.dev,
860+
/* isServer */ false,
861+
/* reactCompilerExclude */ undefined
862+
),
863+
],
862864
}
863865
}
864866
}
@@ -1034,23 +1036,11 @@ function bindingToApi(
10341036
): any {
10351037
if (!rule) return rule
10361038
let serializedRule: any = rule
1037-
if ('loaders' in rule) {
1038-
const narrowedRule = rule as TurbopackRuleConfigItemOptions
1039-
checkLoaderItems(narrowedRule.loaders, glob)
1040-
if (narrowedRule.condition != null) {
1041-
serializedRule = {
1042-
...rule,
1043-
condition: serializeRuleCondition(narrowedRule.condition),
1044-
}
1045-
}
1046-
} else {
1047-
serializedRule = {}
1048-
for (const [key, value] of Object.entries(rule)) {
1049-
if (typeof value === 'object' && value) {
1050-
serializedRule[key] = serializeConfigItem(value, glob)
1051-
} else {
1052-
serializedRule[key] = value
1053-
}
1039+
checkLoaderItems(rule.loaders, glob)
1040+
if (rule.condition != null) {
1041+
serializedRule = {
1042+
...rule,
1043+
condition: serializeRuleCondition(rule.condition),
10541044
}
10551045
}
10561046
return serializedRule

packages/next/src/server/config-schema.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import type {
1111
DeprecatedExperimentalTurboOptions,
1212
TurbopackOptions,
1313
TurbopackRuleConfigItem,
14-
TurbopackRuleConfigItemOptions,
1514
TurbopackRuleConfigItemOrShortcut,
1615
TurbopackRuleCondition,
1716
TurbopackLoaderBuiltinCondition,
@@ -135,21 +134,13 @@ const zTurbopackCondition: zod.ZodType<TurbopackRuleCondition> = z.union([
135134
}),
136135
])
137136

138-
const zTurbopackRuleConfigItemOptions: zod.ZodType<TurbopackRuleConfigItemOptions> =
139-
z.object({
137+
const zTurbopackRuleConfigItem: zod.ZodType<TurbopackRuleConfigItem> = z.object(
138+
{
140139
loaders: z.array(zTurbopackLoaderItem),
141140
as: z.string().optional(),
142141
condition: zTurbopackCondition.optional(),
143-
})
144-
145-
const zTurbopackRuleConfigItem: zod.ZodType<TurbopackRuleConfigItem> = z.union([
146-
z.literal(false),
147-
z.record(
148-
zTurbopackLoaderBuiltinCondition,
149-
z.lazy(() => zTurbopackRuleConfigItem)
150-
),
151-
zTurbopackRuleConfigItemOptions,
152-
])
142+
}
143+
)
153144

154145
const zTurbopackRuleConfigItemOrShortcut: zod.ZodType<TurbopackRuleConfigItemOrShortcut> =
155146
z.union([z.array(zTurbopackLoaderItem), zTurbopackRuleConfigItem])

packages/next/src/server/config-shared.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -281,17 +281,12 @@ export type TurbopackRuleCondition =
281281
content?: RegExp
282282
}
283283

284-
export type TurbopackRuleConfigItemOptions = {
284+
export type TurbopackRuleConfigItem = {
285285
loaders: TurbopackLoaderItem[]
286286
as?: string
287287
condition?: TurbopackRuleCondition
288288
}
289289

290-
export type TurbopackRuleConfigItem =
291-
| TurbopackRuleConfigItemOptions
292-
| { [condition in TurbopackLoaderBuiltinCondition]?: TurbopackRuleConfigItem }
293-
| false
294-
295290
export type TurbopackRuleConfigItemOrShortcut =
296291
| TurbopackLoaderItem[]
297292
| TurbopackRuleConfigItem

0 commit comments

Comments
 (0)