Skip to content

Commit 0e7e166

Browse files
committed
Turbopack: Remove undocumented turbopack.conditions configuration
1 parent 15a0567 commit 0e7e166

File tree

8 files changed

+70
-146
lines changed

8 files changed

+70
-146
lines changed

crates/next-core/src/next_config.rs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use turbo_tasks_fetch::FetchClient;
1414
use turbo_tasks_fs::FileSystemPath;
1515
use turbopack::module_options::{
1616
ConditionItem, ConditionPath, LoaderRuleItem, WebpackRules,
17-
module_options_context::{MdxTransformOptions, OptionWebpackConditions},
17+
module_options_context::MdxTransformOptions,
1818
};
1919
use turbopack_core::{
2020
issue::{Issue, IssueExt, IssueStage, OptionStyledString, StyledString},
@@ -558,8 +558,6 @@ pub struct TurbopackConfig {
558558
/// This option has been replaced by `rules`.
559559
pub loaders: Option<JsonValue>,
560560
pub rules: Option<FxIndexMap<RcStr, RuleConfigCollection>>,
561-
#[turbo_tasks(trace_ignore)]
562-
pub conditions: Option<FxIndexMap<RcStr, ConfigConditionItem>>,
563561
pub resolve_alias: Option<FxIndexMap<RcStr, JsonValue>>,
564562
pub resolve_extensions: Option<Vec<RcStr>>,
565563
pub module_ids: Option<ModuleIds>,
@@ -1479,24 +1477,6 @@ impl NextConfig {
14791477
Ok(Vc::cell(rules))
14801478
}
14811479

1482-
#[turbo_tasks::function]
1483-
pub fn webpack_conditions(&self) -> Result<Vc<OptionWebpackConditions>> {
1484-
let Some(config_conditions) = self.turbopack.as_ref().and_then(|t| t.conditions.as_ref())
1485-
else {
1486-
return Ok(Vc::cell(None));
1487-
};
1488-
1489-
let conditions = config_conditions
1490-
.iter()
1491-
.map(|(k, v)| {
1492-
let item: Result<ConditionItem> = TryInto::<ConditionItem>::try_into((*v).clone());
1493-
item.map(|item| (k.clone(), item))
1494-
})
1495-
.collect::<Result<FxIndexMap<RcStr, ConditionItem>>>()?;
1496-
1497-
Ok(Vc::cell(Some(ResolvedVc::cell(conditions))))
1498-
}
1499-
15001480
#[turbo_tasks::function]
15011481
pub fn persistent_caching_enabled(&self) -> Result<Vc<bool>> {
15021482
Ok(Vc::cell(

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ pub(crate) mod sass;
2626

2727
/// Built-in conditions provided by the Next.js Turbopack integration for configuring webpack
2828
/// loaders. These can be used in the `next.config.js` `turbopack.rules` section.
29-
///
30-
/// These are different from than the user-configurable "conditions" field.
3129
//
3230
// Note: If you add a field here, make sure to also add it in:
3331
// - The typescript definition in `packages/next/src/server/config-shared.ts`
@@ -210,11 +208,9 @@ pub async fn webpack_loader_options(
210208
return Ok(Vc::cell(None));
211209
}
212210

213-
let conditions = next_config.webpack_conditions().to_resolved().await?;
214211
Ok(Vc::cell(Some(
215212
WebpackLoadersOptions {
216213
rules: ResolvedVc::cell(rules),
217-
conditions,
218214
loader_runner_package: Some(loader_runner_package_mapping().to_resolved().await?),
219215
builtin_conditions: NextWebpackLoaderBuiltinConditionSet::new(builtin_conditions)
220216
.to_resolved()

packages/next-mdx/index.js

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ module.exports =
2626
/**
2727
* @type {import('next').NextConfig}
2828
*/
29-
let nextConfig = Object.assign({}, inputConfig, {
29+
const nextConfig = {
30+
...inputConfig,
3031
webpack(config, options) {
3132
config.resolve.alias['next-mdx-import-source-file'] = [
3233
'private-next-root-dir/src/mdx-components',
@@ -45,26 +46,41 @@ module.exports =
4546

4647
return config
4748
},
48-
})
49+
}
4950

5051
if (process.env.TURBOPACK) {
51-
nextConfig.turbopack = Object.assign({}, nextConfig?.turbopack, {
52-
rules: Object.assign({}, nextConfig?.turbopack?.rules, {
53-
'#next-mdx': {
54-
loaders: [loader],
55-
as: '*.tsx',
56-
},
57-
}),
58-
conditions: {
59-
'#next-mdx': {
60-
path: extension,
61-
},
52+
const mdxRule = {
53+
loaders: [loader],
54+
as: '*.tsx',
55+
condition: {
56+
path: extension,
6257
},
63-
resolveAlias: Object.assign({}, nextConfig?.turbopack?.resolveAlias, {
58+
}
59+
60+
// Use a unique glob string for two reasons:
61+
// - This makes it clear where the rule was defined if someone needs to debug.
62+
// - Reduces the chance of a collision (can still happen if `next-mdx` is applied twice with
63+
// different options). Rule evaluation is ordering-sensitive, and a unique glob means we're
64+
// less likely to break the ordering of existing rules.
65+
let wildcardGlob = '{*,next-mdx-rule}'
66+
let wildcardRule = inputConfig.turbopack?.rules?.[wildcardGlob] ?? []
67+
wildcardRule = [
68+
...(Array.isArray(wildcardRule) ? wildcardRule : [wildcardRule]),
69+
mdxRule,
70+
]
71+
72+
nextConfig.turbopack = {
73+
...inputConfig?.turbopack,
74+
rules: {
75+
...inputConfig?.turbopack?.rules,
76+
[wildcardGlob]: wildcardRule,
77+
},
78+
resolveAlias: {
79+
...inputConfig?.turbopack?.resolveAlias,
6480
'next-mdx-import-source-file':
6581
'@vercel/turbopack-next/mdx-import-source',
66-
}),
67-
})
82+
},
83+
}
6884
}
6985

7086
return nextConfig

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

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -807,51 +807,21 @@ function bindingToApi(
807807
originalNextConfig: NextConfigComplete,
808808
projectPath: string
809809
): Record<string, any> {
810-
let nextConfig = { ...(originalNextConfig as NextConfigComplete) }
810+
let nextConfig = { ...originalNextConfig }
811811

812812
const reactCompilerOptions = nextConfig.experimental?.reactCompiler
813813

814-
// It is not easy to set the rules inside of rust as resolving, and passing the context identical to the webpack
815-
// config is bit hard, also we can reuse same codes between webpack config in here.
814+
// TODO: Merge this with `crates/next-core/src/next_shared/webpack_rules/babel.rs` so that we're
815+
// not configuring babel in two different places (potentially causing it to run twice)
816816
if (reactCompilerOptions) {
817817
const options: ReactCompilerOptions =
818818
typeof reactCompilerOptions === 'object' ? reactCompilerOptions : {}
819-
const ruleKeys = ['*.ts', '*.js', '*.jsx', '*.tsx']
820-
if (
821-
Object.keys(nextConfig?.turbopack?.rules ?? {}).some((key) =>
822-
ruleKeys.includes(key)
823-
)
824-
) {
825-
Log.warn(
826-
"The React Compiler cannot be enabled automatically because 'turbopack.rules' contains " +
827-
"a rule for '*.ts', '*.js', '*.jsx', and '*.tsx'. Remove this rule, or add " +
828-
"'babel-loader' and 'babel-plugin-react-compiler' to the Turbopack configuration " +
829-
'manually.'
830-
)
831-
} else {
832-
nextConfig.turbopack ??= {}
833-
nextConfig.turbopack.conditions ??= {}
834-
nextConfig.turbopack.rules ??= {}
835-
836-
for (const key of ruleKeys) {
837-
nextConfig.turbopack.conditions[`#reactCompiler/${key}`] = {
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-
],
853-
}
854-
nextConfig.turbopack.rules[`#reactCompiler/${key}`] = {
819+
nextConfig.turbopack = {
820+
...originalNextConfig.turbopack,
821+
rules: {
822+
...originalNextConfig.turbopack.rules,
823+
// assumption: there is no collision with this glob key
824+
'{*.{js,jsx,ts,tsx,cjs,mjs,mts,cts},react-compiler-builtin-rule}': {
855825
loaders: [
856826
getReactCompilerLoader(
857827
reactCompilerOptions,
@@ -861,8 +831,24 @@ function bindingToApi(
861831
/* reactCompilerExclude */ undefined
862832
),
863833
],
864-
}
865-
}
834+
condition: {
835+
all: [
836+
'browser',
837+
{ not: 'foreign' },
838+
{
839+
content:
840+
options.compilationMode === 'annotation'
841+
? /['"]use memo['"]/
842+
: !options.compilationMode ||
843+
options.compilationMode === 'infer'
844+
? // Matches declaration or useXXX or </ (closing jsx) or /> (self closing jsx)
845+
/['"]use memo['"]|\Wuse[A-Z]|<\/|\/>/
846+
: undefined,
847+
},
848+
],
849+
},
850+
},
851+
},
866852
}
867853
}
868854

@@ -948,17 +934,6 @@ function bindingToApi(
948934
turbopack.rules = serializeTurbopackRules(turbopack.rules)
949935
}
950936

951-
const conditions: (typeof nextConfig)['turbopack']['conditions'] =
952-
turbopack.conditions
953-
if (conditions) {
954-
const serializedConditions: { [key: string]: SerializedRuleCondition } =
955-
{}
956-
for (const [key, value] of Object.entries(conditions)) {
957-
serializedConditions[key] = serializeRuleCondition(value)
958-
}
959-
turbopack.conditions = serializedConditions
960-
}
961-
962937
nextConfigSerializable.turbopack = turbopack
963938
}
964939

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ const zTurbopackRuleConfigCollection: zod.ZodType<TurbopackRuleConfigCollection>
149149

150150
const zTurbopackConfig: zod.ZodType<TurbopackOptions> = z.strictObject({
151151
rules: z.record(z.string(), zTurbopackRuleConfigCollection).optional(),
152-
conditions: z.record(z.string(), zTurbopackCondition).optional(),
153152
resolveAlias: z
154153
.record(
155154
z.string(),

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

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ export interface TurbopackOptions {
301301
/**
302302
* (`next --turbopack` only) A mapping of aliased imports to modules to load in their place.
303303
*
304-
* @see [Resolve Alias](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#resolve-alias)
304+
* @see [Resolve Alias](https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#resolving-aliases)
305305
*/
306306
resolveAlias?: Record<
307307
string,
@@ -311,24 +311,17 @@ export interface TurbopackOptions {
311311
/**
312312
* (`next --turbopack` only) A list of extensions to resolve when importing files.
313313
*
314-
* @see [Resolve Extensions](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#resolve-extensions)
314+
* @see [Resolve Extensions](https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#resolving-custom-extensions)
315315
*/
316316
resolveExtensions?: string[]
317317

318318
/**
319319
* (`next --turbopack` only) A list of webpack loaders to apply when running with Turbopack.
320320
*
321-
* @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders)
321+
* @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#configuring-webpack-loaders)
322322
*/
323323
rules?: Record<string, TurbopackRuleConfigCollection>
324324

325-
/**
326-
* (`next --turbopack` only) A list of conditions to apply when running webpack loaders with Turbopack.
327-
*
328-
* @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders)
329-
*/
330-
conditions?: Record<`#${string}`, TurbopackRuleCondition>
331-
332325
/**
333326
* The module ID strategy to use for Turbopack.
334327
* If not set, the default is `'named'` for development and `'deterministic'`
@@ -348,7 +341,7 @@ export interface DeprecatedExperimentalTurboOptions extends TurbopackOptions {
348341
* (`next --turbopack` only) A list of webpack loaders to apply when running with Turbopack.
349342
*
350343
* @deprecated Use `rules` instead.
351-
* @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders)
344+
* @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#configuring-webpack-loaders)
352345
*/
353346
loaders?: Record<string, TurbopackLoaderItem[]>
354347

turbopack/crates/turbopack/src/module_options/mod.rs

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -577,37 +577,11 @@ impl ModuleOptions {
577577
for (key, rule) in webpack_loaders_options.rules.await?.iter() {
578578
let mut rule_conditions = Vec::new();
579579

580-
if key.starts_with("#") {
581-
// Legacy (undocumented) condition reference syntax:
582-
// https://www.notion.so/vercel/Turbopack-loader-rule-syntax-254e06b059c4809096d1e7c9afad278c
583-
//
584-
// This is a custom marker requiring a corresponding condition entry
585-
let conditions = (*webpack_loaders_options.conditions.await?)
586-
.context(
587-
"Expected a condition entry for the webpack loader rule matching \
588-
{key}. Create a `conditions` mapping in your next.config.js",
589-
)?
590-
.await?;
591-
592-
let condition = conditions.get(key).context(
593-
"Expected a condition entry for the webpack loader rule matching {key}.",
594-
)?;
595-
596-
rule_conditions.push(
597-
rule_condition_from_webpack_condition(
598-
execution_context,
599-
&*builtin_conditions,
600-
condition,
601-
)
602-
.await?,
603-
)
604-
} else {
605-
// prefer to add this condition ahead of the user-defined `condition` field,
606-
// because we know it's cheap to check
607-
rule_conditions.push(
608-
rule_condition_from_webpack_condition_glob(execution_context, key).await?,
609-
)
610-
};
580+
// prefer to add the glob condition ahead of the user-defined `condition` field,
581+
// because we know it's cheap to check
582+
rule_conditions.push(
583+
rule_condition_from_webpack_condition_glob(execution_context, key).await?,
584+
);
611585

612586
if let Some(condition) = &rule.condition {
613587
rule_conditions.push(

turbopack/crates/turbopack/src/module_options/module_options_context.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::fmt::Debug;
33
use serde::{Deserialize, Serialize};
44
use turbo_esregex::EsRegex;
55
use turbo_rcstr::RcStr;
6-
use turbo_tasks::{FxIndexMap, NonLocalValue, ResolvedVc, ValueDefault, Vc, trace::TraceRawVcs};
6+
use turbo_tasks::{NonLocalValue, ResolvedVc, ValueDefault, Vc, trace::TraceRawVcs};
77
use turbo_tasks_fs::FileSystemPath;
88
use turbopack_core::{
99
chunk::SourceMapsType, compile_time_info::CompileTimeInfo, condition::ContextCondition,
@@ -35,14 +35,6 @@ pub struct LoaderRuleItem {
3535
#[turbo_tasks::value(transparent)]
3636
pub struct WebpackRules(Vec<(RcStr, LoaderRuleItem)>);
3737

38-
#[derive(Default)]
39-
#[turbo_tasks::value(transparent)]
40-
pub struct WebpackConditions(pub FxIndexMap<RcStr, ConditionItem>);
41-
42-
#[derive(Default)]
43-
#[turbo_tasks::value(transparent)]
44-
pub struct OptionWebpackConditions(Option<ResolvedVc<WebpackConditions>>);
45-
4638
#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize, NonLocalValue)]
4739
pub enum ConditionPath {
4840
Glob(RcStr),
@@ -66,7 +58,6 @@ pub enum ConditionItem {
6658
#[derive(Clone, Debug)]
6759
pub struct WebpackLoadersOptions {
6860
pub rules: ResolvedVc<WebpackRules>,
69-
pub conditions: ResolvedVc<OptionWebpackConditions>,
7061
pub builtin_conditions: ResolvedVc<Box<dyn WebpackLoaderBuiltinConditionSet>>,
7162
pub loader_runner_package: Option<ResolvedVc<ImportMapping>>,
7263
}

0 commit comments

Comments
 (0)