mirror of
https://github.com/denoland/deno.git
synced 2024-12-21 23:04:45 -05:00
fix: Make npm packages works with import maps (#16754)
Co-authored-by: David Sherret <dsherret@gmail.com>
This commit is contained in:
parent
f077c4f248
commit
b70f520ebc
5 changed files with 81 additions and 5 deletions
|
@ -32,8 +32,12 @@ impl NpmPackageReference {
|
|||
}
|
||||
|
||||
pub fn from_str(specifier: &str) -> Result<NpmPackageReference, AnyError> {
|
||||
let original_text = specifier;
|
||||
let specifier = match specifier.strip_prefix("npm:") {
|
||||
Some(s) => s,
|
||||
Some(s) => {
|
||||
// Strip leading slash, which might come from import map
|
||||
s.strip_prefix('/').unwrap_or(s)
|
||||
}
|
||||
None => {
|
||||
// don't allocate a string here and instead use a static string
|
||||
// because this is hit a lot when a url is not an npm specifier
|
||||
|
@ -65,7 +69,12 @@ impl NpmPackageReference {
|
|||
let sub_path = if parts.len() == name_parts.len() {
|
||||
None
|
||||
} else {
|
||||
Some(parts[name_part_len..].join("/"))
|
||||
let sub_path = parts[name_part_len..].join("/");
|
||||
if sub_path.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(sub_path)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(sub_path) = &sub_path {
|
||||
|
@ -79,6 +88,14 @@ impl NpmPackageReference {
|
|||
}
|
||||
}
|
||||
|
||||
if name.is_empty() {
|
||||
let msg = format!(
|
||||
"Invalid npm specifier '{}'. Did not contain a package name.",
|
||||
original_text
|
||||
);
|
||||
return Err(generic_error(msg));
|
||||
}
|
||||
|
||||
Ok(NpmPackageReference {
|
||||
req: NpmPackageReq { name, version_req },
|
||||
sub_path,
|
||||
|
@ -631,6 +648,54 @@ mod tests {
|
|||
.to_string(),
|
||||
"Not a valid package: @package"
|
||||
);
|
||||
|
||||
// should parse leading slash
|
||||
assert_eq!(
|
||||
NpmPackageReference::from_str("npm:/@package/test/sub_path").unwrap(),
|
||||
NpmPackageReference {
|
||||
req: NpmPackageReq {
|
||||
name: "@package/test".to_string(),
|
||||
version_req: None,
|
||||
},
|
||||
sub_path: Some("sub_path".to_string()),
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
NpmPackageReference::from_str("npm:/test").unwrap(),
|
||||
NpmPackageReference {
|
||||
req: NpmPackageReq {
|
||||
name: "test".to_string(),
|
||||
version_req: None,
|
||||
},
|
||||
sub_path: None,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
NpmPackageReference::from_str("npm:/test/").unwrap(),
|
||||
NpmPackageReference {
|
||||
req: NpmPackageReq {
|
||||
name: "test".to_string(),
|
||||
version_req: None,
|
||||
},
|
||||
sub_path: None,
|
||||
}
|
||||
);
|
||||
|
||||
// should error for no name
|
||||
assert_eq!(
|
||||
NpmPackageReference::from_str("npm:/")
|
||||
.err()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
"Invalid npm specifier 'npm:/'. Did not contain a package name."
|
||||
);
|
||||
assert_eq!(
|
||||
NpmPackageReference::from_str("npm://test")
|
||||
.err()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
"Invalid npm specifier 'npm://test'. Did not contain a package name."
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"imports": {
|
||||
"chalk": "npm:chalk@5"
|
||||
"chalk": "npm:chalk@5",
|
||||
"@denotest/": "npm:/@denotest/dual-cjs-esm/"
|
||||
}
|
||||
}
|
||||
|
|
3
cli/tests/testdata/npm/import_map/main.js
vendored
3
cli/tests/testdata/npm/import_map/main.js
vendored
|
@ -1,7 +1,10 @@
|
|||
import chalk from "chalk";
|
||||
import { getSubPathKind } from "@denotest/subpath/main.mjs";
|
||||
|
||||
console.log(chalk.green("chalk import map loads"));
|
||||
|
||||
export function test(value) {
|
||||
return chalk.red(value);
|
||||
}
|
||||
|
||||
console.log(getSubPathKind());
|
||||
|
|
3
cli/tests/testdata/npm/import_map/main.out
vendored
3
cli/tests/testdata/npm/import_map/main.out
vendored
|
@ -1,3 +1,6 @@
|
|||
Download http://localhost:4545/npm/registry/@denotest/dual-cjs-esm
|
||||
Download http://localhost:4545/npm/registry/chalk
|
||||
Download http://localhost:4545/npm/registry/@denotest/dual-cjs-esm/1.0.0.tgz
|
||||
Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz
|
||||
chalk import map loads
|
||||
esm
|
||||
|
|
8
cli/tsc/00_typescript.js
vendored
8
cli/tsc/00_typescript.js
vendored
|
@ -90846,7 +90846,7 @@ var ts;
|
|||
if (!text.startsWith("npm:")) {
|
||||
throw new Error("Not an npm specifier: ".concat(text));
|
||||
}
|
||||
text = text.replace(/^npm:/, "");
|
||||
text = text.replace(/^npm:\/?/, "");
|
||||
var parts = text.split("/");
|
||||
var namePartLen = text.startsWith("@") ? 2 : 1;
|
||||
if (parts.length < namePartLen) {
|
||||
|
@ -90860,8 +90860,12 @@ var ts;
|
|||
versionReq = lastNamePart.substring(lastAtIndex + 1);
|
||||
nameParts[nameParts.length - 1] = lastNamePart.substring(0, lastAtIndex);
|
||||
}
|
||||
var name = nameParts.join("/");
|
||||
if (name.length === 0) {
|
||||
throw new Error("Npm specifier did not have a name: ".concat(text));
|
||||
}
|
||||
return {
|
||||
name: nameParts.join("/"),
|
||||
name: name,
|
||||
versionReq: versionReq,
|
||||
subPath: parts.length > nameParts.length ? parts.slice(nameParts.length).join("/") : undefined,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue