diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index a29d2c43ade99..36d9caef0b627 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -19,8 +19,8 @@ use turbopack_browser::{ }; use turbopack_core::{ chunk::{ - module_id_strategies::ModuleIdStrategy, ChunkingConfig, ChunkingContext, MinifyType, - SourceMapsType, + module_id_strategies::ModuleIdStrategy, ChunkingConfig, ChunkingContext, MangleType, + MinifyType, SourceMapsType, }, compile_time_info::{ CompileTimeDefineValue, CompileTimeDefines, CompileTimeInfo, DefineableNameSegment, @@ -397,7 +397,7 @@ pub async fn get_client_module_options_context( css: CssOptionsContext { minify_type: if *next_config.turbo_minify(mode).await? { MinifyType::Minify { - mangle: !*no_mangling.await?, + mangle: (!*no_mangling.await?).then_some(MangleType::OptimalSize), } } else { MinifyType::NoMinify @@ -454,7 +454,7 @@ pub async fn get_client_chunking_context( .chunk_suffix_path(chunk_suffix_path) .minify_type(if *minify.await? { MinifyType::Minify { - mangle: !*no_mangling.await?, + mangle: (!*no_mangling.await?).then_some(MangleType::OptimalSize), } } else { MinifyType::NoMinify diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index 0b31b423334e2..71c4b97f2f46a 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -7,8 +7,8 @@ use turbopack::{css::chunk::CssChunkType, resolve_options_context::ResolveOption use turbopack_browser::BrowserChunkingContext; use turbopack_core::{ chunk::{ - module_id_strategies::ModuleIdStrategy, ChunkingConfig, ChunkingContext, MinifyType, - SourceMapsType, + module_id_strategies::ModuleIdStrategy, ChunkingConfig, ChunkingContext, MangleType, + MinifyType, SourceMapsType, }, compile_time_info::{ CompileTimeDefineValue, CompileTimeDefines, CompileTimeInfo, DefineableNameSegment, @@ -241,7 +241,8 @@ pub async fn get_edge_chunking_context_with_client_assets( .asset_base_path(asset_prefix) .minify_type(if *turbo_minify.await? { MinifyType::Minify { - mangle: !*no_mangling.await?, + // React needs deterministic function names to work correctly. + mangle: (!*no_mangling.await?).then_some(MangleType::Deterministic), } } else { MinifyType::NoMinify @@ -304,7 +305,7 @@ pub async fn get_edge_chunking_context( .asset_base_path(ResolvedVc::cell(Some("blob:server/edge/".into()))) .minify_type(if *turbo_minify.await? { MinifyType::Minify { - mangle: !*no_mangling.await?, + mangle: (!*no_mangling.await?).then_some(MangleType::OptimalSize), } } else { MinifyType::NoMinify diff --git a/crates/next-core/src/next_server/context.rs b/crates/next-core/src/next_server/context.rs index 883000639c51b..313fdaca39a98 100644 --- a/crates/next-core/src/next_server/context.rs +++ b/crates/next-core/src/next_server/context.rs @@ -15,7 +15,10 @@ use turbopack::{ transition::Transition, }; use turbopack_core::{ - chunk::{module_id_strategies::ModuleIdStrategy, ChunkingConfig, MinifyType, SourceMapsType}, + chunk::{ + module_id_strategies::ModuleIdStrategy, ChunkingConfig, MangleType, MinifyType, + SourceMapsType, + }, compile_time_info::{ CompileTimeDefineValue, CompileTimeDefines, CompileTimeInfo, DefineableNameSegment, FreeVarReferences, @@ -1015,7 +1018,8 @@ pub async fn get_server_chunking_context_with_client_assets( .asset_prefix(asset_prefix) .minify_type(if *turbo_minify.await? { MinifyType::Minify { - mangle: !*no_mangling.await?, + // React needs deterministic function names to work correctly. + mangle: (!*no_mangling.await?).then_some(MangleType::Deterministic), } } else { MinifyType::NoMinify @@ -1080,7 +1084,7 @@ pub async fn get_server_chunking_context( ) .minify_type(if *turbo_minify.await? { MinifyType::Minify { - mangle: !*no_mangling.await?, + mangle: (!*no_mangling.await?).then_some(MangleType::OptimalSize), } } else { MinifyType::NoMinify diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 025e7afded23a..2195ff0bbe189 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -1187,7 +1187,10 @@ export default async function getBaseWebpackConfig( 'process.env.__NEXT_PRIVATE_MINIMIZE_MACRO_FALSE': false, }, }, - mangle: !noMangling && { reserved: ['AbortSignal'] }, + mangle: !noMangling && { + reserved: ['AbortSignal'], + disableCharFreq: !isClient, + }, }, }), new (getRspackCore().LightningCssMinimizerRspackPlugin)({ diff --git a/turbopack/crates/turbopack-cli/src/build/mod.rs b/turbopack/crates/turbopack-cli/src/build/mod.rs index eec33bb857fbe..9408cee663c6f 100644 --- a/turbopack/crates/turbopack-cli/src/build/mod.rs +++ b/turbopack/crates/turbopack-cli/src/build/mod.rs @@ -27,7 +27,7 @@ use turbopack_core::{ asset::Asset, chunk::{ availability_info::AvailabilityInfo, ChunkingConfig, ChunkingContext, EvaluatableAsset, - EvaluatableAssets, MinifyType, SourceMapsType, + EvaluatableAssets, MangleType, MinifyType, SourceMapsType, }, environment::{BrowserEnvironment, Environment, ExecutionEnvironment, NodeJsEnvironment}, ident::AssetIdent, @@ -93,7 +93,9 @@ impl TurbopackBuildBuilder { show_all: false, log_detail: false, source_maps_type: SourceMapsType::Full, - minify_type: MinifyType::Minify { mangle: true }, + minify_type: MinifyType::Minify { + mangle: Some(MangleType::OptimalSize), + }, target: Target::Node, } } @@ -522,7 +524,9 @@ pub async fn build(args: &BuildArguments) -> Result<()> { .minify_type(if args.no_minify { MinifyType::NoMinify } else { - MinifyType::Minify { mangle: true } + MinifyType::Minify { + mangle: Some(MangleType::OptimalSize), + } }) .target(args.common.target.unwrap_or(Target::Node)) .show_all(args.common.show_all); diff --git a/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs index d184b33903237..52f8c40a22fe8 100644 --- a/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs +++ b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs @@ -17,6 +17,26 @@ use crate::{ output::{OutputAsset, OutputAssets}, }; +#[derive( + Debug, + TaskInput, + Clone, + Copy, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + TraceRawVcs, + DeterministicHash, + NonLocalValue, +)] +#[serde(rename_all = "kebab-case")] +pub enum MangleType { + OptimalSize, + Deterministic, +} + #[derive( Debug, TaskInput, @@ -32,13 +52,17 @@ use crate::{ NonLocalValue, )] pub enum MinifyType { - Minify { mangle: bool }, + // TODO instead of adding a new property here, + // refactor that to Minify(MinifyOptions) to allow defaults on MinifyOptions + Minify { mangle: Option }, NoMinify, } impl Default for MinifyType { fn default() -> Self { - Self::Minify { mangle: true } + Self::Minify { + mangle: Some(MangleType::OptimalSize), + } } } diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index 4419e08d5ca25..c456c98b547a2 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -29,7 +29,7 @@ pub use self::{ }, chunking_context::{ ChunkGroupResult, ChunkGroupType, ChunkingConfig, ChunkingConfigs, ChunkingContext, - ChunkingContextExt, EntryChunkGroupResult, MinifyType, SourceMapsType, + ChunkingContextExt, EntryChunkGroupResult, MangleType, MinifyType, SourceMapsType, }, data::{ChunkData, ChunkDataOption, ChunksData}, evaluate::{EvaluatableAsset, EvaluatableAssetExt, EvaluatableAssets}, diff --git a/turbopack/crates/turbopack-ecmascript/src/minify.rs b/turbopack/crates/turbopack-ecmascript/src/minify.rs index a6de8f16e7465..9a26f8a2b0f08 100644 --- a/turbopack/crates/turbopack-ecmascript/src/minify.rs +++ b/turbopack/crates/turbopack-ecmascript/src/minify.rs @@ -23,12 +23,15 @@ use swc_core::{ }, }; use tracing::{instrument, Level}; -use turbopack_core::code_builder::{Code, CodeBuilder}; +use turbopack_core::{ + chunk::MangleType, + code_builder::{Code, CodeBuilder}, +}; use crate::parse::generate_js_source_map; #[instrument(level = Level::INFO, skip_all)] -pub fn minify(code: &Code, source_maps: bool, mangle: bool) -> Result { +pub fn minify(code: &Code, source_maps: bool, mangle: Option) -> Result { let source_maps = source_maps .then(|| code.generate_source_map_ref()) .transpose()?; @@ -84,14 +87,20 @@ pub fn minify(code: &Code, source_maps: bool, mangle: bool) -> Result { passes: 2, ..Default::default() }), - mangle: if mangle { - Some(MangleOptions { - reserved: vec!["AbortSignal".into()], - ..Default::default() - }) - } else { - None - }, + mangle: mangle.map(|mangle| { + let reserved = vec!["AbortSignal".into()]; + match mangle { + MangleType::OptimalSize => MangleOptions { + reserved, + ..Default::default() + }, + MangleType::Deterministic => MangleOptions { + reserved, + disable_char_freq: true, + ..Default::default() + }, + } + }), ..Default::default() }, &ExtraOptions { @@ -101,7 +110,7 @@ pub fn minify(code: &Code, source_maps: bool, mangle: bool) -> Result { }, ); - if !mangle { + if mangle.is_none() { program.mutate(hygiene_with_config(hygiene::Config { top_level_mark, ..Default::default() diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/options.json index 9ee80c5ad1ecc..78197ec333e88 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/options.json +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/options.json @@ -2,7 +2,7 @@ "runtime": "NodeJs", "minifyType": { "Minify": { - "mangle": true + "mangle": "optimal-size" } } } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/options.json index 3b3b9ab6afcbc..012b46107ba83 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/options.json +++ b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/options.json @@ -1,7 +1,7 @@ { "minifyType": { "Minify": { - "mangle": true + "mangle": "optimal-size" } } }