Skip to content

Commit

Permalink
feat(es/module): Add export_interop_annotation flag (#7330)
Browse files Browse the repository at this point in the history
**Related issue:**

 - vercel/next.js#48801
  • Loading branch information
magic-akari authored Apr 25, 2023
1 parent c77f175 commit caee073
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 4 deletions.
8 changes: 8 additions & 0 deletions bindings/binding_core_wasm/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,14 @@ export interface BaseModuleConfig {
* ```
*/
importInterop?: "swc" | "babel" | "node" | "none";
/**
* Emits `cjs-module-lexer` annotation
* `cjs-module-lexer` is used in Node.js core for detecting the named exports available when importing a CJS module into ESM.
* swc will emit `cjs-module-lexer` detectable annotation with this option enabled.
*
* Defaults to `true` if import_interop is Node, else `false`
*/
exportInteropAnnotation?: boolean;
/**
* If set to true, dynamic imports will be preserved.
*/
Expand Down
9 changes: 5 additions & 4 deletions crates/swc_ecma_transforms_module/src/common_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,15 @@ where
is_export_assign: bool,
) -> impl Iterator<Item = Stmt> {
let import_interop = self.config.import_interop();
let export_interop_annotation = self.config.export_interop_annotation();
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(From::from).collect();

let lexer_reexport = if is_node {
self.emit_lexer_ts_reexport(&link)
let lexer_reexport = if export_interop_annotation {
self.emit_lexer_reexport(&link)
} else {
None
};
Expand Down Expand Up @@ -355,7 +356,7 @@ where
let mut features = self.available_features;
let exports = self.exports();

if is_node {
if export_interop_annotation {
if export_obj_prop_list.len() > 1 {
export_stmts.extend(self.emit_lexer_exports_init(&export_obj_prop_list));
} else {
Expand Down Expand Up @@ -507,7 +508,7 @@ where
/// ```javascript
/// 0 && __export(require("foo")) && __export(require("bar"));
/// ```
fn emit_lexer_ts_reexport(&self, link: &Link) -> Option<Stmt> {
fn emit_lexer_reexport(&self, link: &Link) -> Option<Stmt> {
link.iter()
.filter(|(.., LinkItem(.., link_flag))| link_flag.export_star())
.map(|(src, ..)| {
Expand Down
16 changes: 16 additions & 0 deletions crates/swc_ecma_transforms_module/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ pub struct Config {
pub lazy: Lazy,
#[serde(default)]
pub import_interop: Option<ImportInterop>,
/// Emits `cjs-module-lexer` annotation
/// `cjs-module-lexer` is used in Node.js core for detecting the named
/// exports available when importing a CJS module into ESM.
/// swc will emit `cjs-module-lexer` detectable annotation with this option
/// enabled.
///
/// Defaults to `true` if import_interop is Node, else `false`
#[serde(default)]
pub export_interop_annotation: Option<bool>,
#[serde(default)]
/// Note: deprecated
pub no_interop: bool,
Expand All @@ -39,6 +48,7 @@ impl Default for Config {
strict_mode: default_strict_mode(),
lazy: Lazy::default(),
import_interop: None,
export_interop_annotation: None,
no_interop: false,
ignore_dynamic: false,
preserve_import_meta: false,
Expand Down Expand Up @@ -75,6 +85,12 @@ impl Config {
self.import_interop
.unwrap_or_else(|| self.no_interop.into())
}

#[inline(always)]
pub fn export_interop_annotation(&self) -> bool {
self.export_interop_annotation
.unwrap_or_else(|| self.import_interop == Some(ImportInterop::Node))
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function useRouter() {}

export default useRouter;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"importInterop": "swc",
"exportInteropAnnotation": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
define([
"require",
"exports"
], function(require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
useRouter: function() {
return useRouter;
},
default: function() {
return _default;
}
});
function useRouter() {}
const _default = useRouter;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
useRouter: null,
default: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
useRouter: function() {
return useRouter;
},
default: function() {
return _default;
}
});
function useRouter() {}
const _default = useRouter;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(function(global, factory) {
if (typeof module === "object" && typeof module.exports === "object") factory(exports);
else if (typeof define === "function" && define.amd) define([
"exports"
], factory);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {});
})(this, function(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
useRouter: function() {
return useRouter;
},
default: function() {
return _default;
}
});
function useRouter() {}
const _default = useRouter;
});
8 changes: 8 additions & 0 deletions node-swc/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,14 @@ export interface BaseModuleConfig {
* ```
*/
importInterop?: "swc" | "babel" | "node" | "none";
/**
* Emits `cjs-module-lexer` annotation
* `cjs-module-lexer` is used in Node.js core for detecting the named exports available when importing a CJS module into ESM.
* swc will emit `cjs-module-lexer` detectable annotation with this option enabled.
*
* Defaults to `true` if import_interop is Node, else `false`
*/
exportInteropAnnotation?: boolean;
/**
* If set to true, dynamic imports will be preserved.
*/
Expand Down

1 comment on commit caee073

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: caee073 Previous: 84af855 Ratio
es/full/bugs-1 292379 ns/iter (± 12946) 298468 ns/iter (± 15734) 0.98
es/full/minify/libraries/antd 1549510425 ns/iter (± 33469371) 1565732763 ns/iter (± 33299774) 0.99
es/full/minify/libraries/d3 303436117 ns/iter (± 10832667) 290276659 ns/iter (± 11672983) 1.05
es/full/minify/libraries/echarts 1205291214 ns/iter (± 15571283) 1188693318 ns/iter (± 20378060) 1.01
es/full/minify/libraries/jquery 89928444 ns/iter (± 856909) 90259175 ns/iter (± 835014) 1.00
es/full/minify/libraries/lodash 104415028 ns/iter (± 1052705) 104113133 ns/iter (± 950003) 1.00
es/full/minify/libraries/moment 52198734 ns/iter (± 943765) 52157903 ns/iter (± 406591) 1.00
es/full/minify/libraries/react 19081729 ns/iter (± 177113) 18882705 ns/iter (± 117517) 1.01
es/full/minify/libraries/terser 241432120 ns/iter (± 3995825) 239827202 ns/iter (± 3301417) 1.01
es/full/minify/libraries/three 429860892 ns/iter (± 9164439) 428056017 ns/iter (± 9096120) 1.00
es/full/minify/libraries/typescript 2900676498 ns/iter (± 11754798) 2950190437 ns/iter (± 33405239) 0.98
es/full/minify/libraries/victory 639947137 ns/iter (± 18027836) 644071085 ns/iter (± 14707500) 0.99
es/full/minify/libraries/vue 128676867 ns/iter (± 1312035) 129213817 ns/iter (± 1792547) 1.00
es/full/codegen/es3 28615 ns/iter (± 50) 28581 ns/iter (± 53) 1.00
es/full/codegen/es5 28734 ns/iter (± 56) 28589 ns/iter (± 58) 1.01
es/full/codegen/es2015 28710 ns/iter (± 51) 28669 ns/iter (± 188) 1.00
es/full/codegen/es2016 28680 ns/iter (± 49) 28653 ns/iter (± 49) 1.00
es/full/codegen/es2017 28715 ns/iter (± 53) 28538 ns/iter (± 39) 1.01
es/full/codegen/es2018 28734 ns/iter (± 64) 28641 ns/iter (± 53) 1.00
es/full/codegen/es2019 28735 ns/iter (± 44) 28671 ns/iter (± 47) 1.00
es/full/codegen/es2020 28712 ns/iter (± 45) 28690 ns/iter (± 57) 1.00
es/full/all/es3 178804269 ns/iter (± 3470917) 181472086 ns/iter (± 1748835) 0.99
es/full/all/es5 174568921 ns/iter (± 1861422) 172584009 ns/iter (± 2341696) 1.01
es/full/all/es2015 133993663 ns/iter (± 2070038) 134284410 ns/iter (± 2008069) 1.00
es/full/all/es2016 132279793 ns/iter (± 1751472) 132566761 ns/iter (± 2084396) 1.00
es/full/all/es2017 130309425 ns/iter (± 1500207) 131365633 ns/iter (± 1256663) 0.99
es/full/all/es2018 125554282 ns/iter (± 1615773) 125915302 ns/iter (± 1807712) 1.00
es/full/all/es2019 124457190 ns/iter (± 2031258) 125470340 ns/iter (± 1883353) 0.99
es/full/all/es2020 117328594 ns/iter (± 803501) 117671002 ns/iter (± 868059) 1.00
es/full/parser 517762 ns/iter (± 8020) 506472 ns/iter (± 6823) 1.02
es/full/base/fixer 22951 ns/iter (± 48) 22385 ns/iter (± 48) 1.03
es/full/base/resolver_and_hygiene 86288 ns/iter (± 107) 85689 ns/iter (± 107) 1.01
serialization of serde 139 ns/iter (± 0) 121 ns/iter (± 0) 1.15
css/minify/libraries/bootstrap 27663755 ns/iter (± 126776) 27527490 ns/iter (± 141980) 1.00
css/visitor/compare/clone 2100074 ns/iter (± 13176) 2115455 ns/iter (± 11416) 0.99
css/visitor/compare/visit_mut_span 2284848 ns/iter (± 5129) 2294636 ns/iter (± 11899) 1.00
css/visitor/compare/visit_mut_span_panic 2342902 ns/iter (± 7086) 2330710 ns/iter (± 6456) 1.01
css/visitor/compare/fold_span 3076605 ns/iter (± 15518) 3078287 ns/iter (± 8623) 1.00
css/visitor/compare/fold_span_panic 3225621 ns/iter (± 10964) 3219963 ns/iter (± 23263) 1.00
css/lexer/bootstrap_5_1_3 5137670 ns/iter (± 8265) 5144918 ns/iter (± 9859) 1.00
css/lexer/foundation_6_7_4 4316212 ns/iter (± 8285) 4329797 ns/iter (± 7052) 1.00
css/lexer/tailwind_3_1_1 819628 ns/iter (± 1125) 821083 ns/iter (± 655) 1.00
css/parser/bootstrap_5_1_3 21058145 ns/iter (± 232403) 21037232 ns/iter (± 243057) 1.00
css/parser/foundation_6_7_4 16797035 ns/iter (± 91086) 16757607 ns/iter (± 37404) 1.00
css/parser/tailwind_3_1_1 3233232 ns/iter (± 3629) 3240919 ns/iter (± 3389) 1.00
es/codegen/colors 320847 ns/iter (± 182888) 320478 ns/iter (± 181867) 1.00
es/codegen/large 1094397 ns/iter (± 552526) 1250187 ns/iter (± 649912) 0.88
es/codegen/with-parser/colors 47500 ns/iter (± 170) 47361 ns/iter (± 445) 1.00
es/codegen/with-parser/large 512398 ns/iter (± 906) 513886 ns/iter (± 1275) 1.00
es/minify/libraries/antd 1328797441 ns/iter (± 16782684) 1345568774 ns/iter (± 18816217) 0.99
es/minify/libraries/d3 251575127 ns/iter (± 4104195) 254419056 ns/iter (± 3717845) 0.99
es/minify/libraries/echarts 1040749981 ns/iter (± 16201594) 1025470869 ns/iter (± 17757076) 1.01
es/minify/libraries/jquery 79188877 ns/iter (± 1081350) 78568753 ns/iter (± 750061) 1.01
es/minify/libraries/lodash 95478520 ns/iter (± 1100256) 94315369 ns/iter (± 1004409) 1.01
es/minify/libraries/moment 45939473 ns/iter (± 605526) 45286020 ns/iter (± 139435) 1.01
es/minify/libraries/react 16970338 ns/iter (± 268255) 16989780 ns/iter (± 128609) 1.00
es/minify/libraries/terser 206945729 ns/iter (± 4355639) 211518049 ns/iter (± 5436399) 0.98
es/minify/libraries/three 364498859 ns/iter (± 9403968) 352128435 ns/iter (± 6084395) 1.04
es/minify/libraries/typescript 2472880380 ns/iter (± 19365345) 2474337576 ns/iter (± 11030272) 1.00
es/minify/libraries/victory 561464619 ns/iter (± 7541792) 555838543 ns/iter (± 17909401) 1.01
es/minify/libraries/vue 113989039 ns/iter (± 1848896) 115323403 ns/iter (± 2124607) 0.99
es/visitor/compare/clone 2325488 ns/iter (± 4860) 2333950 ns/iter (± 8230) 1.00
es/visitor/compare/visit_mut_span 2708274 ns/iter (± 5391) 2699920 ns/iter (± 7985) 1.00
es/visitor/compare/visit_mut_span_panic 2740550 ns/iter (± 25152) 2744533 ns/iter (± 5349) 1.00
es/visitor/compare/fold_span 3823888 ns/iter (± 13958) 3812467 ns/iter (± 30226) 1.00
es/visitor/compare/fold_span_panic 3956896 ns/iter (± 10840) 3956327 ns/iter (± 13918) 1.00
es/lexer/colors 13168 ns/iter (± 69) 13116 ns/iter (± 20) 1.00
es/lexer/angular 6457219 ns/iter (± 7964) 6421581 ns/iter (± 9891) 1.01
es/lexer/backbone 793462 ns/iter (± 1284) 788903 ns/iter (± 692) 1.01
es/lexer/jquery 4450671 ns/iter (± 4327) 4430106 ns/iter (± 6124) 1.00
es/lexer/jquery mobile 6973146 ns/iter (± 5899) 6942893 ns/iter (± 6509) 1.00
es/lexer/mootools 3491568 ns/iter (± 4340) 3477700 ns/iter (± 2857) 1.00
es/lexer/underscore 655141 ns/iter (± 613) 650097 ns/iter (± 1012) 1.01
es/lexer/three 21137840 ns/iter (± 27491) 21024004 ns/iter (± 68033) 1.01
es/lexer/yui 3886903 ns/iter (± 6162) 3871244 ns/iter (± 10681) 1.00
es/parser/colors 28970 ns/iter (± 88) 28786 ns/iter (± 44) 1.01
es/parser/angular 15025892 ns/iter (± 170710) 14960426 ns/iter (± 316013) 1.00
es/parser/backbone 2150320 ns/iter (± 14666) 2141131 ns/iter (± 10134) 1.00
es/parser/jquery 11729750 ns/iter (± 111787) 11642189 ns/iter (± 111688) 1.01
es/parser/jquery mobile 18144509 ns/iter (± 164935) 18186273 ns/iter (± 166818) 1.00
es/parser/mootools 8905807 ns/iter (± 18047) 8847833 ns/iter (± 25695) 1.01
es/parser/underscore 1814331 ns/iter (± 10673) 1802523 ns/iter (± 12407) 1.01
es/parser/three 53099585 ns/iter (± 873972) 53780060 ns/iter (± 468411) 0.99
es/parser/yui 9057277 ns/iter (± 60540) 9017052 ns/iter (± 57053) 1.00
es/preset-env/usage/builtin_type 142853 ns/iter (± 35150) 143243 ns/iter (± 35435) 1.00
es/preset-env/usage/property 19738 ns/iter (± 138) 19817 ns/iter (± 54) 1.00
es/resolver/typescript 111408420 ns/iter (± 3670453) 111327600 ns/iter (± 1457921) 1.00
es/fixer/typescript 77304846 ns/iter (± 484504) 76969355 ns/iter (± 1273910) 1.00
es/hygiene/typescript 165927754 ns/iter (± 1581513) 167262198 ns/iter (± 1579315) 0.99
es/resolver_with_hygiene/typescript 306844962 ns/iter (± 2213818) 309861414 ns/iter (± 2983619) 0.99
es/visitor/base-perf/module_clone 80811 ns/iter (± 540) 80446 ns/iter (± 415) 1.00
es/visitor/base-perf/fold_empty 90777 ns/iter (± 342) 90772 ns/iter (± 473) 1.00
es/visitor/base-perf/fold_noop_impl_all 91310 ns/iter (± 365) 91589 ns/iter (± 398) 1.00
es/visitor/base-perf/fold_noop_impl_vec 91470 ns/iter (± 624) 91712 ns/iter (± 388) 1.00
es/visitor/base-perf/boxing_boxed_clone 56 ns/iter (± 0) 57 ns/iter (± 0) 0.98
es/visitor/base-perf/boxing_unboxed_clone 41 ns/iter (± 0) 41 ns/iter (± 0) 1
es/visitor/base-perf/boxing_boxed 103 ns/iter (± 0) 103 ns/iter (± 0) 1
es/visitor/base-perf/boxing_unboxed 78 ns/iter (± 0) 78 ns/iter (± 0) 1
es/visitor/base-perf/visit_contains_this 3570 ns/iter (± 57) 3518 ns/iter (± 78) 1.01
es/base/parallel/resolver/typescript 5687137548 ns/iter (± 405575822) 5763609907 ns/iter (± 451674666) 0.99
es/base/parallel/hygiene/typescript 2003608603 ns/iter (± 28159604) 2010571123 ns/iter (± 32338890) 1.00
misc/visitors/time-complexity/time 5 106 ns/iter (± 0) 106 ns/iter (± 0) 1
misc/visitors/time-complexity/time 10 343 ns/iter (± 0) 341 ns/iter (± 0) 1.01
misc/visitors/time-complexity/time 15 664 ns/iter (± 2) 666 ns/iter (± 3) 1.00
misc/visitors/time-complexity/time 20 1226 ns/iter (± 1) 1225 ns/iter (± 0) 1.00
misc/visitors/time-complexity/time 40 6211 ns/iter (± 11) 6206 ns/iter (± 25) 1.00
misc/visitors/time-complexity/time 60 15588 ns/iter (± 17) 15698 ns/iter (± 11) 0.99
es/full-target/es2016 254205 ns/iter (± 426) 252806 ns/iter (± 765) 1.01
es/full-target/es2017 245870 ns/iter (± 480) 246700 ns/iter (± 514) 1.00
es/full-target/es2018 235501 ns/iter (± 481) 235819 ns/iter (± 550) 1.00
es2020_nullish_coalescing 92882 ns/iter (± 379) 93079 ns/iter (± 443) 1.00
es2020_optional_chaining 124868 ns/iter (± 258) 124708 ns/iter (± 163) 1.00
es2022_class_properties 149201 ns/iter (± 219) 149308 ns/iter (± 337) 1.00
es2018_object_rest_spread 96528 ns/iter (± 381) 96777 ns/iter (± 154) 1.00
es2019_optional_catch_binding 85691 ns/iter (± 160) 85779 ns/iter (± 248) 1.00
es2017_async_to_generator 85802 ns/iter (± 254) 85951 ns/iter (± 168) 1.00
es2016_exponentiation 90334 ns/iter (± 200) 90827 ns/iter (± 260) 0.99
es2015_arrow 94049 ns/iter (± 386) 94395 ns/iter (± 369) 1.00
es2015_block_scoped_fn 92349 ns/iter (± 407) 92473 ns/iter (± 238) 1.00
es2015_block_scoping 169527 ns/iter (± 253) 169690 ns/iter (± 345) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.