Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0c1e164

Browse files
authored
feat: create cross-chunk links for runtime module and facade symbols (#114)
* feat: create cross-chunk links for runtime module and facade symbols * comments * Update failed tests
1 parent ef8ed1a commit 0c1e164

48 files changed

Lines changed: 196 additions & 26 deletions

File tree

Some content is hidden

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

crates/rolldown/src/bundler/bundle/bundle.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ impl<'a> Bundle<'a> {
7070

7171
for stmt_info in module.stmt_infos.iter().chain(linking_info.facade_stmt_infos.iter()) {
7272
for declared in &stmt_info.declared_symbols {
73+
// TODO: pass debug_assert!(self.graph.symbols.get(*declared).chunk_id.is_none());
74+
// FIXME: I don't think this is correct, even though the assigned chunk_id is the same as the current chunk_id.
75+
// A declared symbol should only be processed once.
76+
debug_assert!(
77+
self.graph.symbols.get(*declared).chunk_id.unwrap_or(chunk_id) == chunk_id
78+
);
79+
7380
self.graph.symbols.get_mut(*declared).chunk_id = Some(chunk_id);
7481
}
7582

@@ -98,11 +105,13 @@ impl<'a> Bundle<'a> {
98105
}
99106
}
100107
}
101-
102108
for (chunk_id, chunk) in chunk_graph.chunks.iter_mut_enumerated() {
103109
let chunk_meta_imports = &chunk_meta_imports_vec[chunk_id];
104110
for import_ref in chunk_meta_imports.iter().copied() {
105-
let importee_chunk_id = self.graph.symbols.get(import_ref).chunk_id.unwrap();
111+
let import_symbol = self.graph.symbols.get(import_ref);
112+
let importee_chunk_id = import_symbol.chunk_id.unwrap_or_else(|| {
113+
panic!("symbol {import_ref:?} {import_symbol:?} is not assigned to any chunk")
114+
});
106115
if chunk_id != importee_chunk_id {
107116
chunk
108117
.imports_from_other_chunks
@@ -168,6 +177,14 @@ impl<'a> Bundle<'a> {
168177
FxHashMap::with_capacity_and_hasher(self.graph.entries.len(), BuildHasherDefault::default());
169178
let mut chunks = ChunksVec::with_capacity(self.graph.entries.len());
170179

180+
// FIXME: should only do this while `ROLLDOWN_TEST=1`
181+
let _runtime_chunk_id = chunks.push(Chunk::new(
182+
Some("_rolldown_runtime".to_string()),
183+
None,
184+
BitSet::new(0),
185+
vec![self.graph.runtime.id],
186+
));
187+
171188
// Create chunk for each static and dynamic entry
172189
for (entry_index, (name, module_id)) in self.graph.entries.iter().enumerate() {
173190
let count: u32 = u32::try_from(entry_index).unwrap();

crates/rolldown/src/bundler/chunk/render_chunk_imports.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl Chunk {
3131
.collect::<Vec<_>>();
3232
import_items.sort();
3333
s.append(format!(
34-
"import {{ {} }} from \"./{}\";",
34+
"import {{ {} }} from \"./{}\";\n",
3535
import_items.join(", "),
3636
chunk.file_name.as_ref().unwrap()
3737
));

crates/rolldown/src/bundler/graph/linker.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ impl<'graph> Linker<'graph> {
160160
linking_infos: &mut LinkingInfoVec,
161161
) {
162162
let linking_info = &mut linking_infos[target];
163+
if let Module::Normal(module) = &self.graph.modules[target] {
164+
module.initialize_namespace(linking_info);
165+
}
163166
if linking_info.wrap_symbol.is_some() {
164167
return;
165168
}
@@ -170,6 +173,7 @@ impl<'graph> Linker<'graph> {
170173
match &self.graph.modules[target] {
171174
Module::Normal(module) => {
172175
module.create_wrap_symbol(linking_info, symbols);
176+
173177
let name = if module.exports_kind == ExportsKind::CommonJs {
174178
"__commonJS".into()
175179
} else {
@@ -187,13 +191,25 @@ impl<'graph> Linker<'graph> {
187191

188192
#[allow(clippy::needless_collect)]
189193
fn mark_extra_symbols(&mut self, symbols: &mut Symbols, linking_infos: &mut LinkingInfoVec) {
190-
for id in &self.graph.sorted_modules {
191-
let importer = &self.graph.modules[*id];
194+
// Determine if the namespace symbol need to be generated
195+
for importer_id in &self.graph.sorted_modules {
196+
let importer = &self.graph.modules[*importer_id];
197+
198+
if let Module::Normal(importer) = importer {
199+
let has_reexport_all_from_cjs = importer.get_star_exports_modules().any(|importee| matches!(&self.graph.modules[importee], Module::Normal(m) if m.exports_kind == ExportsKind::CommonJs));
200+
if has_reexport_all_from_cjs {
201+
self.graph.modules[*importer_id]
202+
.mark_symbol_for_namespace_referenced(&mut linking_infos[*importer_id]);
203+
}
204+
}
205+
192206
importer
193207
.import_records()
194208
.iter()
195209
.filter_map(|rec| {
196-
(rec.is_import_namespace && rec.resolved_module.is_valid()).then_some(rec.resolved_module)
210+
((rec.is_import_namespace || matches!(rec.kind, ImportKind::Require))
211+
&& rec.resolved_module.is_valid())
212+
.then_some(rec.resolved_module)
197213
})
198214
.for_each(|importee| {
199215
self.graph.modules[importee]

crates/rolldown/src/bundler/graph/symbols.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ impl Symbols {
7676
Self { inner, references_table: reference_table }
7777
}
7878

79+
pub fn create_facade_symbol(&mut self, owner: ModuleId) -> SymbolRef {
80+
let symbol_id = self.inner[owner].push(Symbol {
81+
// name is meaningless for facade symbols
82+
name: Atom::new_inline("#FACADE#"),
83+
link: None,
84+
chunk_id: None,
85+
namespace_alias: None,
86+
});
87+
let symbol_ref = SymbolRef { owner, symbol: symbol_id };
88+
self.references_table[owner].push(Some(symbol_id));
89+
symbol_ref
90+
}
91+
7992
pub fn create_symbol(&mut self, owner: ModuleId, name: Atom) -> SymbolRef {
8093
let symbol_id =
8194
self.inner[owner].push(Symbol { name, link: None, chunk_id: None, namespace_alias: None });

crates/rolldown/src/bundler/module/normal_module.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,25 @@ impl NormalModule {
333333

334334
pub fn generate_symbol_import_and_use(
335335
&self,
336-
symbol_ref_from_importee: SymbolRef,
336+
other_module_symbol_ref: SymbolRef,
337337
self_linking_info: &mut LinkingInfo,
338338
symbols: &mut Symbols,
339339
) {
340-
debug_assert!(symbol_ref_from_importee.owner != self.id);
341-
let name = symbols.get_original_name(symbol_ref_from_importee).clone();
342-
let local_symbol_ref = self.generate_local_symbol(name, self_linking_info, symbols);
343-
symbols.union(local_symbol_ref, symbol_ref_from_importee);
340+
debug_assert!(other_module_symbol_ref.owner != self.id);
341+
// Create a facade symbol belongs to the self module.
342+
let facade_ref = symbols.create_facade_symbol(self.id);
343+
// The facade symbol is used to reference the symbol from the other module.
344+
symbols.union(facade_ref, other_module_symbol_ref);
345+
346+
self_linking_info.facade_stmt_infos.push(StmtInfo {
347+
// Since the facade symbol is created, it should be declared. This will be used to
348+
// 1. de-conflict the symbol in the de-conflict pass
349+
declared_symbols: vec![facade_ref],
350+
// Since the facade symbol is used, it should be referenced. This will be used to
351+
// create correct cross-chunk links
352+
referenced_symbols: vec![facade_ref],
353+
..Default::default()
354+
});
344355
}
345356

346357
pub fn generate_local_symbol(

crates/rolldown/src/bundler/visitors/mod.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,8 @@ impl<'ast> RendererContext<'ast> {
3939
) -> Self {
4040
let wrap_symbol_name =
4141
linking_info.wrap_symbol.and_then(|s| get_symbol_final_name(s, &graph.symbols, final_names));
42-
let namespace_symbol_name = get_symbol_final_name(
43-
(module.id, module.namespace_symbol.symbol).into(),
44-
&graph.symbols,
45-
final_names,
46-
);
42+
let namespace_symbol_name =
43+
get_symbol_final_name(module.namespace_symbol, &graph.symbols, final_names);
4744
let default_symbol_name = module
4845
.default_export_symbol
4946
.and_then(|s| get_symbol_final_name((module.id, s).into(), &graph.symbols, final_names));
@@ -266,9 +263,7 @@ impl<'ast> RendererContext<'ast> {
266263
if importee.exports_kind == ExportsKind::CommonJs {
267264
self.source.update(expr.span.start, expr.span.end, format!("{wrap_symbol_name}()"));
268265
} else {
269-
let namespace_name = self
270-
.get_symbol_final_name((importee.id, importee.namespace_symbol.symbol).into())
271-
.unwrap();
266+
let namespace_name = self.get_symbol_final_name(importee.namespace_symbol).unwrap();
272267
let to_commonjs_runtime_symbol_name =
273268
self.get_runtime_symbol_final_name(&"__toCommonJS".into());
274269
self.source.update(

crates/rolldown/tests/common/case.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ impl Case {
2727
assets.sort_by_key(|c| c.file_name.clone());
2828
assets
2929
.iter()
30+
// FIXME: should render the runtime module while tree shaking being supported
31+
.filter(|asset| !asset.file_name.contains("rolldown_runtime"))
3032
.flat_map(|asset| {
3133
[
3234
Cow::Owned(format!("# {}\n", asset.file_name)),

crates/rolldown/tests/esbuild/default/common_js_from_es6/artifacts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ input_file: crates/rolldown/tests/esbuild/default/common_js_from_es6
66
# entry_js.js
77

88
```js
9+
import { __esm, __toCommonJS } from "./_rolldown_runtime.js";
10+
911
// bar.js
1012
function bar$1() {
1113
return 'bar'

crates/rolldown/tests/esbuild/default/empty_export_clause_bundle_as_common_js_issue910/artifacts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ input_file: crates/rolldown/tests/esbuild/default/empty_export_clause_bundle_as_
66
# entry_js.js
77

88
```js
9+
import { __esm, __toCommonJS } from "./_rolldown_runtime.js";
10+
911
// types.mjs
1012
var types_ns = {
1113

crates/rolldown/tests/esbuild/default/es6_from_common_js/artifacts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ input_file: crates/rolldown/tests/esbuild/default/es6_from_common_js
66
# entry_js.js
77

88
```js
9+
import { __commonJS, __toESM } from "./_rolldown_runtime.js";
10+
911
// bar.js
1012
var require_bar = __commonJS({
1113
'bar.js'(exports, module) {

0 commit comments

Comments
 (0)