From 99624bbbe760bd544ff6f52617e9d13e88b937be Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Tue, 4 Apr 2023 11:31:56 -0700 Subject: [PATCH 1/2] feat(ecmascript): support configurable emotion options --- .../turbopack-ecmascript/src/transform/mod.rs | 25 ++++++++++++-- crates/turbopack-tests/tests/snapshot.rs | 11 ++++-- crates/turbopack/src/module_options/mod.rs | 22 ++++++++++-- .../module_options/module_options_context.rs | 34 ++++++++++++++++++- 4 files changed, 83 insertions(+), 9 deletions(-) diff --git a/crates/turbopack-ecmascript/src/transform/mod.rs b/crates/turbopack-ecmascript/src/transform/mod.rs index 6d59eb76ac9e0..ef2111e3707ab 100644 --- a/crates/turbopack-ecmascript/src/transform/mod.rs +++ b/crates/turbopack-ecmascript/src/transform/mod.rs @@ -28,7 +28,12 @@ pub enum EcmascriptInputTransform { ClientDirective(StringVc), CommonJs, Custom(CustomTransformVc), - Emotion, + Emotion { + #[serde(default)] + sourcemap: bool, + label_format: OptionStringVc, + auto_label: Option, + }, PresetEnv(EnvironmentVc), React { #[serde(default)] @@ -174,10 +179,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 62b71e2922037..e0c8567171517 100644 --- a/crates/turbopack-tests/tests/snapshot.rs +++ b/crates/turbopack-tests/tests/snapshot.rs @@ -20,7 +20,10 @@ use turbo_tasks_memory::MemoryBackend; use turbopack::{ condition::ContextCondition, ecmascript::EcmascriptModuleAssetVc, - module_options::{JsxTransformOptions, JsxTransformOptionsVc, ModuleOptionsContext}, + module_options::{ + EmotionTransformOptions, EmotionTransformOptionsVc, JsxTransformOptions, + JsxTransformOptionsVc, ModuleOptionsContext, + }, resolve_options_context::ResolveOptionsContext, transition::TransitionsByNameVc, ModuleAssetContextVc, @@ -193,7 +196,11 @@ async fn run_test(resource: &str) -> Result { enable_jsx: Some(JsxTransformOptionsVc::cell(JsxTransformOptions { ..Default::default() })), - enable_emotion: true, + enable_emotion: Some(EmotionTransformOptionsVc::cell(EmotionTransformOptions { + enabled: true, + sourcemap: Some(false), + ..Default::default() + })), enable_styled_components: true, preset_env_versions: Some(env), rules: vec![( diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index 4ae3ea4a92772..bd223627e4365 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,24 @@ 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?; + if emotion_transform.enabled { + 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..dc2698f10838e 100644 --- a/crates/turbopack/src/module_options/module_options_context.rs +++ b/crates/turbopack/src/module_options/module_options_context.rs @@ -89,6 +89,38 @@ impl Default for TypescriptTransformOptionsVc { } } +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +pub enum EmotionLabelKind { + DevOnly, + Always, + Never, +} + +//[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)] +pub struct EmotionTransformOptions { + pub enabled: bool, + pub sourcemap: Option, + pub label_format: Option, + pub auto_label: Option, +} + +#[turbo_tasks::value_impl] +impl EmotionTransformOptionsVc { + #[turbo_tasks::function] + pub fn default() -> Self { + Self::cell(Default::default()) + } +} + +impl Default for EmotionTransformOptionsVc { + fn default() -> Self { + Self::default() + } +} + impl WebpackLoadersOptions { pub fn is_empty(&self) -> bool { self.extension_to_loaders.is_empty() @@ -117,7 +149,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)] From 67c88c74dbf6fde61dc81188ec2e02738ccd71e7 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Wed, 5 Apr 2023 09:12:17 -0700 Subject: [PATCH 2/2] test(snapshot): update fixtures --- ...ests_tests_snapshot_emotion_emotion_input_index_b53fce.js | 5 ++--- ..._tests_snapshot_emotion_emotion_input_index_b53fce.js.map | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) 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 8b07b8c06bc72..dc0b165837101 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