Repository: swc-project/swc (rust)

Issue:
Existing order of generated requires/defines can be problematic for inter-dependency relationships
<!--
If you are using swc at work, please considering adding your company to https://swc.rs/users/
If then, your issue will be fixed more quickly.
-->

**Describe the bug**

When importing from multiple modules, the current version of `swc` generates all of its `require` statements up front, followed by all of its `Object.defineProperty()` calls later.  You'll notice that `babel` does these one at a time, and this is important under certain conditions.  Consider the following input code:

**Input code**

```
export * from "./A";
export * from "./B";
```

The compiled commonjs results in:

```
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
var _exportNames = {
};
var _a = _interopRequireWildcard(require("./A")); // <- all of the requires first
var _b = _interopRequireWildcard(require("./B")); // <- all of the requires first
function _interopRequireWildcard(obj) {
    if (obj && obj.__esModule) {
        return obj;
    } else {
        var newObj = {
        };
        if (obj != null) {
            for(var key in obj){
                if (Object.prototype.hasOwnProperty.call(obj, key)) {
                    var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {
                    };
                    if (desc.get || desc.set) {
                        Object.defineProperty(newObj, key, desc);
                    } else {
                        newObj[key] = obj[key];
                    }
                }
            }
        }
        newObj.default = obj;
        return newObj;
    }
}
Object.keys(_a).forEach(function(key) {
    if (key === "default" || key === "__esModule") return;
    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
    if (key in exports && exports[key] === _a[key]) return;
    Object.defineProperty(exports, key, { // <- finally, our defineProperty calls
        enumerable: true,
        get: function() {
            return _a[key];
        }
    });
});
Object.keys(_b).forEach(function(key) {
    if (key === "default" || key === "__esModule") return;
    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
    if (key in exports && exports[key] === _b[key]) return;
    Object.defineProperty(exports, key, {. // <- finally, our defineProperty calls
        enumerable: true,
        get: function() {
            return _b[key];
        }
    });
});
```

`babel` produces a pattern that "interweaves" them (`require, defineProperty, require, defineProperty`):

```
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _A = require("./A");

Object.keys(_A).forEach(function (key) {
  if (key === "default" || key === "__esModule") return;
  if (key in exports && exports[key] === _A[key]) return;
  Object.defineProperty(exports, key, {
    enumerable: true,
    get: function get() {
      return _A[key];
    }
  });
});

var _B = require("./B");

Object.keys(_B).forEach(function (key) {
  if (key === "default" || key === "__esModule") return;
  if (key in exports && exports[key] === _B[key]) return;
  Object.defineProperty(exports, key, {
    enumerable: true,
    get: function get() {
      return _B[key];
    }
  });
});
```

**Config**

```json
{
    "test": ".*.js$",
    "module": {
      "type": "commonjs"
    },
    "jsc": {
      "parser": {
        "syntax": "ecmascript",
        "jsx": true
      },
      "transform": {
          "react": {
              "runtime": "automatic"
          }
      },
      "loose": true
    }
  },
```

**Expected behavior**
Everything will compile, and quite often, bundlers such as `webpack` will get the resolutions correctly.  However, I've found `jest` for example, when importing the above example, may encounter a class from `B` that depends on `A`.  This breaks, because `A` hasn't been defined yet because the `defineProperty` hasn't been declared yet, resulting in a class construction with an `undefined` value for `A`.

By taking the `swc` output, and simply moving the requires around, everything runs just fine.

**Version**
The version of @swc/core:

```
@swc/cli: 0.1.51
@swc/core: 1.2.105
```

**Additional context**
Add any other context about the problem here.


Pull request:
fix(es/transforms/cjs): Preserve order of imports for reexports
- closes #2594.

This PR attempts to order of the imports / reexports in transpiled runtime codebase. #2594 itself sufficiently explains the issue itself. It could be an implementation detail but so far based on observation tsc / babel works in the same way, which makes think it'd better to align as well. As issue described normally this won't appear but if there's some sort of circular dependencies, or reexports have dependencies across each other it may reveal different behavior.

For the change itself, PR changes the order of injecting handled export_all stmt by putting it after require stmt is created. In result, export_all stmt doesn't use extra_stmt (which appends to stmt at the end). Also changed `exports_alls` to map to stmt itself - when encountering ExportAll stmt it is gauranteed we'll need stmt anyway - hashmap contains generated stmt instead of only keeping name of export. This allowed easier lookup at the end.

Lastly, I noticed there is prior test cases from https://github.com/swc-project/swc/pull/133/ (https://github.com/swc-project/swc/pull/133/files#diff-6d08f604fc5444313bf8d80ca76a84f5abbc95129eb4e1311592637fbb17b089R1075) , looks like it is coming from original transform impl. Test cases are updated without adding new one.

Patch:
diff --git a/ecmascript/transforms/module/src/amd.rs b/ecmascript/transforms/module/src/amd.rs
index a9ddd8ff35..cc36744727 100644
--- a/ecmascript/transforms/module/src/amd.rs
+++ b/ecmascript/transforms/module/src/amd.rs
@@ -516,7 +516,10 @@ where
         };
 
         for export in export_alls {
-            stmts.push(scope.handle_export_all(
+            let export = scope
+                .import_to_export(&export.src, true)
+                .expect("Export should exists");
+            stmts.push(Scope::handle_export_all(
                 exports_ident.clone(),
                 exported_names.clone(),
                 export,
diff --git a/ecmascript/transforms/module/src/common_js.rs b/ecmascript/transforms/module/src/common_js.rs
index ef61117d98..88b100ab8c 100644
--- a/ecmascript/transforms/module/src/common_js.rs
+++ b/ecmascript/transforms/module/src/common_js.rs
@@ -9,8 +9,8 @@ use std::{
     cell::{Ref, RefCell, RefMut},
     rc::Rc,
 };
-use swc_atoms::js_word;
-use swc_common::{FileName, Mark, Span, DUMMY_SP};
+use swc_atoms::{js_word, JsWord};
+use swc_common::{collections::AHashMap, FileName, Mark, Span, DUMMY_SP};
 use swc_ecma_ast::*;
 use swc_ecma_transforms_base::helper;
 use swc_ecma_utils::{
@@ -84,7 +84,10 @@ where
 
         let mut exports = vec![];
         let mut initialized = IndexSet::default();
-        let mut export_alls = vec![];
+
+        let mut export_alls: AHashMap<JsWord, Ident> = Default::default();
+        // Used only if export * exists
+        let mut exported_names: Option<Ident> = None;
 
         for item in items {
             self.in_top_level = true;
@@ -174,6 +177,7 @@ where
                     }
                     drop(scope);
                     drop(scope_ref_mut);
+
                     match item {
                         ModuleItem::ModuleDecl(ModuleDecl::ExportAll(export)) => {
                             self.scope
@@ -181,7 +185,61 @@ where
                                 .lazy_blacklist
                                 .insert(export.src.value.clone());
 
-                            export_alls.push(export);
+                            let mut scope_ref_mut = self.scope.borrow_mut();
+                            let scope = &mut *scope_ref_mut;
+
+                            if exported_names.is_none()
+                                && (export_alls.len() >= 1 || !exports.is_empty())
+                            {
+                                let exported_names_ident = private_ident!("_exportNames");
+                                stmts.push(ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl {
+                                    span: DUMMY_SP,
+                                    kind: VarDeclKind::Var,
+                                    decls: vec![VarDeclarator {
+                                        span: DUMMY_SP,
+                                        name: Pat::Ident(exported_names_ident.clone().into()),
+                                        init: Some(Box::new(Expr::Object(ObjectLit {
+                                            span: DUMMY_SP,
+                                            props: exports
+                                                .clone()
+                                                .into_iter()
+                                                .filter_map(|export| {
+                                                    if export == js_word!("default") {
+                                                        return None;
+                                                    }
+
+                                                    Some(PropOrSpread::Prop(Box::new(
+                                                        Prop::KeyValue(KeyValueProp {
+                                                            key: PropName::Ident(Ident::new(
+                                                                export, DUMMY_SP,
+                                                            )),
+                                                            value: Box::new(Expr::Lit(Lit::Bool(
+                                                                Bool {
+                                                                    span: DUMMY_SP,
+                                                                    value: true,
+                                                                },
+                                                            ))),
+                                                        }),
+                                                    )))
+                                                })
+                                                .collect(),
+                                        }))),
+                                        definite: false,
+                                    }],
+                                    declare: false,
+                                }))));
+
+                                exported_names = Some(exported_names_ident);
+                            }
+
+                            export_alls.entry(export.src.value.clone()).or_insert(
+                                scope
+                                    .import_to_export(&export.src, true)
+                                    .expect("Export should exists"),
+                            );
+
+                            drop(scope);
+                            drop(scope_ref_mut);
                         }
                         ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
                             decl: decl @ Decl::Class(..),
@@ -521,61 +579,8 @@ where
             }
         }
 
-        let has_export = !exports.is_empty();
-
         let mut scope_ref_mut = self.scope.borrow_mut();
         let scope = &mut *scope_ref_mut;
-        // Used only if export * exists
-        let exported_names = {
-            if (!export_alls.is_empty() && has_export) || export_alls.len() >= 2 {
-                let exported_names = private_ident!("_exportNames");
-                stmts.push(ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl {
-                    span: DUMMY_SP,
-                    kind: VarDeclKind::Var,
-                    decls: vec![VarDeclarator {
-                        span: DUMMY_SP,
-                        name: Pat::Ident(exported_names.clone().into()),
-                        init: Some(Box::new(Expr::Object(ObjectLit {
-                            span: DUMMY_SP,
-                            props: exports
-                                .into_iter()
-                                .filter_map(|export| {
-                                    if export == js_word!("default") {
-                                        return None;
-                                    }
-
-                                    Some(PropOrSpread::Prop(Box::new(Prop::KeyValue(
-                                        KeyValueProp {
-                                            key: PropName::Ident(Ident::new(export, DUMMY_SP)),
-                                            value: Box::new(Expr::Lit(Lit::Bool(Bool {
-                                                span: DUMMY_SP,
-                                                value: true,
-                                            }))),
-                                        },
-                                    ))))
-                                })
-                                .collect(),
-                        }))),
-                        definite: false,
-                    }],
-                    declare: false,
-                }))));
-
-                Some(exported_names)
-            } else {
-                None
-            }
-        };
-
-        for export in export_alls {
-            // We use extra_stmts because it should be placed *after* import
-            // statements.
-            extra_stmts.push(ModuleItem::Stmt(scope.handle_export_all(
-                quote_ident!("exports"),
-                exported_names.clone(),
-                export,
-            )));
-        }
 
         if !initialized.is_empty() {
             stmts.push(
@@ -699,6 +704,15 @@ where
                     stmts.push(require.into_stmt().into());
                 }
             }
+
+            let exported = export_alls.remove(&src);
+            if let Some(export) = exported {
+                stmts.push(ModuleItem::Stmt(Scope::handle_export_all(
+                    quote_ident!("exports"),
+                    exported_names.clone(),
+                    export,
+                )));
+            }
         }
 
         stmts.append(&mut extra_stmts);
diff --git a/ecmascript/transforms/module/src/umd.rs b/ecmascript/transforms/module/src/umd.rs
index fc0ea94263..902681eb82 100644
--- a/ecmascript/transforms/module/src/umd.rs
+++ b/ecmascript/transforms/module/src/umd.rs
@@ -525,7 +525,10 @@ where
         };
 
         for export in export_alls {
-            stmts.push(scope.handle_export_all(
+            let export = scope
+                .import_to_export(&export.src, true)
+                .expect("Export should exists");
+            stmts.push(Scope::handle_export_all(
                 exports_ident.clone(),
                 exported_names.clone(),
                 export,
diff --git a/ecmascript/transforms/module/src/util.rs b/ecmascript/transforms/module/src/util.rs
index b838562f94..aa3170edb3 100644
--- a/ecmascript/transforms/module/src/util.rs
+++ b/ecmascript/transforms/module/src/util.rs
@@ -155,13 +155,10 @@ impl Scope {
     /// # Parameters
     /// - `exported_names` Ident of the object literal.
     pub fn handle_export_all(
-        &mut self,
         exports: Ident,
         exported_names: Option<Ident>,
-        export: ExportAll,
+        imported: Ident,
     ) -> Stmt {
-        let imported = self.import_to_export(&export.src, true).unwrap();
-
         let key_ident = private_ident!("key");
 
         let function = Function {


Test patch:
diff --git a/ecmascript/transforms/module/tests/common_js.rs b/ecmascript/transforms/module/tests/common_js.rs
index 0fe24849c7..b6bb92ef7d 100644
--- a/ecmascript/transforms/module/tests/common_js.rs
+++ b/ecmascript/transforms/module/tests/common_js.rs
@@ -1251,7 +1251,6 @@ var _exportNames = {
 };
 
 var _white = require("white");
-var _black = require("black");
 
 Object.keys(_white).forEach(function (key) {
   if (key === "default" || key === "__esModule") return;
@@ -1265,6 +1264,8 @@ Object.keys(_white).forEach(function (key) {
   });
 });
 
+var _black = require("black");
+
 Object.keys(_black).forEach(function (key) {
   if (key === "default" || key === "__esModule") return;
   if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -3785,18 +3786,12 @@ export * from 'react';
 Object.defineProperty(exports, "__esModule", {
   value: true
 });
-var _exportNames = {};
+var _exportNames = {
+};
 
 exports.default = void 0;
 var _react = _interopRequireWildcard(require("react"));
 
-
-// The fact that this exports both a normal default, and all of the names via
-// re-export is an edge case that is important not to miss. See
-// https://github.com/babel/babel/issues/8306 as an example.
-var _default = _react.default;
-exports.default = _default;
-
 Object.keys(_react).forEach(function (key) {
   if (key === "default" || key === "__esModule") return;
   if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -3809,6 +3804,12 @@ Object.keys(_react).forEach(function (key) {
   });
 });
 
+// The fact that this exports both a normal default, and all of the names via
+// re-export is an edge case that is important not to miss. See
+// https://github.com/babel/babel/issues/8306 as an example.
+var _default = _react.default;
+exports.default = _default;
+
 "#
 );
 
@@ -4093,19 +4094,19 @@ test!(
     issue_962,
     "import root from './_root.js';
   import stubFalse from './stubFalse.js';
-    
+
   var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
   var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && \
      module;
-    
+
   var moduleExports = freeModule && freeModule.exports === freeExports;
-    
+
   var Buffer = moduleExports ? root.Buffer : undefined;
-    
+
   var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
-    
+
   var isBuffer = nativeIsBuffer || stubFalse;
-    
+
   export default isBuffer",
     r#"
     "use strict";
@@ -4166,14 +4167,9 @@ Object.defineProperty(exports, "Scope", {
       return _interfaces.Scope;
   }
 });
-var _exportNames = {
-    Scope: true
-};
 var _http = require("./http");
-var _interfaces = require("./interfaces");
 Object.keys(_http).forEach(function(key) {
     if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
     if (key in exports && exports[key] === _http[key]) return;
     Object.defineProperty(exports, key, {
         enumerable: true,
@@ -4182,6 +4178,7 @@ Object.keys(_http).forEach(function(key) {
         }
     });
 });
+var _interfaces = require("./interfaces");
   "#
 );
 
@@ -4214,8 +4211,6 @@ export * from './pipes';
     };
     require("reflect-metadata");
     var _http = require("./http");
-    var _interfaces = require("./interfaces");
-    var _pipes = require("./pipes");
     Object.keys(_http).forEach(function(key) {
         if (key === "default" || key === "__esModule") return;
         if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -4227,6 +4222,8 @@ export * from './pipes';
             }
         });
     });
+    var _interfaces = require("./interfaces");
+    var _pipes = require("./pipes");
     Object.keys(_pipes).forEach(function(key) {
         if (key === "default" || key === "__esModule") return;
         if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -4544,7 +4541,7 @@ test!(
         console.log(foo);
       }
     }
-    
+
     export default class NotOK {
       constructor() {
         console.log(foo);
@@ -4557,9 +4554,9 @@ test!(
       value: true
     });
     exports.default = void 0;
-    
+
     var _foo = _interopRequireDefault(require('foo'));
-    
+
     class OK {
         constructor() {
             console.log(_foo.default);
@@ -4685,11 +4682,11 @@ test!(
     });
     exports.get = get;
     exports.default = void 0;
-    
+
     function get(key) {
       console.log(key);
     }
-    
+
     var _default = a;
     exports.default = _default;
     "
@@ -4756,20 +4753,18 @@ test!(
     };
     exports.BIZ = void 0;
     var _file1 = require('./File1');
-    var _file2 = require('./File2');
-    const BIZ = 'biz';
-    exports.BIZ = BIZ;
     Object.keys(_file1).forEach(function(key) {
-        if (key === 'default' || key === '__esModule') return;
-        if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-        if (key in exports && exports[key] === _file1[key]) return;
-        Object.defineProperty(exports, key, {
-            enumerable: true,
-            get: function() {
-                return _file1[key];
-            }
-        });
+      if (key === 'default' || key === '__esModule') return;
+      if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+      if (key in exports && exports[key] === _file1[key]) return;
+      Object.defineProperty(exports, key, {
+          enumerable: true,
+          get: function() {
+              return _file1[key];
+          }
+      });
     });
+    var _file2 = require('./File2');
     Object.keys(_file2).forEach(function(key) {
         if (key === 'default' || key === '__esModule') return;
         if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
@@ -4781,6 +4776,8 @@ test!(
             }
         });
     });
+    const BIZ = 'biz';
+    exports.BIZ = BIZ;
     "
 );
 
@@ -4922,7 +4919,7 @@ test!(
     ignore_dynamic_1,
     "
     import foo from 'foo';
-    
+
 
     function foo() {
       await import('foo');
diff --git a/tests/fixture/issue-1714/case1/output/index.js b/tests/fixture/issue-1714/case1/output/index.js
index 144713b86e..b6625cc9bd 100644
--- a/tests/fixture/issue-1714/case1/output/index.js
+++ b/tests/fixture/issue-1714/case1/output/index.js
@@ -10,6 +10,16 @@ Object.defineProperty(exports, "render", {
 });
 var _customRender = require("./customRender");
 var _react = _interopRequireWildcard(require("@testing-library/react"));
+Object.keys(_react).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (key in exports && exports[key] === _react[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _react[key];
+        }
+    });
+});
 function _interopRequireWildcard(obj) {
     if (obj && obj.__esModule) {
         return obj;
@@ -33,13 +43,3 @@ function _interopRequireWildcard(obj) {
         return newObj;
     }
 }
-Object.keys(_react).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (key in exports && exports[key] === _react[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _react[key];
-        }
-    });
-});
diff --git a/tests/fixture/issue-1859/case1-js/output/index.js b/tests/fixture/issue-1859/case1-js/output/index.js
index b05ec7f65b..2fd4e8cd95 100644
--- a/tests/fixture/issue-1859/case1-js/output/index.js
+++ b/tests/fixture/issue-1859/case1-js/output/index.js
@@ -5,7 +5,29 @@ Object.defineProperty(exports, "__esModule", {
 var _exportNames = {
 };
 var _appConfig = _interopRequireWildcard(require("./app.config"));
+Object.keys(_appConfig).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _appConfig[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _appConfig[key];
+        }
+    });
+});
 var _databaseConfig = _interopRequireWildcard(require("./database.config"));
+Object.keys(_databaseConfig).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _databaseConfig[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _databaseConfig[key];
+        }
+    });
+});
 function _interopRequireWildcard(obj) {
     if (obj && obj.__esModule) {
         return obj;
@@ -29,25 +51,3 @@ function _interopRequireWildcard(obj) {
         return newObj;
     }
 }
-Object.keys(_appConfig).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _appConfig[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _appConfig[key];
-        }
-    });
-});
-Object.keys(_databaseConfig).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _databaseConfig[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _databaseConfig[key];
-        }
-    });
-});
diff --git a/tests/fixture/issue-1859/case2-ts/output/index.ts b/tests/fixture/issue-1859/case2-ts/output/index.ts
index b05ec7f65b..2fd4e8cd95 100644
--- a/tests/fixture/issue-1859/case2-ts/output/index.ts
+++ b/tests/fixture/issue-1859/case2-ts/output/index.ts
@@ -5,7 +5,29 @@ Object.defineProperty(exports, "__esModule", {
 var _exportNames = {
 };
 var _appConfig = _interopRequireWildcard(require("./app.config"));
+Object.keys(_appConfig).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _appConfig[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _appConfig[key];
+        }
+    });
+});
 var _databaseConfig = _interopRequireWildcard(require("./database.config"));
+Object.keys(_databaseConfig).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _databaseConfig[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _databaseConfig[key];
+        }
+    });
+});
 function _interopRequireWildcard(obj) {
     if (obj && obj.__esModule) {
         return obj;
@@ -29,25 +51,3 @@ function _interopRequireWildcard(obj) {
         return newObj;
     }
 }
-Object.keys(_appConfig).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _appConfig[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _appConfig[key];
-        }
-    });
-});
-Object.keys(_databaseConfig).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _databaseConfig[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _databaseConfig[key];
-        }
-    });
-});
diff --git a/tests/fixture/issue-1859/case3/output/lib.ts b/tests/fixture/issue-1859/case3/output/lib.ts
index 9a9127514a..883a088634 100644
--- a/tests/fixture/issue-1859/case3/output/lib.ts
+++ b/tests/fixture/issue-1859/case3/output/lib.ts
@@ -5,7 +5,29 @@ Object.defineProperty(exports, "__esModule", {
 var _exportNames = {
 };
 var _foo = _interopRequireWildcard(require("./foo"));
+Object.keys(_foo).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _foo[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _foo[key];
+        }
+    });
+});
 var _bar = _interopRequireWildcard(require("./bar"));
+Object.keys(_bar).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _bar[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _bar[key];
+        }
+    });
+});
 function _interopRequireWildcard(obj) {
     if (obj && obj.__esModule) {
         return obj;
@@ -29,25 +51,3 @@ function _interopRequireWildcard(obj) {
         return newObj;
     }
 }
-Object.keys(_foo).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _foo[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _foo[key];
-        }
-    });
-});
-Object.keys(_bar).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _bar[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _bar[key];
-        }
-    });
-});
diff --git a/tests/fixture/issue-2548/case2/output/index.js b/tests/fixture/issue-2548/case2/output/index.js
index 744f3f90fe..ef469be6d9 100644
--- a/tests/fixture/issue-2548/case2/output/index.js
+++ b/tests/fixture/issue-2548/case2/output/index.js
@@ -12,6 +12,17 @@ var _exportNames = {
     X: true
 };
 var _z = _interopRequireWildcard(require("./Z"));
+Object.keys(_z).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _z[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _z[key];
+        }
+    });
+});
 function _interopRequireWildcard(obj) {
     if (obj && obj.__esModule) {
         return obj;
@@ -35,14 +46,3 @@ function _interopRequireWildcard(obj) {
         return newObj;
     }
 }
-Object.keys(_z).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _z[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _z[key];
-        }
-    });
-});
diff --git a/tests/fixture/issue-2548/case3/output/index.js b/tests/fixture/issue-2548/case3/output/index.js
index f7aba41fae..ad4ab29c5a 100644
--- a/tests/fixture/issue-2548/case3/output/index.js
+++ b/tests/fixture/issue-2548/case3/output/index.js
@@ -26,6 +26,17 @@ var _exportNames = {
     X2: true
 };
 var _z = _interopRequireWildcard(require("./Z"));
+Object.keys(_z).forEach(function(key) {
+    if (key === "default" || key === "__esModule") return;
+    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+    if (key in exports && exports[key] === _z[key]) return;
+    Object.defineProperty(exports, key, {
+        enumerable: true,
+        get: function() {
+            return _z[key];
+        }
+    });
+});
 function _interopRequireWildcard(obj) {
     if (obj && obj.__esModule) {
         return obj;
@@ -49,14 +60,3 @@ function _interopRequireWildcard(obj) {
         return newObj;
     }
 }
-Object.keys(_z).forEach(function(key) {
-    if (key === "default" || key === "__esModule") return;
-    if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
-    if (key in exports && exports[key] === _z[key]) return;
-    Object.defineProperty(exports, key, {
-        enumerable: true,
-        get: function() {
-            return _z[key];
-        }
-    });
-});