Skip to content

Commit

Permalink
feat: add OutputChunk modules (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
underfin authored Nov 13, 2023
1 parent 413beb7 commit ccf06fe
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 13 deletions.
4 changes: 3 additions & 1 deletion crates/rolldown/src/bundler/bundle/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ impl<'a> Bundle<'a> {
.iter()
.enumerate()
.map(|(_chunk_id, c)| {
let content = c.render(self.graph, &chunk_graph, self.output_options).unwrap();
let (content, rendered_modules) =
c.render(self.graph, &chunk_graph, self.output_options).unwrap();

Output::Chunk(Box::new(OutputChunk {
file_name: c.file_name.clone().unwrap(),
Expand All @@ -295,6 +296,7 @@ impl<'a> Bundle<'a> {
facade_module_id: c
.entry_module
.map(|id| self.graph.modules[id].expect_normal().resource_id.prettify().to_string()),
modules: rendered_modules,
}))
})
.collect::<Vec<_>>();
Expand Down
10 changes: 10 additions & 0 deletions crates/rolldown/src/bundler/bundle/output.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
use rustc_hash::FxHashMap;

#[derive(Debug)]
pub struct RenderedModule {
// The code of the module is omit at now.
pub original_length: u32,
pub rendered_length: u32,
}

#[derive(Debug)]
pub struct OutputChunk {
pub file_name: String,
pub code: String,
pub is_entry: bool,
pub facade_module_id: Option<String>,
pub modules: FxHashMap<String, RenderedModule>,
}

#[derive(Debug)]
Expand Down
31 changes: 24 additions & 7 deletions crates/rolldown/src/bundler/chunk/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use string_wizard::{Joiner, JoinerOptions};

use crate::{
bundler::{
bundle::output::RenderedModule,
chunk_graph::ChunkGraph,
graph::graph::Graph,
module::ModuleRenderContext,
Expand Down Expand Up @@ -60,34 +61,50 @@ impl Chunk {
self.file_name = Some(pat.render(&FileNameRenderOptions { name: self.name.as_deref() }));
}

#[allow(clippy::unnecessary_wraps)]
#[allow(clippy::unnecessary_wraps, clippy::cast_possible_truncation)]
pub fn render(
&self,
graph: &Graph,
chunk_graph: &ChunkGraph,
output_options: &OutputOptions,
) -> BatchedResult<String> {
) -> BatchedResult<(String, FxHashMap<String, RenderedModule>)> {
use rayon::prelude::*;
let mut rendered_modules = FxHashMap::default();
let mut joiner = Joiner::with_options(JoinerOptions { separator: Some("\n".to_string()) });
joiner.append(self.render_imports_for_esm(graph, chunk_graph));
self
.modules
.par_iter()
.copied()
.map(|id| &graph.modules[id])
.filter_map(|m| {
m.render(ModuleRenderContext { canonical_names: &self.canonical_names, graph, chunk_graph })
.map(|m| {
let rendered_content = m.render(ModuleRenderContext {
canonical_names: &self.canonical_names,
graph,
chunk_graph,
});
(
m.resource_id().prettify().to_string(),
RenderedModule {
original_length: m.original_length(),
rendered_length: rendered_content.as_ref().map(|c| c.len() as u32).unwrap_or_default(),
},
rendered_content,
)
})
.collect::<Vec<_>>()
.into_iter()
.for_each(|item| {
joiner.append(item);
.for_each(|(module_path, rendered_module, rendered_content)| {
if let Some(rendered_content) = rendered_content {
joiner.append(rendered_content);
}
rendered_modules.insert(module_path, rendered_module);
});

if let Some(exports) = self.render_exports(graph, output_options) {
joiner.append(exports);
}

Ok(joiner.join())
Ok((joiner.join(), rendered_modules))
}
}
17 changes: 16 additions & 1 deletion crates/rolldown/src/bundler/module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod normal_module_builder;
use index_vec::IndexVec;
pub use normal_module::NormalModule;
use oxc::span::Atom;
use rolldown_common::{ImportRecord, ImportRecordId, ModuleId, SymbolRef};
use rolldown_common::{ImportRecord, ImportRecordId, ModuleId, ResourceId, SymbolRef};
use rustc_hash::FxHashMap;
use string_wizard::MagicString;

Expand Down Expand Up @@ -76,6 +76,21 @@ impl Module {
Self::External(_) => None,
}
}

#[allow(clippy::cast_possible_truncation)]
pub fn original_length(&self) -> u32 {
match self {
Self::Normal(m) => m.ast.source().len() as u32,
Self::External(_) => 0,
}
}

pub fn resource_id(&self) -> &ResourceId {
match self {
Self::Normal(m) => &m.resource_id,
Self::External(m) => &m.resource_id,
}
}
}

pub struct ModuleRenderContext<'a> {
Expand Down
2 changes: 1 addition & 1 deletion crates/rolldown/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub(crate) type SharedResolver<T> = Arc<Resolver<T>>;

pub use crate::{
bundler::{
bundle::output::{Output, OutputAsset, OutputChunk},
bundle::output::{Output, OutputAsset, OutputChunk, RenderedModule},
bundler::Bundler,
options::{
file_name_template::FileNameTemplate,
Expand Down
8 changes: 8 additions & 0 deletions crates/rolldown_binding/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,19 @@ export interface OutputOptions {
exports?: 'default' | 'named' | 'none' | 'auto'
format?: 'esm' | 'cjs'
}
export interface RenderedModule {
code?: string | null
removedExports: Array<string>
renderedExports: Array<string>
originalLength: number
renderedLength: number
}
export interface OutputChunk {
code: string
fileName: string
isEntry: boolean
facadeModuleId?: string
modules: Record<string, RenderedModule>
}
export interface OutputAsset {
fileName: string
Expand Down
30 changes: 30 additions & 0 deletions crates/rolldown_binding/src/output.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
use std::collections::HashMap;

use derivative::Derivative;
use serde::Deserialize;

#[napi_derive::napi(object)]
#[derive(Deserialize, Default, Derivative)]
#[serde(rename_all = "camelCase")]
#[derivative(Debug)]
pub struct RenderedModule {
pub code: Option<String>,
// TODO
pub removed_exports: Vec<String>,
// TODO
pub rendered_exports: Vec<String>,
pub original_length: u32,
pub rendered_length: u32,
}

impl From<rolldown::RenderedModule> for RenderedModule {
fn from(value: rolldown::RenderedModule) -> Self {
Self {
code: None,
original_length: value.original_length,
rendered_length: value.rendered_length,
removed_exports: vec![],
rendered_exports: vec![],
}
}
}

#[napi_derive::napi(object)]
#[derive(Deserialize, Default, Derivative)]
#[serde(rename_all = "camelCase")]
Expand All @@ -10,6 +38,7 @@ pub struct OutputChunk {
pub file_name: String,
pub is_entry: bool,
pub facade_module_id: Option<String>,
pub modules: HashMap<String, RenderedModule>,
}

impl From<Box<rolldown::OutputChunk>> for OutputChunk {
Expand All @@ -19,6 +48,7 @@ impl From<Box<rolldown::OutputChunk>> for OutputChunk {
file_name: chunk.file_name,
is_entry: chunk.is_entry,
facade_module_id: chunk.facade_module_id,
modules: chunk.modules.into_iter().map(|(key, value)| (key, value.into())).collect(),
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions packages/node/src/utils/transform-to-rollup-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ function transformToRollupOutputChunk(chunk: OutputChunk): RollupOutputChunk {
type: 'chunk',
code: chunk.code,
fileName: chunk.fileName,
// @ts-expect-error undefined can't assign to null
modules: chunk.modules,
get dynamicImports() {
return unimplemented()
},
Expand All @@ -24,9 +26,6 @@ function transformToRollupOutputChunk(chunk: OutputChunk): RollupOutputChunk {
get imports() {
return unimplemented()
},
get modules() {
return unimplemented()
},
get referencedFiles() {
return unimplemented()
},
Expand Down

0 comments on commit ccf06fe

Please sign in to comment.