Skip to content

Commit

Permalink
feat: empty module should have ExportsKind::None (#317)
Browse files Browse the repository at this point in the history
<!-- Thank you for contributing! -->

### Description

<!-- Please insert your description here and provide especially info about the "what" this PR is solving -->

### Test Plan

<!-- e.g. is there anything you'd like reviewers to focus on? -->

---
  • Loading branch information
hyf0 authored Nov 19, 2023
1 parent 94f5ddd commit b15ff14
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 45 deletions.
72 changes: 40 additions & 32 deletions crates/rolldown/src/bundler/visitors/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ pub struct Scanner<'a> {
current_stmt_info: StmtInfo,
result: ScanResult,
esm_export_keyword: Option<Span>,
cjs_export_keyword: Option<Span>,
esm_import_keyword: Option<Span>,
pub namespace_symbol: SymbolRef,
used_exports_ref: bool,
used_module_ref: bool,
}

impl<'ast> Scanner<'ast> {
Expand All @@ -68,45 +70,49 @@ impl<'ast> Scanner<'ast> {
current_stmt_info: StmtInfo::default(),
result,
esm_export_keyword: None,
cjs_export_keyword: None,
esm_import_keyword: None,
module_type,
namespace_symbol: namespace_ref,
used_exports_ref: false,
used_module_ref: false,
}
}

pub fn scan(mut self, program: &Program<'ast>) -> ScanResult {
self.visit_program(program);
self.result
}
let mut exports_kind = ExportsKind::None;

fn set_esm_export_keyword(&mut self, span: Span) {
if self.esm_export_keyword.is_none() {
self.esm_export_keyword = Some(span);
if self.esm_export_keyword.is_some() {
exports_kind = ExportsKind::Esm;
} else if self.used_exports_ref || self.used_module_ref {
exports_kind = ExportsKind::CommonJs;
} else {
// TODO(hyf0): need review this. Why `ModuleType` doesn't have higher priority?
match self.module_type {
ModuleType::CJS | ModuleType::CjsPackageJson => {
exports_kind = ExportsKind::CommonJs;
}
ModuleType::EsmMjs | ModuleType::EsmPackageJson => {
exports_kind = ExportsKind::Esm;
}
ModuleType::Unknown => {
if self.esm_import_keyword.is_some() {
exports_kind = ExportsKind::Esm;
}
}
}
}

self.result.exports_kind = exports_kind;
self.result
}

fn is_unresolved_reference(&self, ident_ref: &IdentifierReference) -> bool {
self.scope.is_unresolved(ident_ref.reference_id.get().unwrap())
}

fn set_cjs_export_keyword(&mut self, span: Span) {
if self.cjs_export_keyword.is_none() {
self.cjs_export_keyword = Some(span);
}
}

fn set_exports_kind(&mut self) {
if self.esm_export_keyword.is_some() {
self.result.exports_kind = ExportsKind::Esm;
} else if self.cjs_export_keyword.is_some() {
self.result.exports_kind = ExportsKind::CommonJs;
} else if self.module_type.is_esm() {
self.result.exports_kind = ExportsKind::Esm;
} else if self.module_type.is_commonjs() {
self.result.exports_kind = ExportsKind::CommonJs;
} else {
self.result.exports_kind = ExportsKind::Esm;
}
fn set_esm_export_keyword(&mut self, span: Span) {
self.esm_export_keyword.get_or_insert(span);
}

fn add_declared_id(&mut self, id: SymbolId) {
Expand Down Expand Up @@ -276,6 +282,8 @@ impl<'ast> Scanner<'ast> {
fn scan_module_decl(&mut self, decl: &ModuleDeclaration) {
match decl {
oxc::ast::ast::ModuleDeclaration::ImportDeclaration(decl) => {
// TODO: this should be the span of `import` keyword, while now it is the span of the whole import declaration.
self.esm_import_keyword.get_or_insert(decl.span);
self.scan_import_decl(decl);
}
oxc::ast::ast::ModuleDeclaration::ExportAllDeclaration(decl) => {
Expand Down Expand Up @@ -311,7 +319,6 @@ impl<'ast> Visit<'ast> for Scanner<'ast> {
self.visit_statement(stmt);
self.result.stmt_infos.add_stmt_info(std::mem::take(&mut self.current_stmt_info));
}
self.set_exports_kind();
}

fn visit_binding_identifier(&mut self, ident: &oxc::ast::ast::BindingIdentifier) {
Expand All @@ -327,14 +334,15 @@ impl<'ast> Visit<'ast> for Scanner<'ast> {
Some(symbol_id) if self.is_top_level(symbol_id) => {
self.add_referenced_symbol(symbol_id);
}
_ => {}
}
if ident.name == "module" || ident.name == "exports" {
if let Some(refs) = self.scope.root_unresolved_references().get(&ident.name) {
if refs.iter().any(|r| (*r).eq(&ident.reference_id.get().unwrap())) {
self.set_cjs_export_keyword(ident.span);
None => {
if ident.name == "module" {
self.used_module_ref = true;
}
if ident.name == "exports" {
self.used_exports_ref = true;
}
}
_ => {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ input_file: crates/rolldown/tests/esbuild/default/nested_common_js
## entry_js.mjs

```js
import { __commonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS } from "./_rolldown_runtime.mjs";
// foo.js
var require_foo = __commonJS({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ input_file: crates/rolldown/tests/esbuild/default/new_expression_common_js
## entry_js.mjs

```js
import { __commonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS } from "./_rolldown_runtime.mjs";
// foo.js
var require_foo = __commonJS({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ input_file: crates/rolldown/tests/esbuild/default/require_child_dir_common_js
## entry_js.mjs

```js
import { __commonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS } from "./_rolldown_runtime.mjs";
// dir/index.js
var require_dir_index = __commonJS({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ input_file: crates/rolldown/tests/esbuild/default/require_parent_dir_common_js
## dir_entry_js.mjs

```js
import { __commonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS } from "./_rolldown_runtime.mjs";
// index.js
var require_require_parent_dir_common_js_index = __commonJS({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ input_file: crates/rolldown/tests/esbuild/default/simple_common_js
## entry_js.mjs

```js
import { __commonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS } from "./_rolldown_runtime.mjs";
// foo.js
var require_foo = __commonJS({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ input_file: crates/rolldown/tests/esbuild/default/use_strict_directive_bundle_is
## entry_js.mjs

```js
import { __commonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS } from "./_rolldown_runtime.mjs";
// cjs.js
var require_cjs = __commonJS({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export { require_shared };
## a.mjs

```js
import { __toESM } from "./_rolldown_runtime.mjs";
import { require_shared } from "./2.mjs";
// a.js
Expand All @@ -31,7 +30,6 @@ console.log(foo)
## b.mjs

```js
import { __toESM } from "./_rolldown_runtime.mjs";
import { require_shared } from "./2.mjs";
// b.js
Expand Down
5 changes: 1 addition & 4 deletions crates/rolldown/tests/fixtures/mix-cjs-esm/artifacts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@ input_file: crates/rolldown/tests/fixtures/mix-cjs-esm
## main.mjs

```js
import { __commonJS, __esm, __toCommonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS, __esm, __toESM } from "./_rolldown_runtime.mjs";
// esm-export-cjs-export.js
module.exports = 1;
const value$1 = 1;
// foo.js
var foo_ns = {
};
var init_foo = __esm({
'foo.js'() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ input_file: crates/rolldown/tests/fixtures/require/require_cjs
## main.mjs

```js
import { __commonJS, __toESM } from "./_rolldown_runtime.mjs";
import { __commonJS } from "./_rolldown_runtime.mjs";
// cjs.js
var require_cjs = __commonJS({
Expand Down

0 comments on commit b15ff14

Please sign in to comment.