Skip to content

Commit e0adc48

Browse files
wbinnssmithtimneutkens
authored andcommitted
Turbopack: support config.turbopack and deprecate config.experimental.turbopack.
This: - Adds support for using `config.turbopack` for Turbopack. The accepted value for this option is identical to the previous experimental one without the deprecated field `loaders`. - Deprecates `config.experimental.turbo`. Warns on its use, but will continue to accept it, merging it with `config.turbopack` while preferring fields on `config.turbopack`. Test Plan: - [ ] Convert use of `config.experimental.turbo` in tests to `config.turbopack` - [ ] Automated test for accepting the experimental option for compatibility, as well as the config merging
1 parent caa595e commit e0adc48

File tree

30 files changed

+311
-244
lines changed

30 files changed

+311
-244
lines changed

Diff for: bench/heavy-npm-deps/next.config.mjs

+1-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ const nextConfig = {
77
ignoreBuildErrors: true,
88
},
99
experimental: {
10-
turbo: {
11-
unstablePersistentCaching: process.env.TURBO_CACHE === '1',
12-
},
10+
turbopackPersistentCaching: process.env.TURBO_CACHE === '1',
1311
},
1412
}
1513

Diff for: crates/next-core/src/next_config.rs

+12-33
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub struct NextConfig {
9494
pub cross_origin: Option<CrossOriginConfig>,
9595
pub dev_indicators: Option<DevIndicatorsConfig>,
9696
pub output: Option<OutputType>,
97+
pub turbopack: Option<TurbopackConfig>,
9798

9899
/// Enables the bundling of node_modules packages (externals) for pages
99100
/// server-side bundles.
@@ -536,7 +537,7 @@ pub enum RemotePatternProtocal {
536537
OperationValue,
537538
)]
538539
#[serde(rename_all = "camelCase")]
539-
pub struct ExperimentalTurboConfig {
540+
pub struct TurbopackConfig {
540541
/// This option has been replaced by `rules`.
541542
pub loaders: Option<JsonValue>,
542543
pub rules: Option<FxIndexMap<RcStr, RuleConfigItemOrShortcut>>,
@@ -546,7 +547,6 @@ pub struct ExperimentalTurboConfig {
546547
pub module_id_strategy: Option<ModuleIdStrategy>,
547548
pub minify: Option<bool>,
548549
pub source_maps: Option<bool>,
549-
pub unstable_persistent_caching: Option<bool>,
550550
}
551551

552552
#[derive(
@@ -668,7 +668,6 @@ pub struct ExperimentalConfig {
668668
mdx_rs: Option<MdxRsOptions>,
669669
strict_next_head: Option<bool>,
670670
swc_plugins: Option<Vec<(RcStr, serde_json::Value)>>,
671-
turbo: Option<ExperimentalTurboConfig>,
672671
external_middleware_rewrites_resolve: Option<bool>,
673672
scroll_restoration: Option<bool>,
674673
manual_client_base_path: Option<bool>,
@@ -748,6 +747,7 @@ pub struct ExperimentalConfig {
748747
/// (doesn't apply to Turbopack).
749748
webpack_build_worker: Option<bool>,
750749
worker_threads: Option<bool>,
750+
turbopack_persistent_caching: Option<bool>,
751751
}
752752

753753
#[derive(
@@ -1144,12 +1144,7 @@ impl NextConfig {
11441144

11451145
#[turbo_tasks::function]
11461146
pub fn webpack_rules(&self, active_conditions: Vec<RcStr>) -> Vc<OptionWebpackRules> {
1147-
let Some(turbo_rules) = self
1148-
.experimental
1149-
.turbo
1150-
.as_ref()
1151-
.and_then(|t| t.rules.as_ref())
1152-
else {
1147+
let Some(turbo_rules) = self.turbopack.as_ref().and_then(|t| t.rules.as_ref()) else {
11531148
return Vc::cell(None);
11541149
};
11551150
if turbo_rules.is_empty() {
@@ -1234,18 +1229,15 @@ impl NextConfig {
12341229
pub fn persistent_caching_enabled(&self) -> Result<Vc<bool>> {
12351230
Ok(Vc::cell(
12361231
self.experimental
1237-
.turbo
1238-
.as_ref()
1239-
.and_then(|t| t.unstable_persistent_caching)
1232+
.turbopack_persistent_caching
12401233
.unwrap_or_default(),
12411234
))
12421235
}
12431236

12441237
#[turbo_tasks::function]
12451238
pub fn resolve_alias_options(&self) -> Result<Vc<ResolveAliasMap>> {
12461239
let Some(resolve_alias) = self
1247-
.experimental
1248-
.turbo
1240+
.turbopack
12491241
.as_ref()
12501242
.and_then(|t| t.resolve_alias.as_ref())
12511243
else {
@@ -1258,8 +1250,7 @@ impl NextConfig {
12581250
#[turbo_tasks::function]
12591251
pub fn resolve_extension(&self) -> Vc<ResolveExtensions> {
12601252
let Some(resolve_extensions) = self
1261-
.experimental
1262-
.turbo
1253+
.turbopack
12631254
.as_ref()
12641255
.and_then(|t| t.resolve_extensions.as_ref())
12651256
else {
@@ -1476,11 +1467,7 @@ impl NextConfig {
14761467
&self,
14771468
_is_development: bool,
14781469
) -> Vc<OptionTreeShaking> {
1479-
let tree_shaking = self
1480-
.experimental
1481-
.turbo
1482-
.as_ref()
1483-
.and_then(|v| v.tree_shaking);
1470+
let tree_shaking = self.turbopack.as_ref().and_then(|v| v.tree_shaking);
14841471

14851472
OptionTreeShaking(match tree_shaking {
14861473
Some(false) => Some(TreeShakingMode::ReexportsOnly),
@@ -1492,11 +1479,7 @@ impl NextConfig {
14921479

14931480
#[turbo_tasks::function]
14941481
pub fn tree_shaking_mode_for_user_code(&self, _is_development: bool) -> Vc<OptionTreeShaking> {
1495-
let tree_shaking = self
1496-
.experimental
1497-
.turbo
1498-
.as_ref()
1499-
.and_then(|v| v.tree_shaking);
1482+
let tree_shaking = self.turbopack.as_ref().and_then(|v| v.tree_shaking);
15001483

15011484
OptionTreeShaking(match tree_shaking {
15021485
Some(false) => Some(TreeShakingMode::ReexportsOnly),
@@ -1508,11 +1491,7 @@ impl NextConfig {
15081491

15091492
#[turbo_tasks::function]
15101493
pub fn module_id_strategy_config(&self) -> Vc<OptionModuleIdStrategy> {
1511-
let Some(module_id_strategy) = self
1512-
.experimental
1513-
.turbo
1514-
.as_ref()
1515-
.and_then(|t| t.module_id_strategy)
1494+
let Some(module_id_strategy) = self.turbopack.as_ref().and_then(|t| t.module_id_strategy)
15161495
else {
15171496
return Vc::cell(None);
15181497
};
@@ -1521,7 +1500,7 @@ impl NextConfig {
15211500

15221501
#[turbo_tasks::function]
15231502
pub async fn turbo_minify(&self, mode: Vc<NextMode>) -> Result<Vc<bool>> {
1524-
let minify = self.experimental.turbo.as_ref().and_then(|t| t.minify);
1503+
let minify = self.turbopack.as_ref().and_then(|t| t.minify);
15251504

15261505
Ok(Vc::cell(
15271506
minify.unwrap_or(matches!(*mode.await?, NextMode::Build)),
@@ -1530,7 +1509,7 @@ impl NextConfig {
15301509

15311510
#[turbo_tasks::function]
15321511
pub async fn turbo_source_maps(&self) -> Result<Vc<bool>> {
1533-
let source_maps = self.experimental.turbo.as_ref().and_then(|t| t.source_maps);
1512+
let source_maps = self.turbopack.as_ref().and_then(|t| t.source_maps);
15341513

15351514
Ok(Vc::cell(source_maps.unwrap_or(true)))
15361515
}

Diff for: examples/with-react-native-web/next.config.js

+16-18
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
/** @type {import('next').NextConfig} */
22
module.exports = {
3-
experimental: {
4-
turbo: {
5-
resolveAlias: {
6-
"react-native": "react-native-web",
7-
},
8-
resolveExtensions: [
9-
".web.js",
10-
".web.jsx",
11-
".web.ts",
12-
".web.tsx",
13-
".mdx",
14-
".tsx",
15-
".ts",
16-
".jsx",
17-
".js",
18-
".mjs",
19-
".json",
20-
],
3+
turbopack: {
4+
resolveAlias: {
5+
"react-native": "react-native-web",
216
},
7+
resolveExtensions: [
8+
".web.js",
9+
".web.jsx",
10+
".web.ts",
11+
".web.tsx",
12+
".mdx",
13+
".tsx",
14+
".ts",
15+
".jsx",
16+
".js",
17+
".mjs",
18+
".json",
19+
],
2220
},
2321
webpack: (config) => {
2422
config.resolve.alias = {

Diff for: examples/with-turbopack-loaders/next.config.js

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
module.exports = {
2-
experimental: {
3-
turbo: {
4-
rules: {
5-
"*.react.svg": {
6-
loaders: ["@svgr/webpack"],
7-
as: "*.js",
8-
},
9-
"*.styl": {
10-
loaders: ["stylus-loader"],
11-
as: "*.css",
12-
},
2+
turbopack: {
3+
rules: {
4+
"*.react.svg": {
5+
loaders: ["@svgr/webpack"],
6+
as: "*.js",
7+
},
8+
"*.styl": {
9+
loaders: ["stylus-loader"],
10+
as: "*.css",
1311
},
1412
},
1513
},

Diff for: packages/next/src/build/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3739,7 +3739,7 @@ function warnAboutTurbopackBuilds(config?: NextConfigComplete) {
37393739
warningStr +=
37403740
'\n\n- It is expected that your bundle size might be different from `next build` with webpack. This will be improved as we work towards stability.'
37413741

3742-
if (!config?.experimental.turbo?.unstablePersistentCaching) {
3742+
if (!config?.experimental.turbopackPersistentCaching) {
37433743
warningStr +=
37443744
'\n- This build is without disk caching; subsequent builds will become faster when disk caching becomes available.'
37453745
}

Diff for: packages/next/src/build/swc/index.ts

+19-16
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import { patchIncorrectLockfile } from '../../lib/patch-incorrect-lockfile'
1010
import { downloadNativeNextSwc, downloadWasmSwc } from '../../lib/download-swc'
1111
import type {
1212
NextConfigComplete,
13-
TurboLoaderItem,
14-
TurboRuleConfigItem,
15-
TurboRuleConfigItemOptions,
16-
TurboRuleConfigItemOrShortcut,
13+
TurbopackLoaderItem,
14+
TurbopackRuleConfigItem,
15+
TurbopackRuleConfigItemOptions,
16+
TurbopackRuleConfigItemOrShortcut,
1717
} from '../../server/config-shared'
1818
import { isDeepStrictEqual } from 'util'
1919
import {
@@ -786,24 +786,24 @@ function bindingToApi(
786786
if (reactCompilerOptions) {
787787
const ruleKeys = ['*.ts', '*.js', '*.jsx', '*.tsx']
788788
if (
789-
Object.keys(nextConfig?.experimental?.turbo?.rules ?? []).some((key) =>
789+
Object.keys(nextConfig?.turbopack?.rules ?? []).some((key) =>
790790
ruleKeys.includes(key)
791791
)
792792
) {
793793
Log.warn(
794-
`The React Compiler cannot be enabled automatically because 'experimental.turbo' contains a rule for '*.ts', '*.js', '*.jsx', and '*.tsx'. Remove this rule, or add 'babel-loader' and 'babel-plugin-react-compiler' to the Turbopack configuration manually.`
794+
`The React Compiler cannot be enabled automatically because 'turbopack.rules' contains a rule for '*.ts', '*.js', '*.jsx', and '*.tsx'. Remove this rule, or add 'babel-loader' and 'babel-plugin-react-compiler' to the Turbopack configuration manually.`
795795
)
796796
} else {
797-
if (!nextConfig.experimental.turbo) {
798-
nextConfig.experimental.turbo = {}
797+
if (!nextConfig.turbopack) {
798+
nextConfig.turbopack = {}
799799
}
800800

801-
if (!nextConfig.experimental.turbo.rules) {
802-
nextConfig.experimental.turbo.rules = {}
801+
if (!nextConfig.turbopack.rules) {
802+
nextConfig.turbopack.rules = {}
803803
}
804804

805805
for (const key of ['*.ts', '*.js', '*.jsx', '*.tsx']) {
806-
nextConfig.experimental.turbo.rules[key] = {
806+
nextConfig.turbopack.rules[key] = {
807807
browser: {
808808
foreign: false,
809809
loaders: [
@@ -840,7 +840,7 @@ function bindingToApi(
840840

841841
if (nextConfigSerializable.experimental?.turbo?.rules) {
842842
ensureLoadersHaveSerializableOptions(
843-
nextConfigSerializable.experimental.turbo?.rules
843+
nextConfigSerializable.turbopack?.rules
844844
)
845845
}
846846

@@ -878,7 +878,7 @@ function bindingToApi(
878878
}
879879

880880
function ensureLoadersHaveSerializableOptions(
881-
turbopackRules: Record<string, TurboRuleConfigItemOrShortcut>
881+
turbopackRules: Record<string, TurbopackRuleConfigItemOrShortcut>
882882
) {
883883
for (const [glob, rule] of Object.entries(turbopackRules)) {
884884
if (Array.isArray(rule)) {
@@ -888,10 +888,10 @@ function bindingToApi(
888888
}
889889
}
890890

891-
function checkConfigItem(rule: TurboRuleConfigItem, glob: string) {
891+
function checkConfigItem(rule: TurbopackRuleConfigItem, glob: string) {
892892
if (!rule) return
893893
if ('loaders' in rule) {
894-
checkLoaderItems((rule as TurboRuleConfigItemOptions).loaders, glob)
894+
checkLoaderItems((rule as TurbopackRuleConfigItemOptions).loaders, glob)
895895
} else {
896896
for (const key in rule) {
897897
const inner = rule[key]
@@ -902,7 +902,10 @@ function bindingToApi(
902902
}
903903
}
904904

905-
function checkLoaderItems(loaderItems: TurboLoaderItem[], glob: string) {
905+
function checkLoaderItems(
906+
loaderItems: TurbopackLoaderItem[],
907+
glob: string
908+
) {
906909
for (const loaderItem of loaderItems) {
907910
if (
908911
typeof loaderItem !== 'string' &&

Diff for: packages/next/src/build/turbopack-build/impl.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ export async function turbopackBuild(): Promise<{
5454
const project = await bindings.turbo.createProject(
5555
{
5656
projectPath: dir,
57-
rootPath:
58-
config.experimental?.turbo?.root || config.outputFileTracingRoot || dir,
57+
rootPath: config.turbopack?.root || config.outputFileTracingRoot || dir,
5958
distDir,
6059
nextConfig: config,
6160
jsConfig: await getTurbopackJsConfig(dir, config),
@@ -83,7 +82,7 @@ export async function turbopackBuild(): Promise<{
8382
},
8483
{
8584
persistentCaching,
86-
memoryLimit: config.experimental.turbo?.memoryLimit,
85+
memoryLimit: config.turbopack?.memoryLimit,
8786
dependencyTracking: persistentCaching,
8887
}
8988
)

Diff for: packages/next/src/lib/turbopack-warning.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export async function validateTurboNextConfig({
144144
if (key.startsWith('webpack') && rawNextConfig.webpack) {
145145
hasWebpackConfig = true
146146
}
147-
if (key.startsWith('experimental.turbo')) {
147+
if (key.startsWith('turbopack')) {
148148
hasTurboConfig = true
149149
}
150150

0 commit comments

Comments
 (0)