fix(es/modules): Preserve order for ts import equals (#5215)

This commit is contained in:
magic-akari 2022-07-16 15:09:06 +08:00 committed by GitHub
parent d693bbbf3a
commit 6b1ce09b6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 136 additions and 61 deletions

View File

@ -93,6 +93,21 @@ where
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) { fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
let import_interop = self.config.import_interop(); let import_interop = self.config.import_interop();
let mut module_map = Default::default();
let mut has_ts_import_equals = false;
// handle `import foo = require("mod")`
n.iter_mut().for_each(|item| {
if let ModuleItem::ModuleDecl(module_decl) = item {
*item = self.handle_ts_import_equals(
module_decl.take(),
&mut module_map,
&mut has_ts_import_equals,
);
}
});
let mut strip = ModuleDeclStrip::new(self.const_var_kind); let mut strip = ModuleDeclStrip::new(self.const_var_kind);
n.visit_mut_with(&mut strip); n.visit_mut_with(&mut strip);
@ -111,20 +126,21 @@ where
.. ..
} = strip; } = strip;
let has_module_decl = has_module_decl || has_ts_import_equals;
let is_export_assign = export_assign.is_some(); let is_export_assign = export_assign.is_some();
if has_module_decl && !import_interop.is_none() && !is_export_assign { if has_module_decl && !import_interop.is_none() && !is_export_assign {
stmts.push(define_es_module(self.exports()).into()) stmts.push(define_es_module(self.exports()).into())
} }
let mut import_map = Default::default();
let mut lazy_record = Default::default(); let mut lazy_record = Default::default();
// `import` -> `require` // `import` -> `require`
// `export` -> `_export(exports, {});` // `export` -> `_export(exports, {});`
stmts.extend( stmts.extend(
self.handle_import_export( self.handle_import_export(
&mut import_map, &mut module_map,
&mut lazy_record, &mut lazy_record,
link, link,
export, export,
@ -157,7 +173,7 @@ where
} }
stmts.visit_mut_children_with(&mut ModuleRefRewriter { stmts.visit_mut_children_with(&mut ModuleRefRewriter {
import_map, import_map: module_map,
lazy_record, lazy_record,
allow_top_level_this: self.config.allow_top_level_this, allow_top_level_this: self.config.allow_top_level_this,
is_global_this: true, is_global_this: true,
@ -268,9 +284,6 @@ where
} }
let mod_ident = private_ident!(local_name_for_src(&src)); let mod_ident = private_ident!(local_name_for_src(&src));
let raw_mod_ident = link_flag
.need_raw_import()
.then(|| private_ident!(local_name_for_src(&src)));
let mut decl_mod_ident = false; let mut decl_mod_ident = false;
@ -278,7 +291,7 @@ where
import_map, import_map,
&mut export_obj_prop_list, &mut export_obj_prop_list,
&mod_ident, &mod_ident,
&raw_mod_ident, &None,
&mut decl_mod_ident, &mut decl_mod_ident,
is_swc_default_helper || is_node_default, is_swc_default_helper || is_node_default,
); );
@ -288,9 +301,6 @@ where
if is_lazy { if is_lazy {
lazy_record.insert(mod_ident.to_id()); lazy_record.insert(mod_ident.to_id());
if let Some(raw_mod_ident) = &raw_mod_ident {
lazy_record.insert(raw_mod_ident.to_id());
}
} }
// require("mod"); // require("mod");
@ -304,21 +314,6 @@ where
import_expr import_expr
}; };
let import_assign = raw_mod_ident.map(|raw_mod_ident| {
let import_expr = import_expr.clone();
if is_lazy {
Stmt::Decl(Decl::Fn(lazy_require(
import_expr,
raw_mod_ident,
self.const_var_kind,
)))
} else {
Stmt::Decl(Decl::Var(
import_expr.into_var_decl(self.const_var_kind, raw_mod_ident.into()),
))
}
});
// _exportStar(require("mod"), exports); // _exportStar(require("mod"), exports);
let import_expr = if link_flag.export_star() { let import_expr = if link_flag.export_star() {
helper_expr!(export_star, "exportStar").as_call( helper_expr!(export_star, "exportStar").as_call(
@ -364,10 +359,6 @@ where
) )
}; };
if let Some(import_assign) = import_assign {
stmts.push(import_assign);
}
stmts.push(stmt); stmts.push(stmt);
} else { } else {
stmts.push(import_expr.into_stmt()); stmts.push(import_expr.into_stmt());
@ -393,6 +384,61 @@ where
export_stmts.into_iter().chain(stmts) export_stmts.into_iter().chain(stmts)
} }
fn handle_ts_import_equals(
&self,
module_decl: ModuleDecl,
module_map: &mut ImportMap,
has_ts_import_equals: &mut bool,
) -> ModuleItem {
if let ModuleDecl::TsImportEquals(TsImportEqualsDecl {
span,
declare: false,
is_export,
is_type_only: false,
id,
module_ref:
TsModuleRef::TsExternalModuleRef(TsExternalModuleRef {
expr:
Str {
span: src_span,
value: src,
..
},
..
}),
}) = module_decl
{
*has_ts_import_equals = true;
let require = self
.resolver
.make_require_call(self.unresolved_mark, src, src_span);
if is_export {
// exports.foo = require("mod")
module_map.insert(id.to_id(), (self.exports(), Some(id.sym.clone())));
let assign_expr = AssignExpr {
span,
op: op!("="),
left: id.as_pat_or_expr(),
right: Box::new(require),
};
assign_expr.into_stmt()
} else {
// const foo = require("mod")
let mut var_decl = require.into_var_decl(self.const_var_kind, id.into());
var_decl.span = span;
Stmt::Decl(var_decl.into())
}
.into()
} else {
module_decl.into()
}
}
fn exports(&self) -> Ident { fn exports(&self) -> Ident {
quote_ident!(DUMMY_SP.apply_mark(self.unresolved_mark), "exports") quote_ident!(DUMMY_SP.apply_mark(self.unresolved_mark), "exports")
} }

View File

@ -1,3 +1,3 @@
"use strict"; "use strict";
const _foo = require("foo"); const foo = require("foo");
module.exports = _foo; module.exports = foo;

View File

@ -2,8 +2,4 @@
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: true value: true
}); });
Object.defineProperty(exports, "foo", { exports.foo = require("foo");
enumerable: true,
get: ()=>_foo
});
const _foo = require("foo");

View File

@ -2,7 +2,7 @@
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: true value: true
}); });
const _foo = require("foo"); const _foo = /*#__PURE__*/ _interopRequireDefault(require("foo"));
const _foo1 = /*#__PURE__*/ _interopRequireDefault(require("foo")); const bar = require("foo");
(0, _foo1.default)(); (0, _foo.default)();
_foo(); bar();

View File

@ -0,0 +1,3 @@
import A = require("a"); // print a
console.log(1);
import B = require("b"); // print b

View File

@ -0,0 +1,13 @@
define([
"require",
"exports",
"a",
"b"
], function(require, exports, _a, _b) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
console.log(1);
});
// print b

View File

@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const A = require("a"); // print a
console.log(1);
const B = require("b"); // print b

View File

@ -0,0 +1,16 @@
(function(global, factory) {
if (typeof module === "object" && typeof module.exports === "object") factory(exports, require("a"), require("b"));
else if (typeof define === "function" && define.amd) define([
"exports",
"a",
"b"
], factory);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global.a, global.b);
})(this, function(exports, _a, _b) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
console.log(1);
});
// print b

View File

@ -2,5 +2,5 @@
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: true value: true
}); });
const _assert = require("assert"); const assert = require("assert");
_assert(true); assert(true);

View File

@ -2,7 +2,7 @@
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: true value: true
}); });
const _assert = require("assert"); const _assert = /*#__PURE__*/ _interopRequireDefault(require("assert"));
const _assert1 = /*#__PURE__*/ _interopRequireDefault(require("assert")); const assert = require("assert");
_assert(true); assert(true);
(0, _assert1.default)(true); (0, _assert.default)(true);

View File

@ -2,15 +2,9 @@
Object.defineProperty(exports, "__esModule", { Object.defineProperty(exports, "__esModule", {
value: true value: true
}); });
function _export(target, all) { Object.defineProperty(exports, "jquery", {
for(var name in all)Object.defineProperty(target, name, { enumerable: true,
enumerable: true, get: ()=>exports["$"]
get: all[name]
});
}
_export(exports, {
"$": ()=>_jquery,
jquery: ()=>_jquery
}); });
const _jquery = require("jquery"); exports["$"] = require("jquery");
_jquery(".hello"); (0, exports["$"])(".hello");

View File

@ -1,5 +1,5 @@
"use strict"; "use strict";
const _foo = require("foo"); const foo = require("foo");
_foo.bar = 1; foo.bar = 1;
_foo.bar = 2; foo.bar = 2;
module.exports = _foo; module.exports = foo;