Skip to content

Commit

Permalink
feat(unstable): Node CJS and ESM resolvers for compat mode (denoland#…
Browse files Browse the repository at this point in the history
…12424)

This commit adds CJS and ESM Node resolvers to the "--compat" mode.

The functionality is spread across "cli/compat" module and Node compatibility
layer in "deno_std/node"; this stems from the fact that ES module resolution
can only be implemented in Rust as it needs to directly integrated with 
"deno_core"; however "deno_std/node" already provided CJS module resolution.

Currently this resolution is only active when running a files using 
"deno run --compat --unstable <filename>", and is not available in other
subcommands, which will be changed in follow up commits.
  • Loading branch information
bartlomieju committed Oct 18, 2021
1 parent 5a48d41 commit 617eeab
Show file tree
Hide file tree
Showing 32 changed files with 1,606 additions and 139 deletions.
88 changes: 0 additions & 88 deletions cli/compat.rs

This file was deleted.

145 changes: 145 additions & 0 deletions cli/compat/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.

use deno_core::error::generic_error;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::url::Url;

pub(crate) fn err_invalid_module_specifier(
request: &str,
reason: &str,
maybe_base: Option<String>,
) -> AnyError {
let mut msg = format!(
"[ERR_INVALID_MODULE_SPECIFIER] Invalid module \"{}\" {}",
request, reason
);

if let Some(base) = maybe_base {
msg = format!("{} imported from {}", msg, base);
}

type_error(msg)
}

pub(crate) fn err_invalid_package_config(
path: &str,
maybe_base: Option<String>,
maybe_message: Option<String>,
) -> AnyError {
let mut msg = format!(
"[ERR_INVALID_PACKAGE_CONFIG] Invalid package config {}",
path
);

if let Some(base) = maybe_base {
msg = format!("{} while importing {}", msg, base);
}

if let Some(message) = maybe_message {
msg = format!("{}. {}", msg, message);
}

generic_error(msg)
}

pub(crate) fn err_module_not_found(
path: &str,
base: &str,
typ: &str,
) -> AnyError {
generic_error(format!(
"[ERR_MODULE_NOT_FOUND] Cannot find {} '{}' imported from {}",
typ, path, base
))
}

pub(crate) fn err_unsupported_dir_import(path: &str, base: &str) -> AnyError {
generic_error(format!("[ERR_UNSUPPORTED_DIR_IMPORT] Directory import '{}' is not supported resolving ES modules imported from {}", path, base))
}

pub(crate) fn err_unsupported_esm_url_scheme(url: &Url) -> AnyError {
let mut msg =
"[ERR_UNSUPPORTED_ESM_URL_SCHEME] Only file and data URLS are supported by the default ESM loader"
.to_string();

if cfg!(window) && url.scheme().len() == 2 {
msg = format!(
"{}. On Windows, absolute path must be valid file:https:// URLs",
msg
);
}

msg = format!("{}. Received protocol '{}'", msg, url.scheme());
generic_error(msg)
}

pub(crate) fn err_invalid_package_target(
pkg_path: String,
key: String,
target: String,
is_import: bool,
maybe_base: Option<String>,
) -> AnyError {
let rel_error = !is_import && !target.is_empty() && !target.starts_with("./");
let mut msg = "[ERR_INVALID_PACKAGE_TARGET]".to_string();

if key == "." {
assert!(!is_import);
msg = format!("{} Invalid \"exports\" main target {} defined in the package config {}package.json", msg, target, pkg_path)
} else {
let ie = if is_import { "imports" } else { "exports" };
msg = format!("{} Invalid \"{}\" target {} defined for '{}' in the package config {}package.json", msg, ie, target, key, pkg_path)
};

if let Some(base) = maybe_base {
msg = format!("{} imported from {}", msg, base);
};
if rel_error {
msg = format!("{}; target must start with \"./\"", msg);
}

generic_error(msg)
}

pub(crate) fn err_package_path_not_exported(
pkg_path: String,
subpath: String,
maybe_base: Option<String>,
) -> AnyError {
let mut msg = "[ERR_PACKAGE_PATH_NOT_EXPORTED]".to_string();

if subpath == "." {
msg = format!(
"{} No \"exports\" main defined in {}package.json",
msg, pkg_path
);
} else {
msg = format!("{} Package subpath \'{}\' is not defined by \"exports\" in {}package.json", msg, subpath, pkg_path);
};

if let Some(base) = maybe_base {
msg = format!("{} imported from {}", msg, base);
}

generic_error(msg)
}

pub(crate) fn err_package_import_not_defined(
specifier: &str,
package_path: Option<String>,
base: &str,
) -> AnyError {
let mut msg = format!(
"[ERR_PACKAGE_IMPORT_NOT_DEFINED] Package import specifier \"{}\" is not defined in",
specifier
);

if let Some(package_path) = package_path {
msg = format!("{} in package {}package.json", msg, package_path);
}

msg = format!("{} imported from {}", msg, base);

type_error(msg)
}

0 comments on commit 617eeab

Please sign in to comment.