diff --git a/crates/turbopack-ecmascript/src/transform/mod.rs b/crates/turbopack-ecmascript/src/transform/mod.rs index cf312e6b66535..0a962b4ecc1a5 100644 --- a/crates/turbopack-ecmascript/src/transform/mod.rs +++ b/crates/turbopack-ecmascript/src/transform/mod.rs @@ -37,7 +37,12 @@ pub enum EcmascriptInputTransform { ServerDirective(StringVc), CommonJs, Custom(CustomTransformVc), - Emotion, + Emotion { + #[serde(default)] + sourcemap: bool, + label_format: OptionStringVc, + auto_label: Option, + }, PresetEnv(EnvironmentVc), React { #[serde(default)] @@ -185,10 +190,24 @@ impl EcmascriptInputTransform { Some(comments.clone()), )); } - EcmascriptInputTransform::Emotion => { + EcmascriptInputTransform::Emotion { + sourcemap, + label_format, + auto_label, + } => { + let options = swc_emotion::EmotionOptions { + // this should be always enabled if match arrives here: + // since moduleoptions expect to push emotion transform only if + // there are valid, enabled config values. + enabled: Some(true), + sourcemap: Some(*sourcemap), + label_format: label_format.await?.clone_value(), + auto_label: *auto_label, + ..Default::default() + }; let p = std::mem::replace(program, Program::Module(Module::dummy())); *program = p.fold_with(&mut swc_emotion::emotion( - Default::default(), + options, Path::new(file_name_str), source_map.clone(), comments.clone(), diff --git a/crates/turbopack-tests/tests/snapshot.rs b/crates/turbopack-tests/tests/snapshot.rs index b9c167f9dd2bb..e85b7b1b63d94 100644 --- a/crates/turbopack-tests/tests/snapshot.rs +++ b/crates/turbopack-tests/tests/snapshot.rs @@ -20,7 +20,9 @@ use turbo_tasks_memory::MemoryBackend; use turbopack::{ condition::ContextCondition, ecmascript::EcmascriptModuleAssetVc, - module_options::{JsxTransformOptions, JsxTransformOptionsVc, ModuleOptionsContext}, + module_options::{ + EmotionTransformConfig, JsxTransformOptions, JsxTransformOptionsVc, ModuleOptionsContext, + }, resolve_options_context::ResolveOptionsContext, transition::TransitionsByNameVc, ModuleAssetContextVc, @@ -193,7 +195,10 @@ async fn run_test(resource: &str) -> Result { enable_jsx: Some(JsxTransformOptionsVc::cell(JsxTransformOptions { ..Default::default() })), - enable_emotion: true, + enable_emotion: Some(EmotionTransformConfig::cell(EmotionTransformConfig { + sourcemap: Some(false), + ..Default::default() + })), enable_styled_components: true, preset_env_versions: Some(env), rules: vec![( diff --git a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js index 46ab6a63aa546..a0f87e9914ef6 100644 --- a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js +++ b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js @@ -10,9 +10,8 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests ; ; const StyledButton = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$node_modules$2f40$emotion$2f$styled$2f$index$2e$js__$28$ecmascript$29$__["default"]("button", { - target: "e1r1p2t30", - label: "StyledButton" -})("background:blue;", "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAanN4SW1wb3J0U291cmNlIEBlbW90aW9uL3JlYWN0ICovXG5cbmltcG9ydCB7IGpzeCB9IGZyb20gXCJAZW1vdGlvbi9yZWFjdFwiO1xuaW1wb3J0IHN0eWxlZCBmcm9tIFwiQGVtb3Rpb24vc3R5bGVkXCI7XG5cbmNvbnN0IFN0eWxlZEJ1dHRvbiA9IHN0eWxlZC5idXR0b25gXG4gIGJhY2tncm91bmQ6IGJsdWU7XG5gO1xuXG5mdW5jdGlvbiBDbGFzc05hbWVCdXR0b24oeyBjaGlsZHJlbiB9KSB7XG4gIHJldHVybiAoXG4gICAgPGJ1dHRvblxuICAgICAgY2xhc3NOYW1lPXtjc3NgXG4gICAgICAgIGJhY2tncm91bmQ6IGJsdWU7XG4gICAgICBgfVxuICAgID5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L2J1dHRvbj5cbiAgKTtcbn1cblxuY29uc29sZS5sb2coU3R5bGVkQnV0dG9uLCBDbGFzc05hbWVCdXR0b24pO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtxQiJ9 */"); + target: "e1r1p2t30" +})("background:blue;"); function ClassNameButton({ children }) { return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$node_modules$2f40$emotion$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$28$ecmascript$29$__["jsxDEV"]("button", { className: css` diff --git a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js.map b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js.map index 1d22ca47c74a5..46599351e5ba0 100644 --- a/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js.map +++ b/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b53fce.js.map @@ -1,6 +1,6 @@ { "version": 3, "sections": [ - {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js"],"sourcesContent":["/** @jsxImportSource @emotion/react */\n\nimport { jsx } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\n\nconst StyledButton = styled.button`\n background: blue;\n`;\n\nfunction ClassNameButton({ children }) {\n return (\n \n {children}\n \n );\n}\n\nconsole.log(StyledButton, ClassNameButton);\n"],"names":[],"mappings":";;;;;;;AAKA,MAAM;;;;AAIN,SAAS,gBAAgB,EAAE,SAAQ,EAAE,EAAE;IACrC,OACE,2LAAC;QACC,WAAW,GAAG,CAAC;;MAEf,CAAC;kBAEA;;;;;;AAGP;AAEA,QAAQ,GAAG,CAAC,cAAc"}}, - {"offset": {"line": 28, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["/turbopack/[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js"],"sourcesContent":["/** @jsxImportSource @emotion/react */\n\nimport { jsx } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\n\nconst StyledButton = styled.button`\n background: blue;\n`;\n\nfunction ClassNameButton({ children }) {\n return (\n \n {children}\n \n );\n}\n\nconsole.log(StyledButton, ClassNameButton);\n"],"names":[],"mappings":";;;;;;;AAKA,MAAM;;;AAIN,SAAS,gBAAgB,EAAE,SAAQ,EAAE,EAAE;IACrC,OACE,2LAAC;QACC,WAAW,GAAG,CAAC;;MAEf,CAAC;kBAEA;;;;;;AAGP;AAEA,QAAQ,GAAG,CAAC,cAAc"}}, + {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] } \ No newline at end of file diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index 4ae3ea4a92772..810f6a4964851 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -61,7 +61,7 @@ impl ModuleOptionsVc { ) -> Result { let ModuleOptionsContext { enable_jsx, - enable_emotion, + ref enable_emotion, enable_react_refresh, enable_styled_jsx, enable_styled_components, @@ -96,8 +96,22 @@ impl ModuleOptionsVc { if enable_styled_jsx { transforms.push(EcmascriptInputTransform::StyledJsx); } - if enable_emotion { - transforms.push(EcmascriptInputTransform::Emotion); + if let Some(enable_emotion) = enable_emotion { + let emotion_transform = enable_emotion.await?; + transforms.push(EcmascriptInputTransform::Emotion { + sourcemap: emotion_transform.sourcemap.unwrap_or(false), + label_format: OptionStringVc::cell(emotion_transform.label_format.clone()), + auto_label: if let Some(auto_label) = emotion_transform.auto_label.as_ref() { + match auto_label { + EmotionLabelKind::Always => Some(true), + EmotionLabelKind::Never => Some(false), + // [TODO]: this is not correct coerece, need to be fixed + EmotionLabelKind::DevOnly => None, + } + } else { + None + }, + }); } if enable_styled_components { transforms.push(EcmascriptInputTransform::StyledComponents); diff --git a/crates/turbopack/src/module_options/module_options_context.rs b/crates/turbopack/src/module_options/module_options_context.rs index de3b6d1e99fdf..9de342fbbdf6a 100644 --- a/crates/turbopack/src/module_options/module_options_context.rs +++ b/crates/turbopack/src/module_options/module_options_context.rs @@ -89,6 +89,42 @@ impl Default for TypescriptTransformOptionsVc { } } +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum EmotionLabelKind { + DevOnly, + Always, + Never, +} + +#[turbo_tasks::value(transparent)] +pub struct OptionEmotionTransformConfig(Option); + +//[TODO]: need to support importmap, there are type mismatch between +//[TODO]: next.config.js to swc's emotion options +#[turbo_tasks::value(shared)] +#[derive(Default, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct EmotionTransformConfig { + pub sourcemap: Option, + pub label_format: Option, + pub auto_label: Option, +} + +#[turbo_tasks::value_impl] +impl EmotionTransformConfigVc { + #[turbo_tasks::function] + pub fn default() -> Self { + Self::cell(Default::default()) + } +} + +impl Default for EmotionTransformConfigVc { + fn default() -> Self { + Self::default() + } +} + impl WebpackLoadersOptions { pub fn is_empty(&self) -> bool { self.extension_to_loaders.is_empty() @@ -117,7 +153,7 @@ pub struct ModuleOptionsContext { #[serde(default)] pub enable_jsx: Option, #[serde(default)] - pub enable_emotion: bool, + pub enable_emotion: Option, #[serde(default)] pub enable_react_refresh: bool, #[serde(default)]