fix(es/modules): Improve compatibility with cjs-module-lexer (#5835)

This commit is contained in:
magic-akari 2022-09-13 15:43:41 +08:00 committed by GitHub
parent cae41739d5
commit bf759819e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 333 additions and 73 deletions

View File

@ -2,7 +2,11 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.y = exports.x = void 0;
0 && (module.exports = {
x: _,
y: _,
default: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -6,7 +6,7 @@ use swc_common::{
use swc_ecma_ast::*;
use swc_ecma_transforms_base::{feature::FeatureFlag, helper_expr};
use swc_ecma_utils::{
member_expr, private_ident, quote_ident, undefined, ExprFactory, FunctionFactory, IsDirective,
member_expr, private_ident, quote_ident, ExprFactory, FunctionFactory, IsDirective,
};
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};
@ -254,11 +254,18 @@ where
is_export_assign: bool,
) -> impl Iterator<Item = Stmt> {
let import_interop = self.config.import_interop();
let is_node = import_interop.is_node();
let mut stmts = Vec::with_capacity(link.len());
let mut export_obj_prop_list = export.into_iter().map(Into::into).collect();
let lexer_reexport = if is_node {
self.emit_lexer_ts_reexport(&link)
} else {
None
};
link.into_iter().for_each(
|(src, LinkItem(src_span, link_specifier_set, mut link_flag))| {
// Optimize for `@swc/helpers`:
@ -277,7 +284,7 @@ where
let is_swc_default_helper =
!link_flag.has_named() && src.starts_with("@swc/helpers/");
let is_node_default = !link_flag.has_named() && import_interop.is_node();
let is_node_default = !link_flag.has_named() && is_node;
if import_interop.is_none() || is_swc_default_helper {
link_flag -= LinkFlag::NAMESPACE;
@ -371,16 +378,24 @@ where
if !export_obj_prop_list.is_empty() && !is_export_assign {
export_obj_prop_list.sort_by_key(|prop| prop.span());
if import_interop.is_node() {
export_stmts = self.emit_lexer_exports_init(&export_obj_prop_list);
}
let features = self.available_features;
let mut features = self.available_features;
let exports = self.exports();
if is_node {
if export_obj_prop_list.len() > 1 {
export_stmts.extend(self.emit_lexer_exports_init(&export_obj_prop_list));
} else {
// `cjs-module-lexer` does not support `get: ()=> foo`
// see https://github.com/nodejs/cjs-module-lexer/pull/74
features -= FeatureFlag::ArrowFunctions;
}
}
export_stmts.extend(emit_export_stmts(features, exports, export_obj_prop_list));
}
export_stmts.extend(lexer_reexport);
export_stmts.into_iter().chain(stmts)
}
@ -445,29 +460,104 @@ where
/// emit [cjs-module-lexer](https://github.com/nodejs/cjs-module-lexer) friendly exports list
/// ```javascript
/// exports.foo = exports.bar = void 0;
/// 0 && (exports.foo = 0);
/// 0 && (module.exports = { foo: _, bar: _ });
/// ```
fn emit_lexer_exports_init(&mut self, export_id_list: &[ObjPropKeyIdent]) -> Vec<Stmt> {
export_id_list
.chunks(100)
.map(|group| {
let mut expr = *undefined(DUMMY_SP);
fn emit_lexer_exports_init(&mut self, export_id_list: &[ObjPropKeyIdent]) -> Option<Stmt> {
match export_id_list.len() {
0 => None,
1 => {
let expr: Expr = 0.into();
for key_value in group {
let prop = prop_name(key_value.key(), DUMMY_SP).into();
let key_value = &export_id_list[0];
let prop = prop_name(key_value.key(), DUMMY_SP).into();
let export_binding = MemberExpr {
obj: Box::new(self.exports().into()),
span: key_value.span(),
prop,
};
let expr = expr.make_assign_to(op!("="), export_binding.as_pat_or_expr());
let expr = BinExpr {
span: DUMMY_SP,
op: op!("&&"),
left: 0.into(),
right: Box::new(expr),
};
let export_binding = MemberExpr {
obj: Box::new(self.exports().into()),
span: key_value.span(),
prop,
};
Some(expr.into_stmt())
}
_ => {
let props = export_id_list
.iter()
.map(|key_value| prop_name(key_value.key(), DUMMY_SP))
.map(|key| KeyValueProp {
key: key.into(),
// `cjs-module-lexer` only support identifier as value
value: quote_ident!("_").into(),
})
.map(Prop::KeyValue)
.map(Box::new)
.map(PropOrSpread::Prop)
.collect();
expr = expr.make_assign_to(op!("="), export_binding.as_pat_or_expr());
let module_exports_assign = ObjectLit {
span: DUMMY_SP,
props,
}
.make_assign_to(
op!("="),
member_expr!(DUMMY_SP.apply_mark(self.unresolved_mark), module.exports).into(),
);
expr.into_stmt()
})
.collect()
let expr = BinExpr {
span: DUMMY_SP,
op: op!("&&"),
left: 0.into(),
right: Box::new(module_exports_assign),
};
Some(expr.into_stmt())
}
}
}
/// emit [cjs-module-lexer](https://github.com/nodejs/cjs-module-lexer) friendly exports list
/// ```javascript
/// 0 && (__export(require("foo")));
/// ```
fn emit_lexer_ts_reexport(&self, link: &Link) -> Option<Stmt> {
let mut seq_list = vec![];
link.iter().for_each(|(src, LinkItem(_, _, link_flag))| {
if link_flag.export_star() {
let import_expr =
self.resolver
.make_require_call(self.unresolved_mark, src.clone(), DUMMY_SP);
let export = Expr::Ident(quote_ident!("__export"))
.as_call(DUMMY_SP, vec![import_expr.as_arg()]);
seq_list.push(Box::new(export));
}
});
if seq_list.is_empty() {
None
} else {
let seq_expr = SeqExpr {
span: DUMMY_SP,
exprs: seq_list,
}
.into();
let expr = BinExpr {
span: DUMMY_SP,
op: op!("&&"),
left: 0.into(),
right: seq_expr,
};
Some(expr.into_stmt())
}
}
fn pure_span(&self) -> Span {

View File

@ -5,10 +5,12 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
0 && __export(require("react"));
const _react = _exportStar(require("react"), exports);
const _default = _react;

View File

@ -2,10 +2,11 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
const _default = function() {
return "foo";

View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Cachier = exports.default = void 0;
0 && (module.exports = {
default: _,
Cachier: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
const _default = {};

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
const _default = [];

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
const _default = foo;

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
function _default() {}

View File

@ -2,10 +2,11 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
class _default {
}

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>foo
get () {
return foo;
}
});
function foo() {}

View File

@ -2,10 +2,11 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>Foo
get () {
return Foo;
}
});
class Foo {
}

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>foo
get () {
return foo;
}
});
var foo;

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_default
get () {
return _default;
}
});
const _default = 42;

View File

@ -2,7 +2,14 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.f4 = exports.f3 = exports.f2 = exports.f1 = exports.y = exports.x = void 0;
0 && (module.exports = {
x: _,
y: _,
f1: _,
f2: _,
f3: _,
f4: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,4 +2,5 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && __export(require("foo"));
_exportStar(require("foo"), exports);

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo = void 0;
Object.defineProperty(exports, "foo", {
enumerable: true,
get: ()=>_foo.foo
get () {
return _foo.foo;
}
});
const _foo = require("foo");

View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo = exports.bar = void 0;
0 && (module.exports = {
bar: _,
foo: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.bar = void 0;
Object.defineProperty(exports, "bar", {
enumerable: true,
get: ()=>_foo.foo
get () {
return _foo.foo;
}
});
const _foo = require("foo");

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>_foo.foo
get () {
return _foo.foo;
}
});
const _foo = require("foo");

View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.bar = void 0;
0 && (module.exports = {
bar: _,
default: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo = void 0;
Object.defineProperty(exports, "foo", {
enumerable: true,
get: ()=>_foo.default
get () {
return _foo.default;
}
});
const _foo = require("foo");

View File

@ -2,8 +2,109 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo98 = exports.foo97 = exports.foo96 = exports.foo95 = exports.foo94 = exports.foo93 = exports.foo92 = exports.foo91 = exports.foo90 = exports.foo9 = exports.foo89 = exports.foo88 = exports.foo87 = exports.foo86 = exports.foo85 = exports.foo84 = exports.foo83 = exports.foo82 = exports.foo81 = exports.foo80 = exports.foo8 = exports.foo79 = exports.foo78 = exports.foo77 = exports.foo76 = exports.foo75 = exports.foo74 = exports.foo73 = exports.foo72 = exports.foo71 = exports.foo70 = exports.foo7 = exports.foo69 = exports.foo68 = exports.foo67 = exports.foo66 = exports.foo65 = exports.foo64 = exports.foo63 = exports.foo62 = exports.foo61 = exports.foo60 = exports.foo6 = exports.foo59 = exports.foo58 = exports.foo57 = exports.foo56 = exports.foo55 = exports.foo54 = exports.foo53 = exports.foo52 = exports.foo51 = exports.foo50 = exports.foo5 = exports.foo49 = exports.foo48 = exports.foo47 = exports.foo46 = exports.foo45 = exports.foo44 = exports.foo43 = exports.foo42 = exports.foo41 = exports.foo40 = exports.foo4 = exports.foo39 = exports.foo38 = exports.foo37 = exports.foo36 = exports.foo35 = exports.foo34 = exports.foo33 = exports.foo32 = exports.foo31 = exports.foo30 = exports.foo3 = exports.foo29 = exports.foo28 = exports.foo27 = exports.foo26 = exports.foo25 = exports.foo24 = exports.foo23 = exports.foo22 = exports.foo21 = exports.foo20 = exports.foo2 = exports.foo19 = exports.foo18 = exports.foo17 = exports.foo16 = exports.foo15 = exports.foo14 = exports.foo13 = exports.foo12 = exports.foo11 = exports.foo100 = exports.foo10 = exports.foo1 = exports.foo = void 0;
exports.foo99 = void 0;
0 && (module.exports = {
foo: _,
foo1: _,
foo10: _,
foo100: _,
foo11: _,
foo12: _,
foo13: _,
foo14: _,
foo15: _,
foo16: _,
foo17: _,
foo18: _,
foo19: _,
foo2: _,
foo20: _,
foo21: _,
foo22: _,
foo23: _,
foo24: _,
foo25: _,
foo26: _,
foo27: _,
foo28: _,
foo29: _,
foo3: _,
foo30: _,
foo31: _,
foo32: _,
foo33: _,
foo34: _,
foo35: _,
foo36: _,
foo37: _,
foo38: _,
foo39: _,
foo4: _,
foo40: _,
foo41: _,
foo42: _,
foo43: _,
foo44: _,
foo45: _,
foo46: _,
foo47: _,
foo48: _,
foo49: _,
foo5: _,
foo50: _,
foo51: _,
foo52: _,
foo53: _,
foo54: _,
foo55: _,
foo56: _,
foo57: _,
foo58: _,
foo59: _,
foo6: _,
foo60: _,
foo61: _,
foo62: _,
foo63: _,
foo64: _,
foo65: _,
foo66: _,
foo67: _,
foo68: _,
foo69: _,
foo7: _,
foo70: _,
foo71: _,
foo72: _,
foo73: _,
foo74: _,
foo75: _,
foo76: _,
foo77: _,
foo78: _,
foo79: _,
foo8: _,
foo80: _,
foo81: _,
foo82: _,
foo83: _,
foo84: _,
foo85: _,
foo86: _,
foo87: _,
foo88: _,
foo89: _,
foo9: _,
foo90: _,
foo91: _,
foo92: _,
foo93: _,
foo94: _,
foo95: _,
foo96: _,
foo97: _,
foo98: _,
foo99: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo = void 0;
Object.defineProperty(exports, "foo", {
enumerable: true,
get: ()=>foo
get () {
return foo;
}
});
var foo;

View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo = exports.bar = void 0;
0 && (module.exports = {
bar: _,
foo: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.bar = void 0;
Object.defineProperty(exports, "bar", {
enumerable: true,
get: ()=>foo
get () {
return foo;
}
});
var foo;

View File

@ -2,9 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
Object.defineProperty(exports, "default", {
enumerable: true,
get: ()=>foo
get () {
return foo;
}
});
var foo;

View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.bar = void 0;
0 && (module.exports = {
bar: _,
default: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,7 +2,18 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo9 = exports.foo8 = exports.foo7 = exports.foo6 = exports.foo5 = exports.foo4 = exports.foo3 = exports.bar = exports.foo2 = exports.foo = void 0;
0 && (module.exports = {
foo: _,
foo2: _,
bar: _,
foo3: _,
foo4: _,
foo5: _,
foo6: _,
foo7: _,
foo8: _,
foo9: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isOdd = exports.nextOdd = void 0;
0 && (module.exports = {
nextOdd: _,
isOdd: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.test2 = exports.test = void 0;
0 && (module.exports = {
test: _,
test2: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,

View File

@ -2,7 +2,13 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.f = exports.e = exports.c = exports.a = exports.test = void 0;
0 && (module.exports = {
test: _,
a: _,
c: _,
e: _,
f: _
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,