Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion crates/pack-core/src/client/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ use crate::{
resolve::externals_plugin::ExternalsPlugin,
transforms::{
dynamic_import_to_require::get_dynamic_import_to_require_rule,
emotion::get_emotion_transform_rule, remove_console::get_remove_console_transform_rule,
emotion::get_emotion_transform_rule,
remove_console::get_remove_console_transform_rule,
styled_components::get_styled_components_transform_rule,
styled_jsx::get_styled_jsx_transform_rule,
swc_ecma_transform_plugins::get_swc_ecma_transform_plugin_rule,
Expand Down Expand Up @@ -461,8 +462,10 @@ pub async fn get_client_chunking_context(
runtime_type,
)
.minify_type(if mode.is_production() && *minify.await? {
let minify_config = config.minify_config().await?;
MinifyType::Minify {
mangle: (!*no_mangling.await?).then_some(MangleType::OptimalSize),
extract_comments: minify_config.extract_comments(),
}
} else {
MinifyType::NoMinify
Expand Down
54 changes: 52 additions & 2 deletions crates/pack-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ pub struct OptimizationConfig {
/// local names for variables, functions etc., which can be useful for
/// debugging/profiling purposes.
pub no_mangling: Option<bool>,
pub minify: Option<bool>,
pub minify: Option<MinifyConfig>,
pub tree_shaking: Option<bool>,
pub package_imports: Option<Vec<RcStr>>,
pub modularize_imports: Option<FxIndexMap<String, ModularizeImportPackageConfig>>,
Expand Down Expand Up @@ -691,6 +691,43 @@ pub struct OptionServerActions(Option<ServerActions>);
#[turbo_tasks::value(transparent)]
pub struct ExternalsConfig(FxIndexMap<RcStr, ExternalConfig>);

#[turbo_tasks::value(transparent)]
pub struct MinifyConfigValue(MinifyConfig);

#[derive(
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, NonLocalValue, OperationValue,
)]
#[serde(untagged)]
pub enum MinifyConfig {
Boolean(bool),
Config {
#[serde(default)]
extract_comments: bool,
},
}

impl Default for MinifyConfig {
fn default() -> Self {
MinifyConfig::Boolean(false)
}
}

impl MinifyConfig {
pub fn is_enabled(&self) -> bool {
match self {
Self::Boolean(enabled) => *enabled,
Self::Config { .. } => true,
}
}

pub fn extract_comments(&self) -> bool {
match self {
Self::Boolean(_) => false,
Self::Config { extract_comments } => *extract_comments,
}
}
}

#[turbo_tasks::value_impl]
impl Config {
#[turbo_tasks::function]
Expand Down Expand Up @@ -1135,13 +1172,26 @@ impl Config {
let minify = self
.optimization
.as_ref()
.map(|op| op.minify.is_none_or(|minify| minify));
.and_then(|op| op.minify.as_ref())
.map(|minify| minify.is_enabled());

Ok(Vc::cell(
minify.unwrap_or(matches!(*mode.await?, Mode::Production)),
))
}

#[turbo_tasks::function]
pub fn minify_config(&self) -> Vc<MinifyConfigValue> {
let minify_config = self
.optimization
.as_ref()
.and_then(|op| op.minify.as_ref())
.cloned()
.unwrap_or_default();

MinifyConfigValue(minify_config).cell()
}

#[turbo_tasks::function]
pub fn no_mangling(&self) -> Vc<bool> {
Vc::cell(
Expand Down
8 changes: 7 additions & 1 deletion crates/pack-core/src/library/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ use turbopack_core::{
environment::Environment,
};

use crate::{config::Config, mode::Mode};
use crate::{
config::Config,
mode::Mode,
shared::transforms::extract_comments::get_extract_comments_transform_rule,
};

use super::LibraryChunkingContext;

Expand Down Expand Up @@ -52,8 +56,10 @@ pub async fn get_library_chunking_context(
(*runtime_export.await?).clone(),
)
.minify_type(if mode.is_production() && *minify.await? {
let minify_config = config.minify_config().await?;
MinifyType::Minify {
mangle: (!*no_mangling.await?).then_some(MangleType::OptimalSize),
extract_comments: minify_config.extract_comments(),
}
} else {
MinifyType::NoMinify
Expand Down
17 changes: 15 additions & 2 deletions crates/pack-core/src/library/ecmascript/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,21 @@ impl EcmascriptLibraryEvaluateChunk {

let mut code = code.build();

if let MinifyType::Minify { mangle } = this.chunking_context.await?.minify_type() {
code = minify(code, source_maps, mangle)?;
if let MinifyType::Minify { mangle, extract_comments } = this.chunking_context.await?.minify_type() {
let result = turbopack_ecmascript::minify::minify_with_options(
code,
source_maps,
mangle,
extract_comments
)?;

code = result.code;

// TODO: Handle extracted comments by creating a license file
// For now, we'll just ignore the extracted comments
if let Some(_extracted_comments) = result.extracted_comments {
// Future implementation: create a LicenseAsset and add it to output
}
}

Ok(code.cell())
Expand Down
1 change: 1 addition & 0 deletions crates/pack-core/src/shared/transforms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use image::{StructuredImageModuleType, module::BlurPlaceholderMode};

pub mod dynamic_import_to_require;
pub mod emotion;
pub mod extract_comments;
pub mod image;
pub mod modularize_imports;
pub mod remove_console;
Expand Down
19 changes: 17 additions & 2 deletions crates/pack-schema/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,21 @@ pub enum SchemaOutputType {
Export,
}

/// Minify configuration that can be either boolean or advanced options
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum SchemaMinifyConfig {
/// Simple boolean to enable/disable minification
Boolean(bool),
/// Advanced minification configuration
Config {
/// Comment extraction configuration
#[serde(default)]
#[schemars(description = "Whether to extract comments to separate files")]
extract_comments: bool,
},
}

/// Optimization configuration
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
Expand All @@ -209,8 +224,8 @@ pub struct SchemaOptimizationConfig {

/// Whether to minify the output
#[serde(skip_serializing_if = "Option::is_none")]
#[schemars(description = "Whether to minify the output")]
pub minify: Option<bool>,
#[schemars(description = "Minify configuration - can be boolean or advanced options with extractComments")]
pub minify: Option<SchemaMinifyConfig>,

/// Whether to enable tree shaking
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
24 changes: 24 additions & 0 deletions examples/minify-extract-comments/project_options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "../../packages/pack/config_schema.json",
"rootPath": "../../",
"projectPath": "./",
"config": {
"entry": [
{
"import": "./src/index.js"
}
],
"output": {
"path": "./dist",
"filename": "[name].[contenthash:6].js",
"chunkFilename": "[name].[contenthash:8].js",
"clean": true
},
"sourceMaps": false,
"optimization": {
"minify": {
"extract_comments": true
}
}
}
}
32 changes: 28 additions & 4 deletions packages/pack/config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,26 @@
}
}
},
"SchemaMinifyConfig": {
"description": "Minify configuration that can be either boolean or advanced options",
"anyOf": [
{
"description": "Simple boolean to enable/disable minification",
"type": "boolean"
},
{
"description": "Advanced minification configuration",
"type": "object",
"properties": {
"extract_comments": {
"description": "Whether to extract comments to separate files",
"default": false,
"type": "boolean"
}
}
}
]
},
"SchemaModuleConfig": {
"description": "Module configuration",
"type": "object",
Expand Down Expand Up @@ -527,10 +547,14 @@
]
},
"minify": {
"description": "Whether to minify the output",
"type": [
"boolean",
"null"
"description": "Minify configuration - can be boolean or advanced options with extractComments",
"anyOf": [
{
"$ref": "#/definitions/SchemaMinifyConfig"
},
{
"type": "null"
}
]
},
"modularizeImports": {
Expand Down
Loading