Skip to content

Commit e7916ab

Browse files
authored
feat: add some warnings in IIFE and CJS. (#1857)
resolves #1855. 1. ``` No name was provided for external module "node:path" in "output.globals" – guessing "node_path". ``` 2. ``` If you do not supply "output.name", you may not be able to access the exports of an IIFE bundle. ``` 3. ``` Entry module "main.js" is using named and default exports together. Consumers of your bundle will have to use `chunk.default` to access the default export, which may not be what you want. Use `output.exports: "named"` to disable this warning. ```
1 parent 58ed16e commit e7916ab

File tree

56 files changed

+342
-65
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+342
-65
lines changed

crates/rolldown/src/ecmascript/format/cjs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub fn render_cjs(
4646
if matches!(entry_module.exports_kind, ExportsKind::Esm) {
4747
let export_items = get_export_items(ctx.chunk, ctx.link_output);
4848
let has_default_export = export_items.iter().any(|(name, _)| name.as_str() == "default");
49-
let export_mode = determine_export_mode(&ctx.options.exports, entry_module, &export_items)?;
49+
let export_mode = determine_export_mode(ctx, entry_module, &export_items)?;
5050
// Only `named` export can we render the namespace markers.
5151
if matches!(&export_mode, OutputExports::Named) {
5252
if let Some(marker) =

crates/rolldown/src/ecmascript/format/iife.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ use crate::{
1111
render_chunk_exports::{get_export_items, render_chunk_exports},
1212
},
1313
};
14+
use arcstr::ArcStr;
1415
use rolldown_common::{ChunkKind, OutputExports};
15-
use rolldown_error::DiagnosableResult;
16+
use rolldown_error::{BuildDiagnostic, DiagnosableResult};
1617
use rolldown_sourcemap::{ConcatSource, RawSource};
1718
use rolldown_utils::ecma_script::legitimize_identifier_name;
18-
use rustc_hash::FxHashMap;
1919

2020
// TODO refactor it to `wrap.rs` to reuse it for other formats (e.g. amd, umd).
2121
pub fn render_iife(
@@ -37,26 +37,30 @@ pub fn render_iife(
3737
let export_items = get_export_items(ctx.chunk, ctx.link_output);
3838
let has_exports = !export_items.is_empty();
3939
let has_default_export = export_items.iter().any(|(name, _)| name.as_str() == "default");
40-
// Since before rendering the `determine_export_mode` runs, `unwrap` here won't cause panic.
41-
// FIXME do not call `determine_export_mode` twice
4240
let entry_module = match ctx.chunk.kind {
4341
ChunkKind::EntryPoint { module, .. } => {
4442
&ctx.link_output.module_table.modules[module].as_ecma().expect("should be ecma module")
4543
}
4644
ChunkKind::Common => unreachable!("iife should be entry point chunk"),
4745
};
48-
let export_mode = determine_export_mode(&ctx.options.exports, entry_module, &export_items)?;
46+
let export_mode = determine_export_mode(ctx, entry_module, &export_items)?;
4947
let named_exports = matches!(&export_mode, OutputExports::Named);
5048

5149
let (import_code, externals) = render_iife_chunk_imports(ctx);
5250

5351
let (input_args, output_args) =
54-
render_iife_arguments(&externals, &ctx.options.globals, has_exports && named_exports);
52+
render_iife_arguments(ctx, &externals, has_exports && named_exports);
5553

5654
concat_source.add_source(Box::new(RawSource::new(format!(
5755
"{}(function({}) {{\n",
58-
if let Some(name) = &ctx.options.name { format!("var {name} = ") } else { String::new() },
59-
// TODO handle external imports here.
56+
if let Some(name) = &ctx.options.name {
57+
format!("var {name} = ")
58+
} else {
59+
ctx
60+
.warnings
61+
.push(BuildDiagnostic::missing_name_option_for_iife_export().with_severity_warning());
62+
String::new()
63+
},
6064
input_args
6165
))));
6266

@@ -162,19 +166,24 @@ fn render_iife_chunk_imports(ctx: &GenerateContext<'_>) -> (String, Vec<String>)
162166
}
163167

164168
fn render_iife_arguments(
169+
ctx: &mut GenerateContext<'_>,
165170
externals: &[String],
166-
globals: &FxHashMap<String, String>,
167171
exports_key: bool,
168172
) -> (String, String) {
169173
let mut input_args = if exports_key { vec!["exports".to_string()] } else { vec![] };
170174
let mut output_args = if exports_key { vec!["{}".to_string()] } else { vec![] };
175+
let globals = &ctx.options.globals;
171176
externals.iter().for_each(|external| {
172177
input_args.push(legitimize_identifier_name(external).to_string());
173178
if let Some(global) = globals.get(external) {
174179
output_args.push(legitimize_identifier_name(global).to_string());
175180
} else {
176-
// TODO add warning for missing global
177-
output_args.push(legitimize_identifier_name(external).to_string());
181+
let target = legitimize_identifier_name(external).to_string();
182+
ctx.warnings.push(
183+
BuildDiagnostic::missing_global_name(ArcStr::from(external), ArcStr::from(&target))
184+
.with_severity_warning(),
185+
);
186+
output_args.push(target.to_string());
178187
}
179188
});
180189
(input_args.join(", "), output_args.join(", "))

crates/rolldown/src/utils/chunk/determine_export_mode.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
use crate::types::generator::GenerateContext;
2+
use arcstr::ArcStr;
13
use rolldown_common::{EcmaModule, OutputExports, SymbolRef};
24
use rolldown_error::{BuildDiagnostic, DiagnosableResult};
35
use rolldown_rstr::Rstr;
46

57
// Port from https://github.com/rollup/rollup/blob/master/src/utils/getExportMode.ts
68
pub fn determine_export_mode(
7-
export_mode: &OutputExports,
9+
ctx: &mut GenerateContext<'_>,
810
module: &EcmaModule,
911
exports: &[(Rstr, SymbolRef)],
1012
) -> DiagnosableResult<OutputExports> {
13+
let export_mode = &ctx.options.exports;
1114
match export_mode {
1215
OutputExports::Named => Ok(OutputExports::Named),
1316
OutputExports::Default => {
@@ -36,7 +39,20 @@ pub fn determine_export_mode(
3639
} else if exports.len() == 1 && exports[0].0.as_str() == "default" {
3740
Ok(OutputExports::Default)
3841
} else {
39-
// TODO add warnings
42+
let has_default_export = exports.iter().any(|(name, _)| name.as_str() == "default");
43+
if has_default_export {
44+
let name = &ctx.chunk.name;
45+
let chunk = ArcStr::from("chunk");
46+
let name = name.as_ref().unwrap_or(&chunk);
47+
ctx.warnings.push(
48+
BuildDiagnostic::mixed_export(
49+
ArcStr::from(module.stable_id.as_str()),
50+
ArcStr::from(name),
51+
exports.iter().map(|(name, _)| name.as_str().into()).collect(),
52+
)
53+
.with_severity_warning(),
54+
);
55+
}
4056
Ok(OutputExports::Named)
4157
}
4258
}

crates/rolldown/tests/esbuild/dce/tree_shaking_no_bundle_iife/_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"import": "entry.js"
77
}
88
],
9-
"format": "iife"
9+
"format": "iife",
10+
"name": "module"
1011
}
1112
}

crates/rolldown/tests/esbuild/dce/tree_shaking_no_bundle_iife/artifacts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ source: crates/rolldown_testing/src/integration_test.rs
66
## entry_js.mjs
77

88
```js
9-
(function() {
9+
var module = (function() {
1010
1111
1212
//#region entry.js

crates/rolldown/tests/rolldown/function/es_module/always/_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"config": {
33
"exports": "named",
44
"esModule": "always",
5-
"format": "iife"
5+
"format": "iife",
6+
"name": "module"
67
}
78
}

crates/rolldown/tests/rolldown/function/es_module/always/artifacts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ source: crates/rolldown_testing/src/integration_test.rs
66
## main.mjs
77

88
```js
9-
(function(exports) {
9+
var module = (function(exports) {
1010
1111
"use strict";
1212
Object.defineProperty(exports, '__esModule', { value: true });

crates/rolldown/tests/rolldown/function/es_module/if_default_prop_iife_false/_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"config": {
33
"exports": "named",
44
"esModule": "if-default-prop",
5-
"format": "iife"
5+
"format": "iife",
6+
"name": "module"
67
}
78
}

crates/rolldown/tests/rolldown/function/es_module/if_default_prop_iife_false/artifacts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ source: crates/rolldown_testing/src/integration_test.rs
66
## main.mjs
77

88
```js
9-
(function(exports) {
9+
var module = (function(exports) {
1010
1111
"use strict";
1212

crates/rolldown/tests/rolldown/function/es_module/if_default_prop_iife_true/_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"config": {
33
"exports": "named",
44
"esModule": "if-default-prop",
5-
"format": "iife"
5+
"format": "iife",
6+
"name": "module"
67
}
78
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy