1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-22 15:10:44 -05:00
denoland-deno/cli/tools/bundle.rs
Bartek Iwańczuk 48ede89f1f
refactor(core): resolve_url_or_path and resolve_url_or_path_deprecated (#18170)
This commit changes current "deno_core::resolve_url_or_path" API to
"resolve_url_or_path_deprecated" and adds new "resolve_url_or_path"
API that requires to explicitly pass the directory from which paths
should be resolved to. 

Some of the call sites were updated to use the new API, the reminder
of them will be updated in a follow up PR.

Towards landing https://github.com/denoland/deno/pull/15454
2023-03-14 01:12:09 +00:00

173 lines
5.1 KiB
Rust

// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::path::PathBuf;
use std::sync::Arc;
use deno_core::error::AnyError;
use deno_core::futures::FutureExt;
use deno_core::resolve_url_or_path_deprecated;
use deno_graph::Module;
use deno_runtime::colors;
use crate::args::BundleFlags;
use crate::args::CliOptions;
use crate::args::Flags;
use crate::args::TsConfigType;
use crate::args::TypeCheckMode;
use crate::graph_util::create_graph_and_maybe_check;
use crate::graph_util::error_for_any_npm_specifier;
use crate::proc_state::ProcState;
use crate::util;
use crate::util::display;
use crate::util::file_watcher::ResolutionResult;
pub async fn bundle(
flags: Flags,
bundle_flags: BundleFlags,
) -> Result<(), AnyError> {
let cli_options = Arc::new(CliOptions::from_flags(flags)?);
log::info!(
"{} \"deno bundle\" is deprecated and will be removed in the future.",
colors::yellow("Warning"),
);
log::info!(
"Use alternative bundlers like \"deno_emit\", \"esbuild\" or \"rollup\" instead."
);
let resolver = |_| {
let cli_options = cli_options.clone();
let source_file1 = &bundle_flags.source_file;
let source_file2 = &bundle_flags.source_file;
async move {
let module_specifier = resolve_url_or_path_deprecated(source_file1)?;
log::debug!(">>>>> bundle START");
let ps = ProcState::from_options(cli_options).await?;
let graph = create_graph_and_maybe_check(module_specifier, &ps).await?;
let mut paths_to_watch: Vec<PathBuf> = graph
.specifiers()
.filter_map(|(_, r)| {
r.ok().and_then(|module| match module {
Module::Esm(m) => m.specifier.to_file_path().ok(),
Module::Json(m) => m.specifier.to_file_path().ok(),
// nothing to watch
Module::Node(_) | Module::Npm(_) | Module::External(_) => None,
})
})
.collect();
if let Ok(Some(import_map_path)) = ps
.options
.resolve_import_map_specifier()
.map(|ms| ms.and_then(|ref s| s.to_file_path().ok()))
{
paths_to_watch.push(import_map_path);
}
Ok((paths_to_watch, graph, ps))
}
.map(move |result| match result {
Ok((paths_to_watch, graph, ps)) => ResolutionResult::Restart {
paths_to_watch,
result: Ok((ps, graph)),
},
Err(e) => ResolutionResult::Restart {
paths_to_watch: vec![PathBuf::from(source_file2)],
result: Err(e),
},
})
};
let operation = |(ps, graph): (ProcState, Arc<deno_graph::ModuleGraph>)| {
let out_file = &bundle_flags.out_file;
async move {
// at the moment, we don't support npm specifiers in deno bundle, so show an error
error_for_any_npm_specifier(&graph)?;
let bundle_output = bundle_module_graph(graph.as_ref(), &ps)?;
log::debug!(">>>>> bundle END");
if let Some(out_file) = out_file {
let output_bytes = bundle_output.code.as_bytes();
let output_len = output_bytes.len();
util::fs::write_file(out_file, output_bytes, 0o644)?;
log::info!(
"{} {:?} ({})",
colors::green("Emit"),
out_file,
colors::gray(display::human_size(output_len as f64))
);
if let Some(bundle_map) = bundle_output.maybe_map {
let map_bytes = bundle_map.as_bytes();
let map_len = map_bytes.len();
let ext = if let Some(curr_ext) = out_file.extension() {
format!("{}.map", curr_ext.to_string_lossy())
} else {
"map".to_string()
};
let map_out_file = out_file.with_extension(ext);
util::fs::write_file(&map_out_file, map_bytes, 0o644)?;
log::info!(
"{} {:?} ({})",
colors::green("Emit"),
map_out_file,
colors::gray(display::human_size(map_len as f64))
);
}
} else {
println!("{}", bundle_output.code);
}
Ok(())
}
};
if cli_options.watch_paths().is_some() {
util::file_watcher::watch_func(
resolver,
operation,
util::file_watcher::PrintConfig {
job_name: "Bundle".to_string(),
clear_screen: !cli_options.no_clear_screen(),
},
)
.await?;
} else {
let module_graph =
if let ResolutionResult::Restart { result, .. } = resolver(None).await {
result?
} else {
unreachable!();
};
operation(module_graph).await?;
}
Ok(())
}
fn bundle_module_graph(
graph: &deno_graph::ModuleGraph,
ps: &ProcState,
) -> Result<deno_emit::BundleEmit, AnyError> {
log::info!("{} {}", colors::green("Bundle"), graph.roots[0]);
let ts_config_result = ps
.options
.resolve_ts_config_for_emit(TsConfigType::Bundle)?;
if ps.options.type_check_mode() == TypeCheckMode::None {
if let Some(ignored_options) = ts_config_result.maybe_ignored_options {
log::warn!("{}", ignored_options);
}
}
deno_emit::bundle_graph(
graph,
deno_emit::BundleOptions {
bundle_type: deno_emit::BundleType::Module,
emit_options: ts_config_result.ts_config.into(),
emit_ignore_directives: true,
},
)
}