mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
fix(vendor): support import mapped jsxImportSource (#19724)
Closes #16108
This commit is contained in:
parent
cd2525d4cf
commit
2e7bcb422d
5 changed files with 86 additions and 2 deletions
|
@ -28,7 +28,7 @@ use std::path::PathBuf;
|
|||
pub type MaybeImportsResult =
|
||||
Result<Vec<deno_graph::ReferrerImports>, AnyError>;
|
||||
|
||||
#[derive(Hash)]
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub struct JsxImportSourceConfig {
|
||||
pub default_specifier: Option<String>,
|
||||
pub module: String,
|
||||
|
|
52
cli/tools/vendor/build.rs
vendored
52
cli/tools/vendor/build.rs
vendored
|
@ -16,6 +16,7 @@ use deno_graph::ModuleGraph;
|
|||
use import_map::ImportMap;
|
||||
use import_map::SpecifierMap;
|
||||
|
||||
use crate::args::JsxImportSourceConfig;
|
||||
use crate::args::Lockfile;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::graph_util;
|
||||
|
@ -63,6 +64,7 @@ pub fn build(
|
|||
output_dir: &Path,
|
||||
original_import_map: Option<&ImportMap>,
|
||||
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||
jsx_import_source: Option<&JsxImportSourceConfig>,
|
||||
environment: &impl VendorEnvironment,
|
||||
) -> Result<usize, AnyError> {
|
||||
assert!(output_dir.is_absolute());
|
||||
|
@ -134,6 +136,7 @@ pub fn build(
|
|||
&all_modules,
|
||||
&mappings,
|
||||
original_import_map,
|
||||
jsx_import_source,
|
||||
parsed_source_cache,
|
||||
)?;
|
||||
environment.write_file(&import_map_path, &import_map_text)?;
|
||||
|
@ -218,6 +221,7 @@ fn build_proxy_module_source(
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::args::JsxImportSourceConfig;
|
||||
use crate::tools::vendor::test::VendorTestBuilder;
|
||||
use deno_core::serde_json::json;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
@ -1147,6 +1151,54 @@ mod test {
|
|||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn existing_import_map_jsx_import_source() {
|
||||
let mut builder = VendorTestBuilder::default();
|
||||
builder.add_entry_point("/mod.tsx");
|
||||
builder.set_jsx_import_source_config(JsxImportSourceConfig {
|
||||
default_specifier: Some("preact".to_string()),
|
||||
module: "jsx-runtime".to_string(),
|
||||
});
|
||||
let mut original_import_map = builder.new_import_map("/import_map.json");
|
||||
let imports = original_import_map.imports_mut();
|
||||
imports
|
||||
.append(
|
||||
"preact/".to_string(),
|
||||
"https://localhost/preact/".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
let output = builder
|
||||
.with_loader(|loader| {
|
||||
loader.add("/mod.tsx", "const myComponent = <div></div>;");
|
||||
loader.add_with_headers(
|
||||
"https://localhost/preact/jsx-runtime",
|
||||
"export function stuff() {}",
|
||||
&[("content-type", "application/typescript")],
|
||||
);
|
||||
})
|
||||
.set_original_import_map(original_import_map)
|
||||
.build()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
output.import_map,
|
||||
Some(json!({
|
||||
"imports": {
|
||||
"https://localhost/": "./localhost/",
|
||||
"preact/jsx-runtime": "./localhost/preact/jsx-runtime.ts",
|
||||
},
|
||||
}))
|
||||
);
|
||||
assert_eq!(
|
||||
output.files,
|
||||
to_file_vec(&[(
|
||||
"/vendor/localhost/preact/jsx-runtime.ts",
|
||||
"export function stuff() {}"
|
||||
),]),
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn vendor_file_fails_loading_dynamic_import() {
|
||||
let mut builder = VendorTestBuilder::with_default_setup();
|
||||
|
|
17
cli/tools/vendor/import_map.rs
vendored
17
cli/tools/vendor/import_map.rs
vendored
|
@ -14,6 +14,7 @@ use import_map::SpecifierMap;
|
|||
use indexmap::IndexMap;
|
||||
use log::warn;
|
||||
|
||||
use crate::args::JsxImportSourceConfig;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
|
||||
use super::mappings::Mappings;
|
||||
|
@ -182,6 +183,7 @@ pub fn build_import_map(
|
|||
modules: &[&Module],
|
||||
mappings: &Mappings,
|
||||
original_import_map: Option<&ImportMap>,
|
||||
jsx_import_source: Option<&JsxImportSourceConfig>,
|
||||
parsed_source_cache: &ParsedSourceCache,
|
||||
) -> Result<String, AnyError> {
|
||||
let mut builder = ImportMapBuilder::new(base_dir, mappings);
|
||||
|
@ -193,6 +195,21 @@ pub fn build_import_map(
|
|||
.add(base_specifier.to_string(), base_specifier);
|
||||
}
|
||||
|
||||
// add the jsx import source to the destination import map, if mapped in the original import map
|
||||
if let (Some(import_map), Some(jsx_import_source)) =
|
||||
(original_import_map, jsx_import_source)
|
||||
{
|
||||
if let Some(default_specifier) = &jsx_import_source.default_specifier {
|
||||
let specifier_text =
|
||||
format!("{}/{}", default_specifier, jsx_import_source.module);
|
||||
if let Ok(resolved_url) =
|
||||
import_map.resolve(&specifier_text, import_map.base_url())
|
||||
{
|
||||
builder.imports.add(specifier_text, &resolved_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(builder.into_import_map(original_import_map).to_json())
|
||||
}
|
||||
|
||||
|
|
2
cli/tools/vendor/mod.rs
vendored
2
cli/tools/vendor/mod.rs
vendored
|
@ -57,12 +57,14 @@ pub async fn vendor(
|
|||
let npm_package_count = graph.npm_packages.len();
|
||||
let try_add_node_modules_dir = npm_package_count > 0
|
||||
&& cli_options.node_modules_dir_enablement().unwrap_or(true);
|
||||
let jsx_import_source = cli_options.to_maybe_jsx_import_source_config();
|
||||
let vendored_count = build::build(
|
||||
graph,
|
||||
factory.parsed_source_cache()?,
|
||||
&output_dir,
|
||||
factory.maybe_import_map().await?.as_deref(),
|
||||
factory.maybe_lockfile().clone(),
|
||||
jsx_import_source.as_ref(),
|
||||
&build::RealVendorEnvironment,
|
||||
)?;
|
||||
|
||||
|
|
15
cli/tools/vendor/test.rs
vendored
15
cli/tools/vendor/test.rs
vendored
|
@ -20,6 +20,7 @@ use deno_graph::GraphKind;
|
|||
use deno_graph::ModuleGraph;
|
||||
use import_map::ImportMap;
|
||||
|
||||
use crate::args::JsxImportSourceConfig;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::npm::CliNpmRegistryApi;
|
||||
use crate::npm::NpmResolution;
|
||||
|
@ -184,6 +185,7 @@ pub struct VendorTestBuilder {
|
|||
loader: TestLoader,
|
||||
original_import_map: Option<ImportMap>,
|
||||
environment: TestVendorEnvironment,
|
||||
jsx_import_source_config: Option<JsxImportSourceConfig>,
|
||||
}
|
||||
|
||||
impl VendorTestBuilder {
|
||||
|
@ -214,6 +216,14 @@ impl VendorTestBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn set_jsx_import_source_config(
|
||||
&mut self,
|
||||
jsx_import_source_config: JsxImportSourceConfig,
|
||||
) -> &mut Self {
|
||||
self.jsx_import_source_config = Some(jsx_import_source_config);
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn build(&mut self) -> Result<VendorOutput, AnyError> {
|
||||
let output_dir = make_path("/vendor");
|
||||
let roots = self.entry_points.clone();
|
||||
|
@ -222,6 +232,7 @@ impl VendorTestBuilder {
|
|||
let analyzer = parsed_source_cache.as_analyzer();
|
||||
let graph = build_test_graph(
|
||||
roots,
|
||||
self.jsx_import_source_config.clone(),
|
||||
self.original_import_map.clone(),
|
||||
loader,
|
||||
&*analyzer,
|
||||
|
@ -233,6 +244,7 @@ impl VendorTestBuilder {
|
|||
&output_dir,
|
||||
self.original_import_map.as_ref(),
|
||||
None,
|
||||
self.jsx_import_source_config.as_ref(),
|
||||
&self.environment,
|
||||
)?;
|
||||
|
||||
|
@ -259,6 +271,7 @@ impl VendorTestBuilder {
|
|||
|
||||
async fn build_test_graph(
|
||||
roots: Vec<ModuleSpecifier>,
|
||||
jsx_import_source_config: Option<JsxImportSourceConfig>,
|
||||
original_import_map: Option<ImportMap>,
|
||||
mut loader: TestLoader,
|
||||
analyzer: &dyn deno_graph::ModuleAnalyzer,
|
||||
|
@ -271,7 +284,7 @@ async fn build_test_graph(
|
|||
None,
|
||||
));
|
||||
CliGraphResolver::new(
|
||||
None,
|
||||
jsx_import_source_config,
|
||||
Some(Arc::new(original_import_map)),
|
||||
false,
|
||||
npm_registry_api,
|
||||
|
|
Loading…
Add table
Reference in a new issue