Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitedf5b4e

Browse files
fix: exported dynamic import is treated as unused (#4648)
<!-- Thank you for contributing! -->### Description1.Closed#4646<!-- Please insert your description here and provide especially infoabout the "what" this PR is solving -->
1 parent701bbc3 commitedf5b4e

File tree

11 files changed

+130
-7
lines changed

11 files changed

+130
-7
lines changed

‎crates/rolldown/src/ast_scanner/dynamic_import.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,28 @@ impl<'me, 'ast: 'me> AstScanner<'me, 'ast> {
100100
&mutself,
101101
import_record_idx:ImportRecordIdx,
102102
) ->Option<std::collections::HashSet<CompactStr, rustc_hash::FxBuildHasher>>{
103-
letremove_paren =self
103+
letast_after_remove_paren_idx =self
104104
.visit_path
105105
.iter()
106-
.rev()
107106
.skip(1)
108-
.find(|kind| !matches!(kind,AstKind::ParenthesizedExpression(_)))?;
109-
match remove_paren{
107+
.rposition(|kind| !matches!(kind,AstKind::ParenthesizedExpression(_)))?;
108+
// ast_after_remove_paren_idx the index is find from `visit_path`
109+
#[allow(clippy::match_on_vec_items)]
110+
matchself.visit_path[ast_after_remove_paren_idx]{
110111
// 1. const mod = await import('mod'); console.log(mod)
111112
// 2. const {a} = await import('mod'); a.something;
112113
AstKind::VariableDeclarator(var_decl) =>{
113-
self.update_dynamic_import_usage_info_from_binding_pattern(&var_decl.id, import_record_idx)
114+
// parent of varDeclarator should be varDeclaration, so we should look for the parent of
115+
// parent
116+
let is_exported =matches!(
117+
self.visit_path.get(ast_after_remove_paren_idx.saturating_sub(2)),
118+
Some(AstKind::ExportDefaultDeclaration(_) |AstKind::ExportNamedDeclaration(_))
119+
);
120+
self.update_dynamic_import_usage_info_from_binding_pattern(
121+
&var_decl.id,
122+
import_record_idx,
123+
is_exported,
124+
)
114125
}
115126
// 3. await import('mod');
116127
// only side effects from `mod` is triggered
@@ -155,16 +166,23 @@ impl<'me, 'ast: 'me> AstScanner<'me, 'ast> {
155166
self.update_dynamic_import_usage_info_from_binding_pattern(
156167
&dynamic_import_binding.pattern,
157168
import_record_id,
169+
false,
158170
)
159171
}
160172

161173
fnupdate_dynamic_import_usage_info_from_binding_pattern(
162174
&mutself,
163175
binding_pattern:&ast::BindingPattern<'_>,
164176
import_record_id:ImportRecordIdx,
177+
is_exported:bool,
165178
) ->Option<FxHashSet<CompactStr>>{
166179
let symbol_id =match&binding_pattern.kind{
167-
ast::BindingPatternKind::BindingIdentifier(id) => id.symbol_id(),
180+
ast::BindingPatternKind::BindingIdentifier(id) =>{
181+
if is_exported{
182+
returnNone;
183+
}
184+
id.symbol_id()
185+
}
168186
// only care about first level destructuring, if it is nested just assume it is used
169187
ast::BindingPatternKind::ObjectPattern(obj) =>{
170188
letmut set =FxHashSet::default();
@@ -189,7 +207,7 @@ impl<'me, 'ast: 'me> AstScanner<'me, 'ast> {
189207
.scoping()
190208
.get_resolved_reference_ids(binding_symbol_id)
191209
.is_empty();
192-
if is_used{
210+
ifis_exported ||is_used{
193211
set.insert(binding_name.into());
194212
}
195213
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
source:crates/rolldown_testing/src/integration_test.rs
3+
---
4+
#Assets
5+
6+
##d1.js
7+
8+
```js
9+
//#region d1.js
10+
const a = "d1a";
11+
12+
//#endregion
13+
export{a};
14+
```
15+
##d2.js
16+
17+
```js
18+
//#region d2.js
19+
const a = "d2a";
20+
const b = "d2b";
21+
22+
//#endregion
23+
export{a,b};
24+
```
25+
##d3.js
26+
27+
```js
28+
//#region d3.js
29+
const a = "d3a";
30+
const b = "d3b";
31+
32+
//#endregion
33+
export{a,b};
34+
```
35+
##d4.js
36+
37+
```js
38+
//#region d4.js
39+
const a = "d4a";
40+
const b = "d4b";
41+
42+
//#endregion
43+
export{a,b};
44+
```
45+
##d5.js
46+
47+
```js
48+
//#region d5.js
49+
const a = "d5a";
50+
51+
//#endregion
52+
export{a};
53+
```
54+
##main.js
55+
56+
```js
57+
//#region main.js
58+
const{a} = await import("./d1.js");
59+
var main_default = await import("./d2.js");
60+
const d3 = await import("./d3.js");
61+
const d4 = () => import("./d4.js");
62+
const d5 = () => import("./d5.js").then((mod) =>{
63+
mod.a;
64+
});
65+
66+
//#endregion
67+
export{a,d3,d4,d5,main_defaultasdefault};
68+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
exportconsta='d1a';
2+
exportconstb='d1b';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
exportconsta='d2a';
2+
exportconstb='d2b';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
exportconsta='d3a';
2+
exportconstb='d3b';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
exportconsta='d4a';
2+
exportconstb='d4b';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
exportconsta='d5a';
2+
exportconstb='d5b';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// should only include a in d1.js
2+
exportconst{ a}=awaitimport('./d1.js')
3+
// should include all in d2.js
4+
exportdefaultawaitimport('./d2.js')
5+
6+
// should include all in d3.js
7+
exportconstd3=awaitimport('./d3.js')
8+
9+
// should include all in d4.js
10+
exportconstd4=()=>import('./d4.js')
11+
12+
// should include all in d5.js
13+
exportconstd5=()=>import('./d5.js').then(mod=>{
14+
mod.a
15+
})

‎crates/rolldown/tests/snapshots/integration_rolldown__filename_with_hash.snap

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5505,6 +5505,15 @@ expression: output
55055505
55065506
- main-!~{000}~.js => main-DnyIjeNr.js
55075507
5508+
# tests/rolldown/tree_shaking/issue_4646
5509+
5510+
- main-!~{000}~.js => main-DJ0xXmIa.js
5511+
- d1-!~{001}~.js => d1-DT1jtzoH.js
5512+
- d2-!~{003}~.js => d2-BUM4Zp6g.js
5513+
- d3-!~{005}~.js => d3-DDbIMCn7.js
5514+
- d4-!~{007}~.js => d4-DGCApdvO.js
5515+
- d5-!~{009}~.js => d5-BG99yqGu.js
5516+
55085517
# tests/rolldown/tree_shaking/json_module_def_format
55095518
55105519
- main-!~{000}~.js => main-Cp4dwvDl.js

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp