From 0871741e981c464c210aa94ead3906dc24f3994d Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Tue, 26 Nov 2024 11:18:27 +0100 Subject: [PATCH] WIP --- cli/tools/bundle/bundle_graph.rs | 70 ++++++++++++++++++++++++++++++++ cli/tools/bundle/mod.rs | 68 ++++++++++++++++++++++--------- 2 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 cli/tools/bundle/bundle_graph.rs diff --git a/cli/tools/bundle/bundle_graph.rs b/cli/tools/bundle/bundle_graph.rs new file mode 100644 index 0000000000..dd555aa070 --- /dev/null +++ b/cli/tools/bundle/bundle_graph.rs @@ -0,0 +1,70 @@ +use std::collections::HashMap; + +use deno_ast::MediaType; +use deno_core::url::Url; +use deno_graph::{ExternalModule, JsonModule, WasmModule}; + +#[derive(Debug)] +pub struct BundleDep { + pub id: usize, + pub raw: String, + pub is_dyanmic: bool, +} + +#[derive(Debug)] +pub struct BundleJsModule { + pub specifier: Url, + pub media_type: MediaType, + pub source: String, + pub dependencies: Vec, +} + +#[derive(Debug)] +pub enum BundleMod { + Js(BundleJsModule), + Json(JsonModule), + Wasm(WasmModule), + Node(String), + External(ExternalModule), +} + +#[derive(Debug)] +pub struct BundleGraph { + id: usize, + url_to_id: HashMap, + modules: HashMap, +} + +/// The bundle graph only contains fully resolved modules. +impl BundleGraph { + pub fn new() -> Self { + Self { + id: 0, + url_to_id: HashMap::new(), + modules: HashMap::new(), + } + } + + pub fn insert(&mut self, specifier: Url, module: BundleMod) -> usize { + let id = self.register(specifier); + self.modules.insert(id, module); + id + } + + pub fn register(&mut self, specifier: Url) -> usize { + if let Some(id) = self.url_to_id.get(&specifier) { + *id + } else { + let id = self.id; + self.id += 1; + self.url_to_id.insert(specifier, id); + id + } + } + + pub fn add_dependency(&mut self, id: usize, dep: BundleDep) { + if let Some(BundleMod::Js(module)) = self.modules.get_mut(&id) { + module.dependencies.push(dep) + } + } +} diff --git a/cli/tools/bundle/mod.rs b/cli/tools/bundle/mod.rs index 12c0978bed..73b098e8c4 100644 --- a/cli/tools/bundle/mod.rs +++ b/cli/tools/bundle/mod.rs @@ -7,6 +7,7 @@ use std::{ sync::Arc, }; +use bundle_graph::{BundleDep, BundleGraph, BundleJsModule, BundleMod}; use deno_core::{anyhow::Context, error::AnyError, url::Url}; use deno_graph::{GraphKind, Module, ModuleGraph, NpmModule, Resolution}; use deno_runtime::{colors, deno_node::NodeResolver}; @@ -24,6 +25,8 @@ use crate::{ util::{fs::collect_specifiers, path::matches_pattern_or_exact_path}, }; +mod bundle_graph; + #[derive(Debug)] struct BundleChunkStat { name: PathBuf, @@ -32,23 +35,6 @@ struct BundleChunkStat { brotli: usize, } -#[derive(Debug)] -enum BundleGraphModKind { - Asset(String), - Js, - Json, - Wasm, - Node, -} - -#[derive(Debug)] -struct BundleGraphMod { - id: usize, - kind: BundleGraphModKind, - used_count: usize, - has_side_effects: bool, -} - pub async fn bundle( flags: Arc, bundle_flags: BundleFlags, @@ -87,7 +73,7 @@ pub async fn bundle( graph.valid()?; - let bundle_graph: HashMap = HashMap::new(); + let mut bundle_graph = BundleGraph::new(); let mut id = 0; let mut all_modules: HashMap = HashMap::new(); @@ -121,6 +107,8 @@ pub async fn bundle( resolved } + let mut pending_npm_dep_links: HashMap = HashMap::new(); + // Hack: Create sub graphs for every npm module we encounter and // expand npm specifiers to the actual file for module in graph.modules() { @@ -138,9 +126,49 @@ pub async fn bundle( let resolved = resolve_npm_module(&module, npm_resolver, node_resolver); npm_modules.insert(resolved.clone()); } - _ => { - all_modules.insert(url.clone(), module.clone()); + Module::Js(js_module) => { + let id = bundle_graph.insert( + url.clone(), + BundleMod::Js(BundleJsModule { + specifier: url.clone(), + media_type: js_module.media_type, + source: js_module.source.to_string(), + dependencies: vec![], + }), + ); + + for (raw, dep) in &js_module.dependencies { + if let Some(code) = dep.get_code() { + if code.scheme() == "npm" { + pending_npm_dep_links.insert(id, code.clone()); + } else { + let dep_id = bundle_graph.register(code.clone()); + bundle_graph.add_dependency( + id, + BundleDep { + id: dep_id, + raw: raw.to_string(), + is_dyanmic: dep.is_dynamic, + }, + ); + } + } + eprintln!("JS dep {} {:#?}", raw, dep); + } } + Module::Json(json_module) => { + bundle_graph.insert(url.clone(), BundleMod::Json(json_module.clone())); + } + Module::Wasm(wasm_module) => { + bundle_graph.insert(url.clone(), BundleMod::Wasm(wasm_module.clone())); + } + Module::Node(built_in_node_module) => { + bundle_graph.insert( + url.clone(), + BundleMod::Node(built_in_node_module.module_name.to_string()), + ); + } + Module::External(external_module) => todo!(), } }