diff --git a/packages/core/integration-tests/test/integration/jsx-member/foo.jsx b/packages/core/integration-tests/test/integration/jsx-member/foo.jsx new file mode 100644 index 00000000000..4013f887b3a --- /dev/null +++ b/packages/core/integration-tests/test/integration/jsx-member/foo.jsx @@ -0,0 +1 @@ +export const Foo = null; diff --git a/packages/core/integration-tests/test/integration/jsx-member/index.jsx b/packages/core/integration-tests/test/integration/jsx-member/index.jsx new file mode 100644 index 00000000000..94d3965468b --- /dev/null +++ b/packages/core/integration-tests/test/integration/jsx-member/index.jsx @@ -0,0 +1,7 @@ +import { Foo } from "./foo"; + +const S = { + Foo: () => "S", +}; + +module.exports = ; diff --git a/packages/core/integration-tests/test/transpilation.js b/packages/core/integration-tests/test/transpilation.js index 5397e170279..cc669bbce28 100644 --- a/packages/core/integration-tests/test/transpilation.js +++ b/packages/core/integration-tests/test/transpilation.js @@ -87,6 +87,13 @@ describe('transpilation', function() { assert(file.includes('fileName: "integration/jsx/index.jsx"')); }); + it('should support compiling JSX correctly with member expression type', async function() { + await bundle(path.join(__dirname, '/integration/jsx-member/index.jsx')); + + let file = await outputFS.readFile(path.join(distDir, 'index.js'), 'utf8'); + assert(file.includes('React.createElement(S.Foo')); + }); + it('should support compiling JSX in JS files with React dependency', async function() { await bundle(path.join(__dirname, '/integration/jsx-react/index.js')); diff --git a/packages/transformers/js/core/src/dependency_collector.rs b/packages/transformers/js/core/src/dependency_collector.rs index 8be27903394..6b2c4a34185 100644 --- a/packages/transformers/js/core/src/dependency_collector.rs +++ b/packages/transformers/js/core/src/dependency_collector.rs @@ -10,6 +10,7 @@ use swc_ecmascript::ast; use swc_ecmascript::utils::ident::IdentLike; use swc_ecmascript::visit::{Fold, FoldWith}; +use crate::fold_member_expr_skip_prop; use crate::utils::*; use crate::Config; @@ -780,16 +781,7 @@ impl<'a> Fold for DependencyCollector<'a> { node.fold_children_with(self) } - fn fold_member_expr(&mut self, mut node: ast::MemberExpr) -> ast::MemberExpr { - node.obj = node.obj.fold_children_with(self); - - // To ensure that fold_expr doesn't replace `require` in non-computed member expressions - if node.computed { - node.prop = node.prop.fold_children_with(self); - } - - node - } + fold_member_expr_skip_prop! {} fn fold_expr(&mut self, node: ast::Expr) -> ast::Expr { use ast::*; diff --git a/packages/transformers/js/core/src/modules.rs b/packages/transformers/js/core/src/modules.rs index c64e5baa986..f6aafaf28e4 100644 --- a/packages/transformers/js/core/src/modules.rs +++ b/packages/transformers/js/core/src/modules.rs @@ -6,6 +6,8 @@ use swc_ecma_preset_env::{Feature, Versions}; use swc_ecmascript::ast::*; use swc_ecmascript::visit::{Fold, FoldWith}; +use crate::fold_member_expr_skip_prop; + type IdentId = (JsWord, SyntaxContext); macro_rules! id { ($ident: expr) => { @@ -613,4 +615,6 @@ impl Fold for ESMFold { _ => node.fold_children_with(self), } } + + fold_member_expr_skip_prop! {} } diff --git a/packages/transformers/js/core/src/utils.rs b/packages/transformers/js/core/src/utils.rs index faa481956ec..3f6372a5684 100644 --- a/packages/transformers/js/core/src/utils.rs +++ b/packages/transformers/js/core/src/utils.rs @@ -309,3 +309,22 @@ impl BailoutReason { } } } + +#[macro_export] +macro_rules! fold_member_expr_skip_prop { + () => { + fn fold_member_expr( + &mut self, + mut node: swc_ecmascript::ast::MemberExpr, + ) -> swc_ecmascript::ast::MemberExpr { + node.obj = node.obj.fold_children_with(self); + + // To ensure that fold_expr doesn't replace `require` in non-computed member expressions + if node.computed { + node.prop = node.prop.fold_children_with(self); + } + + node + } + }; +}