diff --git a/packages/next/build/swc/src/styled_jsx/mod.rs b/packages/next/build/swc/src/styled_jsx/mod.rs index 2abf9985e7a60..80973b2b599e1 100644 --- a/packages/next/build/swc/src/styled_jsx/mod.rs +++ b/packages/next/build/swc/src/styled_jsx/mod.rs @@ -36,6 +36,7 @@ struct StyledJSXTransformer { has_styled_jsx: bool, bindings: AHashSet, nearest_scope_bindings: AHashSet, + func_scope_level: u8, style_import_name: Option, external_bindings: Vec, file_has_css_resolve: bool, @@ -185,7 +186,7 @@ impl Fold for StyledJSXTransformer { Expr::TaggedTpl(tagged_tpl) => match &*tagged_tpl.tag { Expr::Ident(identifier) => { if self.external_bindings.contains(&identifier.to_id()) { - match self.process_tagged_template_expr(&tagged_tpl) { + match self.process_tagged_template_expr(&tagged_tpl, &identifier.sym) { Ok(expr) => expr, Err(_) => Expr::TaggedTpl(tagged_tpl), } @@ -199,7 +200,7 @@ impl Fold for StyledJSXTransformer { }) => { if let Expr::Ident(identifier) = &**boxed_ident { if self.external_bindings.contains(&identifier.to_id()) { - match self.process_tagged_template_expr(&tagged_tpl) { + match self.process_tagged_template_expr(&tagged_tpl, &identifier.sym) { Ok(expr) => expr, Err(_) => Expr::TaggedTpl(tagged_tpl), } @@ -320,6 +321,7 @@ impl Fold for StyledJSXTransformer { } fn fold_function(&mut self, mut func: Function) -> Function { + self.func_scope_level = self.func_scope_level + 1; let surrounding_scope_bindings = take(&mut self.nearest_scope_bindings); self.in_function_params = true; let mut new_params = vec![]; @@ -331,10 +333,12 @@ impl Fold for StyledJSXTransformer { self.nearest_scope_bindings.extend(collect_decls(&func)); func.body = func.body.fold_with(self); self.nearest_scope_bindings = surrounding_scope_bindings; + self.func_scope_level = self.func_scope_level - 1; func } fn fold_arrow_expr(&mut self, mut func: ArrowExpr) -> ArrowExpr { + self.func_scope_level = self.func_scope_level + 1; let surrounding_scope_bindings = take(&mut self.nearest_scope_bindings); self.in_function_params = true; let mut new_params = vec![]; @@ -346,6 +350,7 @@ impl Fold for StyledJSXTransformer { self.nearest_scope_bindings.extend(collect_decls(&func)); func.body = func.body.fold_with(self); self.nearest_scope_bindings = surrounding_scope_bindings; + self.func_scope_level = self.func_scope_level - 1; func } @@ -425,11 +430,15 @@ impl StyledJSXTransformer { } css = String::from(s); css_span = *span; - let res = self.evaluator.as_mut().unwrap().eval(&expr); - is_dynamic = if let Some(EvalResult::Lit(_)) = res { - false + is_dynamic = if self.func_scope_level > 0 { + let res = self.evaluator.as_mut().unwrap().eval(&expr); + if let Some(EvalResult::Lit(_)) = res { + false + } else { + true + } } else { - true + false }; expressions = exprs.clone(); } @@ -495,7 +504,16 @@ impl StyledJSXTransformer { } } - fn process_tagged_template_expr(&mut self, tagged_tpl: &TaggedTpl) -> Result { + fn process_tagged_template_expr( + &mut self, + tagged_tpl: &TaggedTpl, + tag: &str, + ) -> Result { + if tag != "resolve" { + // Check whether there are undefined references or + // references to this.something (e.g. props or state). + // We allow dynamic styles only when resolving styles. + } let style = self.get_jsx_style(&Expr::Tpl(tagged_tpl.tpl.clone()), false); let styles = vec![style]; let (static_class_name, class_name) = diff --git a/packages/next/build/swc/tests/fixture/styled-jsx/styles/input.js b/packages/next/build/swc/tests/fixture/styled-jsx/styles/input.js index d76049606fd30..7cbd27576cf26 100644 --- a/packages/next/build/swc/tests/fixture/styled-jsx/styles/input.js +++ b/packages/next/build/swc/tests/fixture/styled-jsx/styles/input.js @@ -24,7 +24,6 @@ export const uh = bar export const foo = css`div { color: ${color}}` -// TODO: the next 3 should not transformed as dynamic css.resolve` div { color: ${colors.green.light}; diff --git a/packages/next/build/swc/tests/fixture/styled-jsx/styles/output.js b/packages/next/build/swc/tests/fixture/styled-jsx/styles/output.js index 057e8963dc33e..eafa22c8e539a 100644 --- a/packages/next/build/swc/tests/fixture/styled-jsx/styles/output.js +++ b/packages/next/build/swc/tests/fixture/styled-jsx/styles/output.js @@ -11,32 +11,14 @@ export const uh = bar; export const foo = new String(`div.jsx-a0d126276b085021 {color:${color}}`); foo.__hash = "a0d126276b085021"; ({ - styles: <_JSXStyle id={"47e08c293b53f262"} dynamic={[ - colors1.green.light - ]}>{`div.__jsx-style-dynamic-selector {color:${colors1.green.light}} -a.__jsx-style-dynamic-selector {color:red}`}, - className: _JSXStyle.dynamic([ - [ - "47e08c293b53f262", - [ - colors1.green.light - ] - ] - ]) + styles: <_JSXStyle id={"47e08c293b53f262"}>{`div.jsx-47e08c293b53f262 {color:${colors1.green.light}} +a.jsx-47e08c293b53f262 {color:red}`}, + className: "jsx-47e08c293b53f262" }); const b = { - styles: <_JSXStyle id={"47e08c293b53f262"} dynamic={[ - colors1.green.light - ]}>{`div.__jsx-style-dynamic-selector {color:${colors1.green.light}} -a.__jsx-style-dynamic-selector {color:red}`}, - className: _JSXStyle.dynamic([ - [ - "47e08c293b53f262", - [ - colors1.green.light - ] - ] - ]) + styles: <_JSXStyle id={"47e08c293b53f262"}>{`div.jsx-47e08c293b53f262 {color:${colors1.green.light}} +a.jsx-47e08c293b53f262 {color:red}`}, + className: "jsx-47e08c293b53f262" }; const dynamic = (colors)=>{ const b = {