Repository: swc-project/swc (Rust)

Issue:
Wrong variable used in dynamic import and import
### Describe the bug

with a code like `import(variable)`, SWC will output a code that will crash with `ReferenceError: variable is not defined` when `variable` is imported from another module

### Input code

```typescript
import { foo } from 'bar';

import(foo);
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "jsx": false
    }
  },
  "isModule": true,
  "module": {
    "type": "commonjs"
  }
}
```


### Playground link

https://play.swc.rs/?version=1.2.128&code=H4sIAAAAAAAAA8vMLcgvKlGoVkjLz1eoVUgrys9VUE9KLFK35uLKBMtpAGU0rbkA8UzezSkAAAA%3D&config=H4sIAAAAAAAAAy2KQQrAIAwE%2F7JnX%2BAf%2BgixKShaJYlQkfy9FnramWEXskT4hR5YiD%2BSeWt44EGxBomcusLt205XKEJmDkmOdo5C8MqDHOpvCzr7XsRWa7uzwOwFk8nycWMAAAA%3D

### Expected behavior

When we look at the output of this code:

![image](https://user-images.githubusercontent.com/22725671/149246547-16f753e5-e019-42df-8089-04bbf784519c.png)


We can see that `foo` is transpiled to `_bar.foo`. So I'd expect it to behave the same way here.

### Actual behavior

But when we look at our code sample:

![image](https://user-images.githubusercontent.com/22725671/149246588-34437903-b59d-436d-8a34-a5ce256e0079.png)


We can see that `require(foo)` is used, when `foo` was never injected in the global scope (`_bar.foo` is)

### Version

1.2.128

(but it was also buggy in all versions I checked, and I went back up to the version 1.2.83, but I couldn't go further in the REPL)

### Additional context

It doesn't happen with `require` instead of `import()`:

![image](https://user-images.githubusercontent.com/22725671/149246803-3bbb5011-e5ce-4502-9184-f28491950782.png)

---


Nor with `require` instead of `import from`:

![image](https://user-images.githubusercontent.com/22725671/149247078-626c4204-f3c5-4381-9ed9-439f778c3ba7.png)


---


It crashes too with default import:

![image](https://user-images.githubusercontent.com/22725671/149247025-266ab66e-0eb9-4a3e-9937-5a54335b0d5a.png)


---

But it works with `import *`

![image](https://user-images.githubusercontent.com/22725671/149247052-d2402986-f73f-43b0-8ad7-5b2efe78b6b9.png)




Discussion:
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.



Patch:
diff --git a/crates/swc_ecma_transforms_module/src/util.rs b/crates/swc_ecma_transforms_module/src/util.rs
index 4af62997a7d8..604ee1008bcb 100644
--- a/crates/swc_ecma_transforms_module/src/util.rs
+++ b/crates/swc_ecma_transforms_module/src/util.rs
@@ -506,13 +506,21 @@ impl Scope {
             Expr::Call(CallExpr {
                 span,
                 callee: Callee::Import(_),
-                args,
+                mut args,
                 ..
             }) if !folder.config().ignore_dynamic
                 // TODO: import assertion
                 && args.len() == 1 =>
             {
-                folder.make_dynamic_import(span, args)
+                let expr = match *(args.pop().unwrap().expr) {
+                    Expr::Ident(ident) => match Self::fold_ident(folder, ident) {
+                        Ok(expr) => expr,
+                        Err(ident) => Expr::Ident(ident),
+                    },
+                    expr => expr,
+                };
+
+                folder.make_dynamic_import(span, vec![expr.as_arg()])
             }
 
             Expr::Call(CallExpr {


Test patch:
diff --git a/crates/swc_ecma_transforms_module/tests/common_js.rs b/crates/swc_ecma_transforms_module/tests/common_js.rs
index 58e355c788c0..58e0253db1cb 100644
--- a/crates/swc_ecma_transforms_module/tests/common_js.rs
+++ b/crates/swc_ecma_transforms_module/tests/common_js.rs
@@ -4283,6 +4283,41 @@ test!(
   }
   "
 );
+test!(
+    syntax(),
+    |_| tr(Config {
+        ..Default::default()
+    }),
+    issue_3246_1,
+    "import { foo } from 'bar';
+
+    import(foo);
+    ",
+    r#""use strict";
+    var _bar = require("bar");
+    Promise.resolve().then(function() {
+        return _interopRequireWildcard(require(_bar.foo));
+    });
+    "#
+);
+
+test!(
+    syntax(),
+    |_| tr(Config {
+        ..Default::default()
+    }),
+    issue_3246_2,
+    "import foo from 'bar';
+
+  import(foo);
+  ",
+    r#""use strict";
+  var _bar = _interopRequireDefault(require("bar"));
+  Promise.resolve().then(function() {
+      return _interopRequireWildcard(require(_bar.default));
+  });
+  "#
+);
 
 test!(
     syntax(),