diff --git a/crates/rolldown/src/bundler/visitors/esm_wrap_source_render.rs b/crates/rolldown/src/bundler/visitors/esm_wrap_source_render.rs index 5772e9d8f8b..12b7b02efe9 100644 --- a/crates/rolldown/src/bundler/visitors/esm_wrap_source_render.rs +++ b/crates/rolldown/src/bundler/visitors/esm_wrap_source_render.rs @@ -55,16 +55,6 @@ impl<'ast> EsmWrapSourceRender<'ast> { ); self.ctx.source.append("\n}\n});"); } - - fn hoisted_function(&mut self, func: &'ast oxc::ast::ast::Function<'ast>) { - // deconflict function name - if let Some(id) = &func.id { - let name = - self.ctx.get_symbol_final_name((self.ctx.module.id, id.expect_symbol_id()).into()).unwrap(); - self.ctx.overwrite(id.span.start, id.span.end, name.to_string()); - } - self.hoisted_functions.push(func.span); - } } impl<'ast> Visit<'ast> for EsmWrapSourceRender<'ast> { @@ -105,7 +95,15 @@ impl<'ast> Visit<'ast> for EsmWrapSourceRender<'ast> { } Declaration::FunctionDeclaration(func) => { self.ctx.remove_node(Span::new(named_decl.span.start, func.span.start)); - self.hoisted_function(func); + let id = func.id.as_ref().unwrap(); + let name = self + .ctx + .get_symbol_final_name((self.ctx.module.id, id.expect_symbol_id()).into()) + .unwrap(); + if id.name != name { + self.ctx.overwrite(id.span.start, id.span.end, name.to_string()); + } + self.hoisted_functions.push(func.span); } Declaration::ClassDeclaration(class) => { let id = class.id.as_ref().unwrap(); @@ -114,6 +112,9 @@ impl<'ast> Visit<'ast> for EsmWrapSourceRender<'ast> { { self.hoisted_vars.push(name.clone()); self.ctx.overwrite(named_decl.span.start, class.span.start, format!("{name} = ")); + // avoid syntax error + // export class Foo {} Foo.prop = 123 => var Foo = class Foo {} \n Foo.prop = 123 + self.ctx.source.append_right(class.span.end, "\n"); } } _ => {} @@ -142,12 +143,27 @@ impl<'ast> Visit<'ast> for EsmWrapSourceRender<'ast> { } oxc::ast::ast::ExportDefaultDeclarationKind::FunctionDeclaration(func) => { self.ctx.remove_node(Span::new(decl.span.start, func.span.start)); - self.hoisted_function(func); + if let Some(id) = &func.id { + let name = self + .ctx + .get_symbol_final_name((self.ctx.module.id, id.expect_symbol_id()).into()) + .unwrap(); + if id.name != name { + self.ctx.overwrite(id.span.start, id.span.end, name.to_string()); + } + } else { + let default_symbol_name = self.ctx.default_symbol_name.unwrap(); + self.ctx.source.append_right(func.params.span.start, format!(" {default_symbol_name}")); + } + self.hoisted_functions.push(func.span); } oxc::ast::ast::ExportDefaultDeclarationKind::ClassDeclaration(class) => { let default_symbol_name = self.ctx.default_symbol_name.unwrap(); self.hoisted_vars.push(default_symbol_name.clone()); self.ctx.overwrite(decl.span.start, class.span.start, format!("{default_symbol_name} = ")); + // avoid syntax error + // export default class Foo {} Foo.prop = 123 => var Foo = class Foo {} \n Foo.prop = 123 + self.ctx.source.append_right(class.span.end, "\n"); } _ => {} } diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/a.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/a.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/a.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/a.js diff --git a/crates/rolldown/tests/esbuild/default/export_froms_common_js/artifacts.snap b/crates/rolldown/tests/esbuild/default/export_froms_common_js/artifacts.snap new file mode 100644 index 00000000000..9ef821310c9 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/export_froms_common_js/artifacts.snap @@ -0,0 +1,126 @@ +--- +source: crates/rolldown/tests/common/case.rs +expression: content +input_file: crates/rolldown/tests/esbuild/default/export_froms_common_js +--- +# main.js + +```js +// h.js +async function foo$1() {} +var h_ns = { + get default() { return foo$1 } +}; +var init_h = __esm({ +'h.js'() { + foo$1.prop = 123 +} +}); +// g.js +async function g_default() {} +var g_ns = { + get default() { return g_default } +}; +var init_g = __esm({ +'g.js'() { + +} +}); +// f.js +function foo() {} +var f_ns = { + get default() { return foo } +}; +var init_f = __esm({ +'f.js'() { + foo.prop = 123 +} +}); +// e.js +function e_default() {} +var e_ns = { + get default() { return e_default } +}; +var init_e = __esm({ +'e.js'() { + +} +}); +// d.js +var Foo; +var d_ns = { + get default() { return Foo } +}; +var init_d = __esm({ +'d.js'() { +Foo = class Foo {} + Foo.prop = 123 +} +}); +// c.js +var c_default; +var c_ns = { + get default() { return c_default } +}; +var init_c = __esm({ +'c.js'() { +c_default = class {} + +} +}); +// b.js +var xyz; +var b_ns = { + get xyz() { return xyz } +}; +var init_b = __esm({ +'b.js'() { +xyz = null +} +}); +// a.js +var abc; +var a_ns = { + get abc() { return abc } +}; +var init_a = __esm({ +'a.js'() { +abc = undefined +} +}); +// commonjs.js +function Fn() {} +var commonjs_default,v,l,c,Class; +var commonjs_ns = { + get Fn() { return Fn }, + get Class() { return Class }, + get abc() { return abc }, + get v() { return v }, + get default() { return commonjs_default }, + get c() { return c }, + get b() { return b_ns }, + get l() { return l } +}; +var init_commonjs = __esm({ +'commonjs.js'() { +commonjs_default = 123 +v = 234 +l = 234 +c = 234 + + +Class = class Class {} + + + +} +}); +// main.js +(init_commonjs(), __toCommonJS(commonjs_ns)) +(init_c(), __toCommonJS(c_ns)) +(init_d(), __toCommonJS(d_ns)) +(init_e(), __toCommonJS(e_ns)) +(init_f(), __toCommonJS(f_ns)) +(init_g(), __toCommonJS(g_ns)) +(init_h(), __toCommonJS(h_ns)) +``` diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/b.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/b.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/b.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/b.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/c.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/c.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/c.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/c.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/commonjs.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/commonjs.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/commonjs.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/commonjs.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/d.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/d.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/d.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/d.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/e.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/e.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/e.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/e.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/f.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/f.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/f.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/f.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/g.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/g.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/g.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/g.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/h.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/h.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/h.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/h.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/main.js b/crates/rolldown/tests/esbuild/default/export_froms_common_js/main.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/main.js rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/main.js diff --git a/crates/rolldown/tests/esbuild/default/.export_froms_common_js/test.config.json b/crates/rolldown/tests/esbuild/default/export_froms_common_js/test.config.json similarity index 100% rename from crates/rolldown/tests/esbuild/default/.export_froms_common_js/test.config.json rename to crates/rolldown/tests/esbuild/default/export_froms_common_js/test.config.json diff --git a/crates/rolldown/tests/esbuild/default/nested_common_js/artifacts.snap b/crates/rolldown/tests/esbuild/default/nested_common_js/artifacts.snap new file mode 100644 index 00000000000..f5165f1fa09 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/nested_common_js/artifacts.snap @@ -0,0 +1,23 @@ +--- +source: crates/rolldown/tests/common/case.rs +expression: content +input_file: crates/rolldown/tests/esbuild/default/nested_common_js +--- +# main.js + +```js +// foo.js +var require_foo = __commonJS({ +'foo.js'(exports, module) { +module.exports = function() { + return 123 +} +} +}); +// main.js +function nestedScope() { + const fn = require_foo() + console.log(fn()) +} +nestedScope() +``` diff --git a/crates/rolldown/tests/esbuild/default/.nested_common_js/foo.js b/crates/rolldown/tests/esbuild/default/nested_common_js/foo.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.nested_common_js/foo.js rename to crates/rolldown/tests/esbuild/default/nested_common_js/foo.js diff --git a/crates/rolldown/tests/esbuild/default/.nested_common_js/main.js b/crates/rolldown/tests/esbuild/default/nested_common_js/main.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.nested_common_js/main.js rename to crates/rolldown/tests/esbuild/default/nested_common_js/main.js diff --git a/crates/rolldown/tests/esbuild/default/.nested_common_js/test.config.json b/crates/rolldown/tests/esbuild/default/nested_common_js/test.config.json similarity index 100% rename from crates/rolldown/tests/esbuild/default/.nested_common_js/test.config.json rename to crates/rolldown/tests/esbuild/default/nested_common_js/test.config.json diff --git a/crates/rolldown/tests/esbuild/default/new_expression_common_js/artifacts.snap b/crates/rolldown/tests/esbuild/default/new_expression_common_js/artifacts.snap new file mode 100644 index 00000000000..a59b5097741 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/new_expression_common_js/artifacts.snap @@ -0,0 +1,18 @@ +--- +source: crates/rolldown/tests/common/case.rs +expression: content +input_file: crates/rolldown/tests/esbuild/default/new_expression_common_js +--- +# main.js + +```js +// foo.js +var require_foo = __commonJS({ +'foo.js'(exports, module) { +class Foo {} +module.exports = {Foo}; +} +}); +// main.js +new (require_foo()).Foo(); +``` diff --git a/crates/rolldown/tests/esbuild/default/.new_expression_common_js/foo.js b/crates/rolldown/tests/esbuild/default/new_expression_common_js/foo.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.new_expression_common_js/foo.js rename to crates/rolldown/tests/esbuild/default/new_expression_common_js/foo.js diff --git a/crates/rolldown/tests/esbuild/default/.new_expression_common_js/main.js b/crates/rolldown/tests/esbuild/default/new_expression_common_js/main.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.new_expression_common_js/main.js rename to crates/rolldown/tests/esbuild/default/new_expression_common_js/main.js diff --git a/crates/rolldown/tests/esbuild/default/.new_expression_common_js/test.config.json b/crates/rolldown/tests/esbuild/default/new_expression_common_js/test.config.json similarity index 100% rename from crates/rolldown/tests/esbuild/default/.new_expression_common_js/test.config.json rename to crates/rolldown/tests/esbuild/default/new_expression_common_js/test.config.json diff --git a/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/artifacts.snap b/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/artifacts.snap new file mode 100644 index 00000000000..c5d367a2a94 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/artifacts.snap @@ -0,0 +1,17 @@ +--- +source: crates/rolldown/tests/common/case.rs +expression: content +input_file: crates/rolldown/tests/esbuild/default/require_child_dir_common_js +--- +# main.js + +```js +// dir/index.js +var require_dir_index = __commonJS({ +'dir/index.js'(exports, module) { +module.exports = 123 +} +}); +// main.js +console.log(require_dir_index()) +``` diff --git a/crates/rolldown/tests/esbuild/default/.require_child_dir_common_js/dir/index.js b/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/dir/index.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_child_dir_common_js/dir/index.js rename to crates/rolldown/tests/esbuild/default/require_child_dir_common_js/dir/index.js diff --git a/crates/rolldown/tests/esbuild/default/.require_child_dir_common_js/main.js b/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/main.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_child_dir_common_js/main.js rename to crates/rolldown/tests/esbuild/default/require_child_dir_common_js/main.js diff --git a/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/test.config.json b/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/test.config.json new file mode 100644 index 00000000000..9e26dfeeb6e --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_child_dir_common_js/test.config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/crates/rolldown/tests/esbuild/default/require_child_dir_es6/artifacts.snap b/crates/rolldown/tests/esbuild/default/require_child_dir_es6/artifacts.snap new file mode 100644 index 00000000000..a5902d78b89 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_child_dir_es6/artifacts.snap @@ -0,0 +1,15 @@ +--- +source: crates/rolldown/tests/common/case.rs +expression: content +input_file: crates/rolldown/tests/esbuild/default/require_child_dir_es6 +--- +# main.js + +```js +// dir/index.js +var dir_index_default = 123 + +// main.js + +console.log(dir_index_default) +``` diff --git a/crates/rolldown/tests/esbuild/default/.require_child_dir_es6/dir/index.js b/crates/rolldown/tests/esbuild/default/require_child_dir_es6/dir/index.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_child_dir_es6/dir/index.js rename to crates/rolldown/tests/esbuild/default/require_child_dir_es6/dir/index.js diff --git a/crates/rolldown/tests/esbuild/default/.require_child_dir_es6/main.js b/crates/rolldown/tests/esbuild/default/require_child_dir_es6/main.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_child_dir_es6/main.js rename to crates/rolldown/tests/esbuild/default/require_child_dir_es6/main.js diff --git a/crates/rolldown/tests/esbuild/default/require_child_dir_es6/test.config.json b/crates/rolldown/tests/esbuild/default/require_child_dir_es6/test.config.json new file mode 100644 index 00000000000..9e26dfeeb6e --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_child_dir_es6/test.config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/artifacts.snap b/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/artifacts.snap new file mode 100644 index 00000000000..374be5d77e4 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/artifacts.snap @@ -0,0 +1,17 @@ +--- +source: crates/rolldown/tests/common/case.rs +expression: content +input_file: crates/rolldown/tests/esbuild/default/require_parent_dir_common_js +--- +# main.js + +```js +// index.js +var require_require_parent_dir_common_js_index = __commonJS({ +'index.js'(exports, module) { +module.exports = 123 +} +}); +// dir/entry.js +console.log(require_require_parent_dir_common_js_index()) +``` diff --git a/crates/rolldown/tests/esbuild/default/.require_parent_dir_common_js/dir/entry.js b/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/dir/entry.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_parent_dir_common_js/dir/entry.js rename to crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/dir/entry.js diff --git a/crates/rolldown/tests/esbuild/default/.require_parent_dir_common_js/index.js b/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/index.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_parent_dir_common_js/index.js rename to crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/index.js diff --git a/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/test.config.json b/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/test.config.json new file mode 100644 index 00000000000..e81489ce2f6 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_parent_dir_common_js/test.config.json @@ -0,0 +1,10 @@ +{ + "input": { + "input": [ + { + "name": "main", + "import": "dir/entry.js" + } + ] + } +} \ No newline at end of file diff --git a/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/artifacts.snap b/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/artifacts.snap new file mode 100644 index 00000000000..4452751cc1a --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/artifacts.snap @@ -0,0 +1,15 @@ +--- +source: crates/rolldown/tests/common/case.rs +expression: content +input_file: crates/rolldown/tests/esbuild/default/require_parent_dir_es6 +--- +# main.js + +```js +// index.js +var require_parent_dir_es6_index_default = 123 + +// dir/entry.js + +console.log(require_parent_dir_es6_index_default) +``` diff --git a/crates/rolldown/tests/esbuild/default/.require_parent_dir_es6/dir/entry.js b/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/dir/entry.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_parent_dir_es6/dir/entry.js rename to crates/rolldown/tests/esbuild/default/require_parent_dir_es6/dir/entry.js diff --git a/crates/rolldown/tests/esbuild/default/.require_parent_dir_es6/index.js b/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/index.js similarity index 100% rename from crates/rolldown/tests/esbuild/default/.require_parent_dir_es6/index.js rename to crates/rolldown/tests/esbuild/default/require_parent_dir_es6/index.js diff --git a/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/test.config.json b/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/test.config.json new file mode 100644 index 00000000000..e81489ce2f6 --- /dev/null +++ b/crates/rolldown/tests/esbuild/default/require_parent_dir_es6/test.config.json @@ -0,0 +1,10 @@ +{ + "input": { + "input": [ + { + "name": "main", + "import": "dir/entry.js" + } + ] + } +} \ No newline at end of file diff --git a/crates/rolldown/tests/fixtures/basic_commonjs/artifacts.snap b/crates/rolldown/tests/fixtures/basic_commonjs/artifacts.snap index 8d9470991ed..eed38816e87 100644 --- a/crates/rolldown/tests/fixtures/basic_commonjs/artifacts.snap +++ b/crates/rolldown/tests/fixtures/basic_commonjs/artifacts.snap @@ -22,6 +22,7 @@ var init_esm = __esm({ esm_named_var = 1; esm_named_class = class esm_named_class {} + } }); // commonjs.js