From 03ae0f0e83c79484853f3a4ab8aa8a821c3b8a80 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 23 May 2022 12:49:28 -0400 Subject: [PATCH] fix(vendor): handle relative imports when mapped local folder name differs from remote's (#14465) --- cli/tools/vendor/build.rs | 15 +++++++--- cli/tools/vendor/import_map.rs | 52 +++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/cli/tools/vendor/build.rs b/cli/tools/vendor/build.rs index 0e42edb4ac..dd362ebfbb 100644 --- a/cli/tools/vendor/build.rs +++ b/cli/tools/vendor/build.rs @@ -628,10 +628,14 @@ mod test { .add("/mod.ts", "import 'https://localhost/mod.ts';") .add( "https://localhost/mod.ts", - "import './npm:test@1.0.0/test/test!cjs';", + "import './npm:test@1.0.0/test/test!cjs?test';import './npm:test@1.0.0/mod.ts';", + ) + .add( + "https://localhost/npm:test@1.0.0/mod.ts", + "console.log(4);", ) .add_with_headers( - "https://localhost/npm:test@1.0.0/test/test!cjs", + "https://localhost/npm:test@1.0.0/test/test!cjs?test", "console.log(5);", &[("content-type", "application/javascript")], ); @@ -648,7 +652,9 @@ mod test { }, "scopes": { "./localhost/": { - "./localhost/npm:test@1.0.0/test/test!cjs": "./localhost/npm_test@1.0.0/test/test!cjs.js" + "./localhost/npm:test@1.0.0/mod.ts": "./localhost/npm_test@1.0.0/mod.ts", + "./localhost/npm:test@1.0.0/test/test!cjs?test": "./localhost/npm_test@1.0.0/test/test!cjs.js", + "./localhost/npm_test@1.0.0/test/test!cjs?test": "./localhost/npm_test@1.0.0/test/test!cjs.js" } } })) @@ -658,8 +664,9 @@ mod test { to_file_vec(&[ ( "/vendor/localhost/mod.ts", - "import './npm:test@1.0.0/test/test!cjs';" + "import './npm:test@1.0.0/test/test!cjs?test';import './npm:test@1.0.0/mod.ts';" ), + ("/vendor/localhost/npm_test@1.0.0/mod.ts", "console.log(4);"), ( "/vendor/localhost/npm_test@1.0.0/test/test!cjs.js", "console.log(5);" diff --git a/cli/tools/vendor/import_map.rs b/cli/tools/vendor/import_map.rs index 4bbdbd1ae1..1b2a2e2634 100644 --- a/cli/tools/vendor/import_map.rs +++ b/cli/tools/vendor/import_map.rs @@ -86,12 +86,14 @@ impl<'a> ImportsBuilder<'a> { } pub fn add(&mut self, key: String, specifier: &ModuleSpecifier) { - self.imports.insert( - key, - self - .mappings - .relative_specifier_text(self.mappings.output_dir(), specifier), - ); + let value = self + .mappings + .relative_specifier_text(self.mappings.output_dir(), specifier); + + // skip creating identity entries + if key != value { + self.imports.insert(key, value); + } } } @@ -221,7 +223,8 @@ fn handle_dep_specifier( return; } - let key = if text.starts_with("./") || text.starts_with("../") { + let imports = import_map.scope(base_specifier); + if text.starts_with("./") || text.starts_with("../") { // resolve relative specifier key let mut local_base_specifier = mappings.local_uri(base_specifier); local_base_specifier.set_query(unresolved_specifier.query()); @@ -236,14 +239,37 @@ fn handle_dep_specifier( ) }); local_base_specifier.set_query(unresolved_specifier.query()); - mappings - .relative_specifier_text(mappings.output_dir(), &local_base_specifier) + + imports.add( + mappings.relative_specifier_text( + mappings.output_dir(), + &local_base_specifier, + ), + &specifier, + ); + + // add a mapping that uses the local directory name and the remote + // filename in order to support files importing this relatively + imports.add( + { + let local_path = mappings.local_path(&specifier); + let mut value = + ModuleSpecifier::from_directory_path(local_path.parent().unwrap()) + .unwrap(); + value.set_query(specifier.query()); + value.set_path(&format!( + "{}{}", + value.path(), + specifier.path_segments().unwrap().last().unwrap(), + )); + mappings.relative_specifier_text(mappings.output_dir(), &value) + }, + &specifier, + ); } else { // absolute (`/`) or bare specifier should be left as-is - text.to_string() - }; - let imports = import_map.scope(base_specifier); - imports.add(key, &specifier); + imports.add(text.to_string(), &specifier); + } } }