diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2022-09-03 18:19:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-03 18:19:30 +0200 |
commit | e324151520c62c9503e5e38da66827cd7815ea14 (patch) | |
tree | 51449e9ea202b758a4ac74210b97f6c9b65d26e7 /cli | |
parent | fc4025c878a7986576f693ed3ad297212f6a99de (diff) |
BREAKING(unstable): remove --compat mode (#15678)
This commit removes "compat" mode. We shipped support for "npm:" specifier
support in v1.25 and that is preferred way to interact with Node code that we
will iterate and improve upon.
Diffstat (limited to 'cli')
78 files changed, 12 insertions, 2354 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs index e80bf3a61..861cbb5fb 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -312,9 +312,6 @@ pub struct Flags { pub lock: Option<PathBuf>, pub log_level: Option<Level>, pub no_remote: bool, - /// If true, a list of Node built-in modules will be injected into - /// the import map. - pub compat: bool, pub no_prompt: bool, pub reload: bool, pub seed: Option<u64>, @@ -1869,7 +1866,6 @@ fn runtime_args( .arg(v8_flags_arg()) .arg(seed_arg()) .arg(enable_testing_features_arg()) - .arg(compat_arg()) } fn inspect_args(app: Command) -> Command { @@ -2009,21 +2005,6 @@ fn seed_arg<'a>() -> Arg<'a> { }) } -static COMPAT_HELP: Lazy<String> = Lazy::new(|| { - format!( - "See https://deno.land/manual@v{}/node/compatibility_mode", - SHORT_VERSION.as_str() - ) -}); - -fn compat_arg<'a>() -> Arg<'a> { - Arg::new("compat") - .long("compat") - .requires("unstable") - .help("UNSTABLE: Node compatibility mode.") - .long_help(COMPAT_HELP.as_str()) -} - fn watch_arg<'a>(takes_files: bool) -> Arg<'a> { let arg = Arg::new("watch") .long("watch") @@ -2916,7 +2897,6 @@ fn runtime_args_parse( location_arg_parse(flags, matches); v8_flags_arg_parse(flags, matches); seed_arg_parse(flags, matches); - compat_arg_parse(flags, matches); enable_testing_features_arg_parse(flags, matches); } @@ -3001,12 +2981,6 @@ fn seed_arg_parse(flags: &mut Flags, matches: &ArgMatches) { } } -fn compat_arg_parse(flags: &mut Flags, matches: &ArgMatches) { - if matches.is_present("compat") { - flags.compat = true; - } -} - fn no_check_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) { if let Some(cache_type) = matches.value_of("no-check") { match cache_type { @@ -5566,23 +5540,6 @@ mod tests { } #[test] - fn compat() { - let r = - flags_from_vec(svec!["deno", "run", "--compat", "--unstable", "foo.js"]); - assert_eq!( - r.unwrap(), - Flags { - subcommand: DenoSubcommand::Run(RunFlags { - script: "foo.js".to_string(), - }), - compat: true, - unstable: true, - ..Flags::default() - } - ); - } - - #[test] fn test_config_path_args() { let flags = flags_from_vec(svec!["deno", "run", "foo.js"]).unwrap(); assert_eq!( diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 90fa5220b..261de6c87 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -35,7 +35,6 @@ use std::net::SocketAddr; use std::path::PathBuf; use crate::args::config_file::JsxImportSourceConfig; -use crate::compat; use crate::deno_dir::DenoDir; use crate::emit::get_ts_config_for_emit; use crate::emit::TsConfigType; @@ -230,9 +229,6 @@ impl CliOptions { imports.extend(config_imports); } } - if self.flags.compat { - imports.extend(compat::get_node_imports()); - } if imports.is_empty() { Ok(None) } else { @@ -277,10 +273,6 @@ impl CliOptions { .unwrap_or(false) } - pub fn compat(&self) -> bool { - self.flags.compat - } - pub fn coverage_dir(&self) -> Option<String> { fn allow_coverage(sub_command: &DenoSubcommand) -> bool { match sub_command { diff --git a/cli/compat/esm_resolver.rs b/cli/compat/esm_resolver.rs deleted file mode 100644 index 2a5da4fe1..000000000 --- a/cli/compat/esm_resolver.rs +++ /dev/null @@ -1,1288 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use crate::node::errors; -use crate::resolver::ImportMapResolver; -use deno_core::error::generic_error; -use deno_core::error::AnyError; -use deno_core::serde_json; -use deno_core::serde_json::Map; -use deno_core::serde_json::Value; -use deno_core::url::Url; -use deno_core::ModuleSpecifier; -use deno_graph::source::ResolveResponse; -use deno_graph::source::Resolver; -use deno_runtime::deno_node::DEFAULT_CONDITIONS; -use regex::Regex; -use std::path::PathBuf; - -#[derive(Debug, Default)] -pub struct NodeEsmResolver { - maybe_import_map_resolver: Option<ImportMapResolver>, -} - -impl NodeEsmResolver { - pub fn new(maybe_import_map_resolver: Option<ImportMapResolver>) -> Self { - Self { - maybe_import_map_resolver, - } - } -} - -impl Resolver for NodeEsmResolver { - fn resolve( - &self, - specifier: &str, - referrer: &ModuleSpecifier, - ) -> ResolveResponse { - // First try to resolve using import map, ignoring any errors - if !specifier.starts_with("node:") { - if let Some(import_map_resolver) = &self.maybe_import_map_resolver { - let response = import_map_resolver.resolve(specifier, referrer); - if !matches!(response, ResolveResponse::Err(_)) { - return response; - } - } - } - - let current_dir = match std::env::current_dir() { - Ok(path) => path, - Err(err) => return ResolveResponse::Err(err.into()), - }; - let node_resolution = - node_resolve(specifier, referrer.as_str(), ¤t_dir); - - match node_resolution { - Ok(resolve_response) => { - // If node resolution succeeded, return the specifier - resolve_response - } - Err(err) => { - // If node resolution failed, check if it's because of unsupported - // URL scheme, and if so try to resolve using regular resolution algorithm - if err - .to_string() - .starts_with("[ERR_UNSUPPORTED_ESM_URL_SCHEME]") - { - return match deno_core::resolve_import(specifier, referrer.as_str()) { - Ok(specifier) => ResolveResponse::Esm(specifier), - Err(err) => ResolveResponse::Err(err.into()), - }; - } - - ResolveResponse::Err(err) - } - } - } -} - -/// This function is an implementation of `defaultResolve` in -/// `lib/internal/modules/esm/resolve.js` from Node. -fn node_resolve( - specifier: &str, - referrer: &str, - cwd: &std::path::Path, -) -> Result<ResolveResponse, AnyError> { - // TODO(bartlomieju): skipped "policy" part as we don't plan to support it - - if let Some(resolved) = crate::node::try_resolve_builtin_module(specifier) { - return Ok(ResolveResponse::Esm(resolved)); - } - - if let Ok(url) = Url::parse(specifier) { - if url.scheme() == "data" { - return Ok(ResolveResponse::Specifier(url)); - } - - let protocol = url.scheme(); - - if protocol == "node" { - let split_specifier = url.as_str().split(':'); - let specifier = split_specifier.skip(1).collect::<String>(); - if let Some(resolved) = - crate::node::try_resolve_builtin_module(&specifier) - { - return Ok(ResolveResponse::Esm(resolved)); - } else { - return Err(generic_error(format!("Unknown module {}", specifier))); - } - } - - if protocol != "file" && protocol != "data" { - return Err(errors::err_unsupported_esm_url_scheme(&url)); - } - - if referrer.starts_with("data:") { - let referrer_url = Url::parse(referrer)?; - let url = referrer_url.join(specifier).map_err(AnyError::from)?; - return Ok(ResolveResponse::Specifier(url)); - } - } - - let is_main = referrer.is_empty(); - let parent_url = if is_main { - Url::from_directory_path(cwd).unwrap() - } else { - Url::parse(referrer).expect("referrer was not proper url") - }; - - let conditions = DEFAULT_CONDITIONS; - let url = module_resolve(specifier, &parent_url, conditions)?; - - let resolve_response = if url.as_str().starts_with("http") { - ResolveResponse::Esm(url) - } else if url.as_str().ends_with(".js") { - let package_config = get_package_scope_config(&url)?; - if package_config.typ == "module" { - ResolveResponse::Esm(url) - } else { - ResolveResponse::CommonJs(url) - } - } else if url.as_str().ends_with(".cjs") { - ResolveResponse::CommonJs(url) - } else { - ResolveResponse::Esm(url) - }; - // TODO(bartlomieju): skipped checking errors for commonJS resolution and - // "preserveSymlinksMain"/"preserveSymlinks" options. - Ok(resolve_response) -} - -fn to_file_path(url: &ModuleSpecifier) -> PathBuf { - url - .to_file_path() - .unwrap_or_else(|_| panic!("Provided URL was not file:// URL: {}", url)) -} - -fn to_file_path_string(url: &ModuleSpecifier) -> String { - to_file_path(url).display().to_string() -} - -fn should_be_treated_as_relative_or_absolute_path(specifier: &str) -> bool { - if specifier.is_empty() { - return false; - } - - if specifier.starts_with('/') { - return true; - } - - is_relative_specifier(specifier) -} - -// TODO(ry) We very likely have this utility function elsewhere in Deno. -fn is_relative_specifier(specifier: &str) -> bool { - let specifier_len = specifier.len(); - let specifier_chars: Vec<_> = specifier.chars().collect(); - - if !specifier_chars.is_empty() && specifier_chars[0] == '.' { - if specifier_len == 1 || specifier_chars[1] == '/' { - return true; - } - if specifier_chars[1] == '.' - && (specifier_len == 2 || specifier_chars[2] == '/') - { - return true; - } - } - false -} - -fn module_resolve( - specifier: &str, - base: &ModuleSpecifier, - conditions: &[&str], -) -> Result<ModuleSpecifier, AnyError> { - let resolved = if should_be_treated_as_relative_or_absolute_path(specifier) { - base.join(specifier)? - } else if specifier.starts_with('#') { - package_imports_resolve(specifier, base, conditions)? - } else if let Ok(resolved) = Url::parse(specifier) { - resolved - } else { - package_resolve(specifier, base, conditions)? - }; - finalize_resolution(resolved, base) -} - -fn finalize_resolution( - resolved: ModuleSpecifier, - base: &ModuleSpecifier, -) -> Result<ModuleSpecifier, AnyError> { - // TODO(bartlomieju): this is not part of Node resolution algorithm - // (as it doesn't support http/https); but I had to short circuit here - // for remote modules because they are mainly used to polyfill `node` built - // in modules. Another option would be to leave the resolved URLs - // as `node:<module_name>` and do the actual remapping to std's polyfill - // in module loader. I'm not sure which approach is better. - if resolved.scheme().starts_with("http") { - return Ok(resolved); - } - - let encoded_sep_re = Regex::new(r"%2F|%2C").expect("bad regex"); - - if encoded_sep_re.is_match(resolved.path()) { - return Err(errors::err_invalid_module_specifier( - resolved.path(), - "must not include encoded \"/\" or \"\\\\\" characters", - Some(to_file_path_string(base)), - )); - } - - let path = to_file_path(&resolved); - - // TODO(bartlomieju): currently not supported - // if (getOptionValue('--experimental-specifier-resolution') === 'node') { - // ... - // } - - let p_str = path.to_str().unwrap(); - let p = if p_str.ends_with('/') { - p_str[p_str.len() - 1..].to_string() - } else { - p_str.to_string() - }; - - let (is_dir, is_file) = if let Ok(stats) = std::fs::metadata(&p) { - (stats.is_dir(), stats.is_file()) - } else { - (false, false) - }; - if is_dir { - return Err(errors::err_unsupported_dir_import( - resolved.as_str(), - base.as_str(), - )); - } else if !is_file { - return Err(errors::err_module_not_found( - resolved.as_str(), - base.as_str(), - "module", - )); - } - - Ok(resolved) -} - -fn throw_import_not_defined( - specifier: &str, - package_json_url: Option<ModuleSpecifier>, - base: &ModuleSpecifier, -) -> AnyError { - errors::err_package_import_not_defined( - specifier, - package_json_url.map(|u| to_file_path_string(&u.join(".").unwrap())), - &to_file_path_string(base), - ) -} - -fn pattern_key_compare(a: &str, b: &str) -> i32 { - let a_pattern_index = a.find('*'); - let b_pattern_index = b.find('*'); - - let base_len_a = if let Some(index) = a_pattern_index { - index + 1 - } else { - a.len() - }; - let base_len_b = if let Some(index) = b_pattern_index { - index + 1 - } else { - b.len() - }; - - if base_len_a > base_len_b { - return -1; - } - - if base_len_b > base_len_a { - return 1; - } - - if a_pattern_index.is_none() { - return 1; - } - - if b_pattern_index.is_none() { - return -1; - } - - if a.len() > b.len() { - return -1; - } - - if b.len() > a.len() { - return 1; - } - - 0 -} - -fn package_imports_resolve( - name: &str, - base: &ModuleSpecifier, - conditions: &[&str], -) -> Result<ModuleSpecifier, AnyError> { - if name == "#" || name.starts_with("#/") || name.ends_with('/') { - let reason = "is not a valid internal imports specifier name"; - return Err(errors::err_invalid_module_specifier( - name, - reason, - Some(to_file_path_string(base)), - )); - } - - let mut package_json_url = None; - - let package_config = get_package_scope_config(base)?; - if package_config.exists { - package_json_url = - Some(Url::from_file_path(package_config.pjsonpath).unwrap()); - if let Some(imports) = &package_config.imports { - if imports.contains_key(name) && !name.contains('*') { - let maybe_resolved = resolve_package_target( - package_json_url.clone().unwrap(), - imports.get(name).unwrap().to_owned(), - "".to_string(), - name.to_string(), - base, - false, - true, - conditions, - )?; - if let Some(resolved) = maybe_resolved { - return Ok(resolved); - } - } else { - let mut best_match = ""; - let mut best_match_subpath = None; - for key in imports.keys() { - let pattern_index = key.find('*'); - if let Some(pattern_index) = pattern_index { - let key_sub = &key[0..=pattern_index]; - if name.starts_with(key_sub) { - let pattern_trailer = &key[pattern_index + 1..]; - if name.len() > key.len() - && name.ends_with(&pattern_trailer) - && pattern_key_compare(best_match, key) == 1 - && key.rfind('*') == Some(pattern_index) - { - best_match = key; - best_match_subpath = Some( - name[pattern_index..=(name.len() - pattern_trailer.len())] - .to_string(), - ); - } - } - } - } - - if !best_match.is_empty() { - let target = imports.get(best_match).unwrap().to_owned(); - let maybe_resolved = resolve_package_target( - package_json_url.clone().unwrap(), - target, - best_match_subpath.unwrap(), - best_match.to_string(), - base, - true, - true, - conditions, - )?; - if let Some(resolved) = maybe_resolved { - return Ok(resolved); - } - } - } - } - } - - Err(throw_import_not_defined(name, package_json_url, base)) -} - -fn is_conditional_exports_main_sugar( - exports: &Value, - package_json_url: &ModuleSpecifier, - base: &ModuleSpecifier, -) -> Result<bool, AnyError> { - if exports.is_string() || exports.is_array() { - return Ok(true); - } - - if exports.is_null() || !exports.is_object() { - return Ok(false); - } - - let exports_obj = exports.as_object().unwrap(); - let mut is_conditional_sugar = false; - let mut i = 0; - for key in exports_obj.keys() { - let cur_is_conditional_sugar = key.is_empty() || !key.starts_with('.'); - if i == 0 { - is_conditional_sugar = cur_is_conditional_sugar; - i += 1; - } else if is_conditional_sugar != cur_is_conditional_sugar { - return Err(errors::err_invalid_package_config( - &to_file_path_string(package_json_url), - Some(base.as_str().to_string()), - Some("\"exports\" cannot contains some keys starting with \'.\' and some not. - The exports object must either be an object of package subpath keys - or an object of main entry condition name keys only.".to_string()) - )); - } - } - - Ok(is_conditional_sugar) -} - -fn throw_invalid_package_target( - subpath: String, - target: String, - package_json_url: &ModuleSpecifier, - internal: bool, - base: &ModuleSpecifier, -) -> AnyError { - errors::err_invalid_package_target( - to_file_path_string(&package_json_url.join(".").unwrap()), - subpath, - target, - internal, - Some(base.as_str().to_string()), - ) -} - -fn throw_invalid_subpath( - subpath: String, - package_json_url: &ModuleSpecifier, - internal: bool, - base: &ModuleSpecifier, -) -> AnyError { - let ie = if internal { "imports" } else { "exports" }; - let reason = format!( - "request is not a valid subpath for the \"{}\" resolution of {}", - ie, - to_file_path_string(package_json_url) - ); - errors::err_invalid_module_specifier( - &subpath, - &reason, - Some(to_file_path_string(base)), - ) -} - -#[allow(clippy::too_many_arguments)] -fn resolve_package_target_string( - target: String, - subpath: String, - match_: String, - package_json_url: ModuleSpecifier, - base: &ModuleSpecifier, - pattern: bool, - internal: bool, - conditions: &[&str], -) -> Result<ModuleSpecifier, AnyError> { - if !subpath.is_empty() && !pattern && !target.ends_with('/') { - return Err(throw_invalid_package_target( - match_, - target, - &package_json_url, - internal, - base, - )); - } - - let invalid_segment_re = - Regex::new(r"(^|\|/)(..?|node_modules)(\|/|$)").expect("bad regex"); - let pattern_re = Regex::new(r"\*").expect("bad regex"); - - if !target.starts_with("./") { - if internal && !target.starts_with("../") && !target.starts_with('/') { - let is_url = Url::parse(&target).is_ok(); - if !is_url { - let export_target = if pattern { - pattern_re - .replace(&target, |_caps: ®ex::Captures| subpath.clone()) - .to_string() - } else { - format!("{}{}", target, subpath) - }; - return package_resolve(&export_target, &package_json_url, conditions); - } - } - return Err(throw_invalid_package_target( - match_, - target, - &package_json_url, - internal, - base, - )); - } - - if invalid_segment_re.is_match(&target[2..]) { - return Err(throw_invalid_package_target( - match_, - target, - &package_json_url, - internal, - base, - )); - } - - let resolved = package_json_url.join(&target)?; - let resolved_path = resolved.path(); - let package_url = package_json_url.join(".").unwrap(); - let package_path = package_url.path(); - - if !resolved_path.starts_with(package_path) { - return Err(throw_invalid_package_target( - match_, - target, - &package_json_url, - internal, - base, - )); - } - - if subpath.is_empty() { - return Ok(resolved); - } - - if invalid_segment_re.is_match(&subpath) { - let request = if pattern { - match_.replace('*', &subpath) - } else { - format!("{}{}", match_, subpath) - }; - return Err(throw_invalid_subpath( - request, - &package_json_url, - internal, - base, - )); - } - - if pattern { - let replaced = pattern_re - .replace(resolved.as_str(), |_caps: ®ex::Captures| subpath.clone()); - let url = Url::parse(&replaced)?; - return Ok(url); - } - - Ok(resolved.join(&subpath)?) -} - -#[allow(clippy::too_many_arguments)] -fn resolve_package_target( - package_json_url: ModuleSpecifier, - target: Value, - subpath: String, - package_subpath: String, - base: &ModuleSpecifier, - pattern: bool, - internal: bool, - conditions: &[&str], -) -> Result<Option<ModuleSpecifier>, AnyError> { - if let Some(target) = target.as_str() { - return Ok(Some(resolve_package_target_string( - target.to_string(), - subpath, - package_subpath, - package_json_url, - base, - pattern, - internal, - conditions, - )?)); - } else if let Some(target_arr) = target.as_array() { - if target_arr.is_empty() { - return Ok(None); - } - - let mut last_error = None; - for target_item in target_arr { - let resolved_result = resolve_package_target( - package_json_url.clone(), - target_item.to_owned(), - subpath.clone(), - package_subpath.clone(), - base, - pattern, - internal, - conditions, - ); - - if let Err(e) = resolved_result { - let err_string = e.to_string(); - last_error = Some(e); - if err_string.starts_with("[ERR_INVALID_PACKAGE_TARGET]") { - continue; - } - return Err(last_error.unwrap()); - } - let resolved = resolved_result.unwrap(); - if resolved.is_none() { - last_error = None; - continue; - } - return Ok(resolved); - } - if last_error.is_none() { - return Ok(None); - } - return Err(last_error.unwrap()); - } else if let Some(target_obj) = target.as_object() { - for key in target_obj.keys() { - // TODO(bartlomieju): verify that keys are not numeric - // return Err(errors::err_invalid_package_config( - // to_file_path_string(package_json_url), - // Some(base.as_str().to_string()), - // Some("\"exports\" cannot contain numeric property keys.".to_string()), - // )); - - if key == "default" || conditions.contains(&key.as_str()) { - let condition_target = target_obj.get(key).unwrap().to_owned(); - let resolved = resolve_package_target( - package_json_url.clone(), - condition_target, - subpath.clone(), - package_subpath.clone(), - base, - pattern, - internal, - conditions, - )?; - if resolved.is_none() { - continue; - } - return Ok(resolved); - } - } - } else if target.is_null() { - return Ok(None); - } - - Err(throw_invalid_package_target( - package_subpath, - target.to_string(), - &package_json_url, - internal, - base, - )) -} - -fn throw_exports_not_found( - subpath: String, - package_json_url: &ModuleSpecifier, - base: &ModuleSpecifier, -) -> AnyError { - errors::err_package_path_not_exported( - to_file_path_string(&package_json_url.join(".").unwrap()), - subpath, - Some(to_file_path_string(base)), - ) -} - -fn package_exports_resolve( - package_json_url: ModuleSpecifier, - package_subpath: String, - package_config: PackageConfig, - base: &ModuleSpecifier, - conditions: &[&str], -) -> Result<ModuleSpecifier, AnyError> { - let exports = &package_config.exports.unwrap(); - - let exports_map = - if is_conditional_exports_main_sugar(exports, &package_json_url, base)? { - let mut map = Map::new(); - map.insert(".".to_string(), exports.to_owned()); - map - } else { - exports.as_object().unwrap().to_owned() - }; - - if exports_map.contains_key(&package_subpath) - && package_subpath.find('*').is_none() - && !package_subpath.ends_with('/') - { - let target = exports_map.get(&package_subpath).unwrap().to_owned(); - let resolved = resolve_package_target( - package_json_url.clone(), - target, - "".to_string(), - package_subpath.to_string(), - base, - false, - false, - conditions, - )?; - if resolved.is_none() { - return Err(throw_exports_not_found( - package_subpath, - &package_json_url, - base, - )); - } - return Ok(resolved.unwrap()); - } - - let mut best_match = ""; - let mut best_match_subpath = None; - for key in exports_map.keys() { - let pattern_index = key.find('*'); - if let Some(pattern_index) = pattern_index { - let key_sub = &key[0..=pattern_index]; - if package_subpath.starts_with(key_sub) { - // When this reaches EOL, this can throw at the top of the whole function: - // - // if (StringPrototypeEndsWith(packageSubpath, '/')) - // throwInvalidSubpath(packageSubpath) - // - // To match "imports" and the spec. - if package_subpath.ends_with('/') { - // TODO(bartlomieju): - // emitTrailingSlashPatternDeprecation(); - } - let pattern_trailer = &key[pattern_index + 1..]; - if package_subpath.len() > key.len() - && package_subpath.ends_with(&pattern_trailer) - && pattern_key_compare(best_match, key) == 1 - && key.rfind('*') == Some(pattern_index) - { - best_match = key; - best_match_subpath = Some( - package_subpath - [pattern_index..=(package_subpath.len() - pattern_trailer.len())] - .to_string(), - ); - } - } - } - } - - if !best_match.is_empty() { - let target = exports.get(best_match).unwrap().to_owned(); - let maybe_resolved = resolve_package_target( - package_json_url.clone(), - target, - best_match_subpath.unwrap(), - best_match.to_string(), - base, - true, - false, - conditions, - )?; - if let Some(resolved) = maybe_resolved { - return Ok(resolved); - } else { - return Err(throw_exports_not_found( - package_subpath, - &package_json_url, - base, - )); - } - } - - Err(throw_exports_not_found( - package_subpath, - &package_json_url, - base, - )) -} - -fn package_resolve( - specifier: &str, - base: &ModuleSpecifier, - conditions: &[&str], -) -> Result<ModuleSpecifier, AnyError> { - let (package_name, package_subpath, is_scoped) = - parse_package_name(specifier, base)?; - - // ResolveSelf - let package_config = get_package_scope_config(base)?; - if package_config.exists { - let package_json_url = - Url::from_file_path(&package_config.pjsonpath).unwrap(); - if package_config.name.as_ref() == Some(&package_name) { - if let Some(exports) = &package_config.exports { - if !exports.is_null() { - return package_exports_resolve( - package_json_url, - package_subpath, - package_config, - base, - conditions, - ); - } - } - } - } - - let mut package_json_url = - base.join(&format!("./node_modules/{}/package.json", package_name))?; - let mut package_json_path = to_file_path(&package_json_url); - let mut last_path; - loop { - let p_str = package_json_path.to_str().unwrap(); - let package_str_len = "/package.json".len(); - let p = p_str[0..=p_str.len() - package_str_len].to_string(); - let is_dir = if let Ok(stats) = std::fs::metadata(&p) { - stats.is_dir() - } else { - false - }; - if !is_dir { - last_path = package_json_path; - - let prefix = if is_scoped { - "../../../../node_modules/" - } else { - "../../../node_modules/" - }; - package_json_url = package_json_url - .join(&format!("{}{}/package.json", prefix, package_name))?; - package_json_path = to_file_path(&package_json_url); - if package_json_path.to_str().unwrap().len() - == last_path.to_str().unwrap().len() - { - break; - } else { - continue; - } - } - - // Package match. - let package_config = - get_package_config(package_json_path.clone(), specifier, Some(base))?; - if package_config.exports.is_some() { - return package_exports_resolve( - package_json_url, - package_subpath, - package_config, - base, - conditions, - ); - } - if package_subpath == "." { - return legacy_main_resolve(&package_json_url, &package_config, base); - } - - return package_json_url - .join(&package_subpath) - .map_err(AnyError::from); - } - - Err(errors::err_module_not_found( - &package_json_url - .join(".") - .unwrap() - .to_file_path() - .unwrap() - .display() - .to_string(), - &to_file_path_string(base), - "package", - )) -} - -fn parse_package_name( - specifier: &str, - base: &ModuleSpecifier, -) -> Result<(String, String, bool), AnyError> { - let mut separator_index = specifier.find('/'); - let mut valid_package_name = true; - let mut is_scoped = false; - if specifier.is_empty() { - valid_package_name = false; - } else if specifier.starts_with('@') { - is_scoped = true; - if let Some(index) = separator_index { - separator_index = specifier[index + 1..].find('/'); - } else { - valid_package_name = false; - } - } - - let package_name = if let Some(index) = separator_index { - specifier[0..index].to_string() - } else { - specifier.to_string() - }; - - // Package name cannot have leading . and cannot have percent-encoding or separators. - for ch in package_name.chars() { - if ch == '%' || ch == '\\' { - valid_package_name = false; - break; - } - } - - if !valid_package_name { - return Err(errors::err_invalid_module_specifier( - specifier, - "is not a valid package name", - Some(to_file_path_string(base)), - )); - } - - let package_subpath = if let Some(index) = separator_index { - format!(".{}", specifier.chars().skip(index).collect::<String>()) - } else { - ".".to_string() - }; - - Ok((package_name, package_subpath, is_scoped)) -} - -#[derive(Clone, Debug)] -struct PackageConfig { - exists: bool, - exports: Option<Value>, - imports: Option<Map<String, Value>>, - main: Option<String>, - name: Option<String>, - pjsonpath: PathBuf, - typ: String, -} - -pub fn check_if_should_use_esm_loader( - main_module: &ModuleSpecifier, -) -> Result<bool, AnyError> { - let s = main_module.as_str(); - if s.ends_with(".mjs") { - return Ok(true); - } - if s.ends_with(".cjs") { - return Ok(false); - } - let package_config = get_package_scope_config(main_module)?; - Ok(package_config.typ == "module") -} - -fn get_package_config( - path: PathBuf, - specifier: &str, - maybe_base: Option<&ModuleSpecifier>, -) -> Result<PackageConfig, AnyError> { - // TODO(bartlomieju): - // if let Some(existing) = package_json_cache.get(path) { - // return Ok(existing.clone()); - // } - - let result = std::fs::read_to_string(&path); - - let source = result.unwrap_or_else(|_| "".to_string()); - if source.is_empty() { - let package_config = PackageConfig { - pjsonpath: path, - exists: false, - main: None, - name: None, - typ: "none".to_string(), - exports: None, - imports: None, - }; - // TODO(bartlomieju): - // package_json_cache.set(package_json_path, package_config.clone()); - return Ok(package_config); - } - - let package_json: Value = serde_json::from_str(&source).map_err(|err| { - let base_msg = maybe_base.map(|base| { - format!("\"{}\" from {}", specifier, to_file_path(base).display()) - }); - errors::err_invalid_package_config( - &path.display().to_string(), - base_msg, - Some(err.to_string()), - ) - })?; - - let imports_val = package_json.get("imports"); - let main_val = package_json.get("main"); - let name_val = package_json.get("name"); - let typ_val = package_json.get("type"); - let exports = package_json.get("exports").map(|e| e.to_owned()); - - let imports = if let Some(imp) = imports_val { - imp.as_object().map(|imp| imp.to_owned()) - } else { - None - }; - let main = if let Some(m) = main_val { - m.as_str().map(|m| m.to_string()) - } else { - None - }; - let name = if let Some(n) = name_val { - n.as_str().map(|n| n.to_string()) - } else { - None - }; - - // Ignore unknown types for forwards compatibility - let typ = if let Some(t) = typ_val { - if let Some(t) = t.as_str() { - if t != "module" && t != "commonjs" { - "none".to_string() - } else { - t.to_string() - } - } else { - "none".to_string() - } - } else { - "none".to_string() - }; - - let package_config = PackageConfig { - pjsonpath: path, - exists: true, - main, - name, - typ, - exports, - imports, - }; - // TODO(bartlomieju): - // package_json_cache.set(package_json_path, package_config.clone()); - Ok(package_config) -} - -fn get_package_scope_config( - resolved: &ModuleSpecifier, -) -> Result<PackageConfig, AnyError> { - let mut package_json_url = resolved.join("./package.json")?; - - loop { - let package_json_path = package_json_url.path(); - - if package_json_path.ends_with("node_modules/package.json") { - break; - } - - let package_config = get_package_config( - to_file_path(&package_json_url), - resolved.as_str(), - None, - )?; - - if package_config.exists { - return Ok(package_config); - } - - let last_package_json_url = package_json_url.clone(); - package_json_url = package_json_url.join("../package.json")?; - - // TODO(bartlomieju): I'm not sure this will work properly - // Terminates at root where ../package.json equals ../../package.json - // (can't just check "/package.json" for Windows support) - if package_json_url.path() == last_package_json_url.path() { - break; - } - } - - let package_json_path = to_file_path(&package_json_url); - let package_config = PackageConfig { - pjsonpath: package_json_path, - exists: false, - main: None, - name: None, - typ: "none".to_string(), - exports: None, - imports: None, - }; - - // TODO(bartlomieju): - // package_json_cache.set(package_json_path, package_config.clone()); - - Ok(package_config) -} - -fn file_exists(path_url: &ModuleSpecifier) -> bool { - if let Ok(stats) = std::fs::metadata(to_file_path(path_url)) { - stats.is_file() - } else { - false - } -} - -fn legacy_main_resolve( - package_json_url: &ModuleSpecifier, - package_config: &PackageConfig, - _base: &ModuleSpecifier, -) -> Result<ModuleSpecifier, AnyError> { - let mut guess; - - if let Some(main) = &package_config.main { - guess = package_json_url.join(&format!("./{}", main))?; - if file_exists(&guess) { - return Ok(guess); - } - - let mut found = false; - for ext in [ - ".js", - ".json", - ".node", - "/index.js", - "/index.json", - "/index.node", - ] { - guess = package_json_url.join(&format!("./{}{}", main, ext))?; - if file_exists(&guess) { - found = true; - break; - } - } - - if found { - // TODO(bartlomieju): emitLegacyIndexDeprecation() - return Ok(guess); - } - } - - for p in ["./index.js", "./index.json", "./index.node"] { - guess = package_json_url.join(p)?; - if file_exists(&guess) { - // TODO(bartlomieju): emitLegacyIndexDeprecation() - return Ok(guess); - } - } - - Err(generic_error("not found")) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::deno_std::CURRENT_STD_URL; - - fn testdir(name: &str) -> PathBuf { - let c = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - c.join("compat/testdata/").join(name) - } - - #[test] - fn basic() { - let cwd = testdir("basic"); - let main = Url::from_file_path(cwd.join("main.js")).unwrap(); - let actual = node_resolve("foo", main.as_str(), &cwd).unwrap(); - let expected = - Url::from_file_path(cwd.join("node_modules/foo/index.js")).unwrap(); - assert!(matches!(actual, ResolveResponse::Esm(_))); - assert_eq!(actual.to_result().unwrap(), expected); - - let actual = node_resolve( - "data:application/javascript,console.log(\"Hello%20Deno\");", - main.as_str(), - &cwd, - ) - .unwrap(); - let expected = - Url::parse("data:application/javascript,console.log(\"Hello%20Deno\");") - .unwrap(); - assert!(matches!(actual, ResolveResponse::Specifier(_))); - assert_eq!(actual.to_result().unwrap(), expected); - } - - #[test] - fn deep() { - let cwd = testdir("deep"); - let main = Url::from_file_path(cwd.join("a/b/c/d/main.js")).unwrap(); - let actual = node_resolve("foo", main.as_str(), &cwd).unwrap(); - let expected = - Url::from_file_path(cwd.join("node_modules/foo/index.js")).unwrap(); - matches!(actual, ResolveResponse::Esm(_)); - assert_eq!(actual.to_result().unwrap(), expected); - } - - #[test] - fn package_subpath() { - let cwd = testdir("subpath"); - let main = Url::from_file_path(cwd.join("main.js")).unwrap(); - let actual = node_resolve("foo", main.as_str(), &cwd).unwrap(); - let expected = - Url::from_file_path(cwd.join("node_modules/foo/index.js")).unwrap(); - matches!(actual, ResolveResponse::CommonJs(_)); - assert_eq!(actual.to_result().unwrap(), expected); - let actual = node_resolve("foo/server.js", main.as_str(), &cwd).unwrap(); - let expected = - Url::from_file_path(cwd.join("node_modules/foo/server.js")).unwrap(); - matches!(actual, ResolveResponse::CommonJs(_)); - assert_eq!(actual.to_result().unwrap(), expected); - } - - #[test] - fn basic_deps() { - let cwd = testdir("basic_deps"); - let main = Url::from_file_path(cwd.join("main.js")).unwrap(); - let actual = node_resolve("foo", main.as_str(), &cwd).unwrap(); - let foo_js = - Url::from_file_path(cwd.join("node_modules/foo/foo.js")).unwrap(); - assert!(matches!(actual, ResolveResponse::Esm(_))); - assert_eq!(actual.to_result().unwrap(), foo_js); - - let actual = node_resolve("bar", foo_js.as_str(), &cwd).unwrap(); - - let bar_js = - Url::from_file_path(cwd.join("node_modules/bar/bar.js")).unwrap(); - assert!(matches!(actual, ResolveResponse::Esm(_))); - assert_eq!(actual.to_result().unwrap(), bar_js); - } - - #[test] - fn builtin_http() { - let cwd = testdir("basic"); - let main = Url::from_file_path(cwd.join("main.js")).unwrap(); - let expected = CURRENT_STD_URL.join("node/http.ts").unwrap(); - - let actual = node_resolve("http", main.as_str(), &cwd).unwrap(); - assert!(matches!(actual, ResolveResponse::Esm(_))); - assert_eq!(actual.to_result().unwrap(), expected); - - let actual = node_resolve("node:http", main.as_str(), &cwd).unwrap(); - assert!(matches!(actual, ResolveResponse::Esm(_))); - assert_eq!(actual.to_result().unwrap(), expected); - } - - #[test] - fn conditional_exports() { - // check that `exports` mapping works correctly - let cwd = testdir("conditions"); - let main = Url::from_file_path(cwd.join("main.js")).unwrap(); - let actual = node_resolve("imports_exports", main.as_str(), &cwd).unwrap(); - let expected = Url::from_file_path( - cwd.join("node_modules/imports_exports/import_export.js"), - ) - .unwrap(); - assert!(matches!(actual, ResolveResponse::CommonJs(_))); - assert_eq!(actual.to_result().unwrap(), expected); - - // check that `imports` mapping works correctly - let cwd = testdir("conditions/node_modules/imports_exports"); - let main = Url::from_file_path(cwd.join("import_export.js")).unwrap(); - let actual = node_resolve("#dep", main.as_str(), &cwd).unwrap(); - let expected = Url::from_file_path(cwd.join("import_polyfill.js")).unwrap(); - assert!(matches!(actual, ResolveResponse::CommonJs(_))); - assert_eq!(actual.to_result().unwrap(), expected); - } - - #[test] - fn test_is_relative_specifier() { - assert!(is_relative_specifier("./foo.js")); - assert!(!is_relative_specifier("https://deno.land/std/node/http.ts")); - } - - #[test] - fn test_check_if_should_use_esm_loader() { - let basic = testdir("basic"); - let main = Url::from_file_path(basic.join("main.js")).unwrap(); - assert!(check_if_should_use_esm_loader(&main).unwrap()); - - let cjs = Url::from_file_path(basic.join("main.cjs")).unwrap(); - assert!(!check_if_should_use_esm_loader(&cjs).unwrap()); - - let not_esm = testdir("not_esm"); - let main = Url::from_file_path(not_esm.join("main.js")).unwrap(); - assert!(!check_if_should_use_esm_loader(&main).unwrap()); - } -} diff --git a/cli/compat/mod.rs b/cli/compat/mod.rs deleted file mode 100644 index 0581f208f..000000000 --- a/cli/compat/mod.rs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -mod esm_resolver; - -use crate::file_fetcher::FileFetcher; -use crate::node::NODE_COMPAT_URL; -use crate::node::SUPPORTED_MODULES; -use deno_ast::MediaType; -use deno_core::error::AnyError; -use deno_core::located_script_name; -use deno_core::url::Url; -use deno_core::JsRuntime; -use deno_core::ModuleSpecifier; -use once_cell::sync::Lazy; - -pub use esm_resolver::check_if_should_use_esm_loader; -pub use esm_resolver::NodeEsmResolver; - -pub static GLOBAL_URL: Lazy<Url> = - Lazy::new(|| NODE_COMPAT_URL.join("node/global.ts").unwrap()); - -pub static MODULE_URL: Lazy<Url> = - Lazy::new(|| NODE_COMPAT_URL.join("node/module.ts").unwrap()); - -static COMPAT_IMPORT_URL: Lazy<Url> = - Lazy::new(|| Url::parse("flags:compat").unwrap()); - -/// Provide imports into a module graph when the compat flag is true. -pub fn get_node_imports() -> Vec<(Url, Vec<String>)> { - vec![( - COMPAT_IMPORT_URL.clone(), - vec![GLOBAL_URL.as_str().to_owned()], - )] -} - -pub fn load_cjs_module( - js_runtime: &mut JsRuntime, - module: &str, - main: bool, -) -> Result<(), AnyError> { - let source_code = &format!( - r#"(async function loadCjsModule(module) {{ - const Module = await import("{module_loader}"); - Module.default._load(module, null, {main}); - }})('{module}');"#, - module_loader = MODULE_URL.as_str(), - main = main, - module = escape_for_single_quote_string(module), - ); - - js_runtime.execute_script(&located_script_name!(), source_code)?; - Ok(()) -} - -pub fn add_global_require( - js_runtime: &mut JsRuntime, - main_module: &str, -) -> Result<(), AnyError> { - let source_code = &format!( - r#"(async function setupGlobalRequire(main) {{ - const Module = await import("{}"); - const require = Module.createRequire(main); - globalThis.require = require; - }})('{}');"#, - MODULE_URL.as_str(), - escape_for_single_quote_string(main_module), - ); - - js_runtime.execute_script(&located_script_name!(), source_code)?; - Ok(()) -} - -fn escape_for_single_quote_string(text: &str) -> String { - text.replace('\\', r"\\").replace('\'', r"\'") -} - -pub fn setup_builtin_modules( - js_runtime: &mut JsRuntime, -) -> Result<(), AnyError> { - let mut script = String::new(); - for module in SUPPORTED_MODULES { - // skipping the modules that contains '/' as they are not available in NodeJS repl as well - if !module.name.contains('/') { - script = format!( - "{}const {MODULE_NAME} = require('{MODULE_NAME}');\n", - script, - MODULE_NAME = module.name - ); - } - } - - js_runtime.execute_script("setup_node_builtins.js", &script)?; - Ok(()) -} - -/// Translates given CJS module into ESM. This function will perform static -/// analysis on the file to find defined exports and reexports. -/// -/// For all discovered reexports the analysis will be performed recursively. -/// -/// If successful a source code for equivalent ES module is returned. -pub fn translate_cjs_to_esm( - file_fetcher: &FileFetcher, - specifier: &ModuleSpecifier, - code: String, - media_type: MediaType, -) -> Result<String, AnyError> { - let parsed_source = deno_ast::parse_script(deno_ast::ParseParams { - specifier: specifier.to_string(), - text_info: deno_ast::SourceTextInfo::new(code.into()), - media_type, - capture_tokens: true, - scope_analysis: false, - maybe_syntax: None, - })?; - let analysis = parsed_source.analyze_cjs(); - - let mut source = vec![ - r#"import { createRequire } from "node:module";"#.to_string(), - r#"const require = createRequire(import.meta.url);"#.to_string(), - ]; - - // if there are reexports, handle them first - for (idx, reexport) in analysis.reexports.iter().enumerate() { - // Firstly, resolve relate reexport specifier - let resolved_reexport = node_resolver::resolve( - reexport, - &specifier.to_file_path().unwrap(), - // FIXME(bartlomieju): check if these conditions are okay, probably - // should be `deno-require`, because `deno` is already used in `esm_resolver.rs` - &["deno", "require", "default"], - )?; - let reexport_specifier = - ModuleSpecifier::from_file_path(&resolved_reexport).unwrap(); - // Secondly, read the source code from disk - let reexport_file = file_fetcher.get_source(&reexport_specifier).unwrap(); - // Now perform analysis again - { - let parsed_source = deno_ast::parse_script(deno_ast::ParseParams { - specifier: reexport_specifier.to_string(), - text_info: deno_ast::SourceTextInfo::new(reexport_file.source), - media_type: reexport_file.media_type, - capture_tokens: true, - scope_analysis: false, - maybe_syntax: None, - })?; - let analysis = parsed_source.analyze_cjs(); - - source.push(format!( - "const reexport{} = require(\"{}\");", - idx, reexport - )); - - for export in analysis.exports.iter().filter(|e| e.as_str() != "default") - { - // TODO(bartlomieju): Node actually checks if a given export exists in `exports` object, - // but it might not be necessary here since our analysis is more detailed? - source.push(format!( - "export const {0} = Deno[Deno.internal].require.bindExport(reexport{1}.{2}, reexport{1});", - export, idx, export - )); - } - } - } - - source.push(format!( - "const mod = require(\"{}\");", - specifier - .to_file_path() - .unwrap() - .to_str() - .unwrap() - .replace('\\', "\\\\") - .replace('\'', "\\\'") - .replace('\"', "\\\"") - )); - source.push("export default mod;".to_string()); - - for export in analysis.exports.iter().filter(|e| e.as_str() != "default") { - // TODO(bartlomieju): Node actually checks if a given export exists in `exports` object, - // but it might not be necessary here since our analysis is more detailed? - source.push(format!( - "export const {} = Deno[Deno.internal].require.bindExport(mod.{}, mod);", - export, export - )); - } - - let translated_source = source.join("\n"); - Ok(translated_source) -} diff --git a/cli/compat/testdata/basic/main.js b/cli/compat/testdata/basic/main.js deleted file mode 100644 index c0748305d..000000000 --- a/cli/compat/testdata/basic/main.js +++ /dev/null @@ -1 +0,0 @@ -import "foo"; diff --git a/cli/compat/testdata/basic/node_modules/foo/index.js b/cli/compat/testdata/basic/node_modules/foo/index.js deleted file mode 100644 index e69de29bb..000000000 --- a/cli/compat/testdata/basic/node_modules/foo/index.js +++ /dev/null diff --git a/cli/compat/testdata/basic/node_modules/foo/package.json b/cli/compat/testdata/basic/node_modules/foo/package.json deleted file mode 100644 index a74d52fd3..000000000 --- a/cli/compat/testdata/basic/node_modules/foo/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "foo", - "type": "module", - "exports": "./index.js" -} diff --git a/cli/compat/testdata/basic/package.json b/cli/compat/testdata/basic/package.json deleted file mode 100644 index cc4ac5493..000000000 --- a/cli/compat/testdata/basic/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "bar", - "type": "module", - "dependencies": { - "foo": "1.0.0" - } -} diff --git a/cli/compat/testdata/basic_deps/main.js b/cli/compat/testdata/basic_deps/main.js deleted file mode 100644 index c0748305d..000000000 --- a/cli/compat/testdata/basic_deps/main.js +++ /dev/null @@ -1 +0,0 @@ -import "foo"; diff --git a/cli/compat/testdata/basic_deps/node_modules/bar/bar.js b/cli/compat/testdata/basic_deps/node_modules/bar/bar.js deleted file mode 100644 index 98e51675e..000000000 --- a/cli/compat/testdata/basic_deps/node_modules/bar/bar.js +++ /dev/null @@ -1 +0,0 @@ -export const BAR = 123; diff --git a/cli/compat/testdata/basic_deps/node_modules/bar/package.json b/cli/compat/testdata/basic_deps/node_modules/bar/package.json deleted file mode 100644 index c2043f610..000000000 --- a/cli/compat/testdata/basic_deps/node_modules/bar/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "bar", - "version": "0.1.2", - "type": "module", - "exports": "./bar.js" -} diff --git a/cli/compat/testdata/basic_deps/node_modules/foo/foo.js b/cli/compat/testdata/basic_deps/node_modules/foo/foo.js deleted file mode 100644 index 0026acc8e..000000000 --- a/cli/compat/testdata/basic_deps/node_modules/foo/foo.js +++ /dev/null @@ -1 +0,0 @@ -import "bar"; diff --git a/cli/compat/testdata/basic_deps/node_modules/foo/package.json b/cli/compat/testdata/basic_deps/node_modules/foo/package.json deleted file mode 100644 index 376dae81e..000000000 --- a/cli/compat/testdata/basic_deps/node_modules/foo/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "foo", - "type": "module", - "exports": "./foo.js", - "dependencies": { - "bar": "0.1.2" - } -} diff --git a/cli/compat/testdata/basic_deps/package.json b/cli/compat/testdata/basic_deps/package.json deleted file mode 100644 index 138d401ed..000000000 --- a/cli/compat/testdata/basic_deps/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "main_program", - "type": "module", - "dependencies": { - "foo": "1.0.0" - } -} diff --git a/cli/compat/testdata/conditions/main.js b/cli/compat/testdata/conditions/main.js deleted file mode 100644 index cafddb5d6..000000000 --- a/cli/compat/testdata/conditions/main.js +++ /dev/null @@ -1 +0,0 @@ -import "imports_exports"; diff --git a/cli/compat/testdata/conditions/node_modules/imports_exports/import_export.js b/cli/compat/testdata/conditions/node_modules/imports_exports/import_export.js deleted file mode 100644 index 3ebd222ea..000000000 --- a/cli/compat/testdata/conditions/node_modules/imports_exports/import_export.js +++ /dev/null @@ -1,6 +0,0 @@ -import dep from "#dep"; - -export default { - bar: "bar", - dep, -}; diff --git a/cli/compat/testdata/conditions/node_modules/imports_exports/import_polyfill.js b/cli/compat/testdata/conditions/node_modules/imports_exports/import_polyfill.js deleted file mode 100644 index 76716a3ef..000000000 --- a/cli/compat/testdata/conditions/node_modules/imports_exports/import_polyfill.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - polyfill: "import", -}; diff --git a/cli/compat/testdata/conditions/node_modules/imports_exports/package.json b/cli/compat/testdata/conditions/node_modules/imports_exports/package.json deleted file mode 100644 index 5d26359db..000000000 --- a/cli/compat/testdata/conditions/node_modules/imports_exports/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": "1.0.0", - "name": "imports_exports", - "main": "./require_export.cjs", - "imports": { - "#dep": { - "import": "./import_polyfill.js", - "require": "./require_polyfill.js" - } - }, - "exports": { - ".": { - "import": "./import_export.js", - "require": "./require_export.cjs" - } - } -} diff --git a/cli/compat/testdata/conditions/node_modules/imports_exports/require_export.cjs b/cli/compat/testdata/conditions/node_modules/imports_exports/require_export.cjs deleted file mode 100644 index 11648c0d7..000000000 --- a/cli/compat/testdata/conditions/node_modules/imports_exports/require_export.cjs +++ /dev/null @@ -1,6 +0,0 @@ -const dep = require("#dep"); - -module.exports = { - foo: "foo", - dep, -};
\ No newline at end of file diff --git a/cli/compat/testdata/conditions/node_modules/imports_exports/require_polyfill.js b/cli/compat/testdata/conditions/node_modules/imports_exports/require_polyfill.js deleted file mode 100644 index 1023fd65c..000000000 --- a/cli/compat/testdata/conditions/node_modules/imports_exports/require_polyfill.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - polyfill: "require", -}; diff --git a/cli/compat/testdata/conditions/package.json b/cli/compat/testdata/conditions/package.json deleted file mode 100644 index 4d6d004dd..000000000 --- a/cli/compat/testdata/conditions/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "conditions", - "type": "module", - "dependencies": { - "imports_exports": "1.0.0" - } -} diff --git a/cli/compat/testdata/deep/a/b/c/d/main.js b/cli/compat/testdata/deep/a/b/c/d/main.js deleted file mode 100644 index c0748305d..000000000 --- a/cli/compat/testdata/deep/a/b/c/d/main.js +++ /dev/null @@ -1 +0,0 @@ -import "foo"; diff --git a/cli/compat/testdata/deep/node_modules/foo/index.js b/cli/compat/testdata/deep/node_modules/foo/index.js deleted file mode 100644 index e69de29bb..000000000 --- a/cli/compat/testdata/deep/node_modules/foo/index.js +++ /dev/null diff --git a/cli/compat/testdata/deep/node_modules/foo/package.json b/cli/compat/testdata/deep/node_modules/foo/package.json deleted file mode 100644 index a74d52fd3..000000000 --- a/cli/compat/testdata/deep/node_modules/foo/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "foo", - "type": "module", - "exports": "./index.js" -} diff --git a/cli/compat/testdata/not_esm/main.js b/cli/compat/testdata/not_esm/main.js deleted file mode 100644 index 347e20832..000000000 --- a/cli/compat/testdata/not_esm/main.js +++ /dev/null @@ -1 +0,0 @@ -require("foo"); diff --git a/cli/compat/testdata/not_esm/node_modules/foo/index.js b/cli/compat/testdata/not_esm/node_modules/foo/index.js deleted file mode 100644 index e69de29bb..000000000 --- a/cli/compat/testdata/not_esm/node_modules/foo/index.js +++ /dev/null diff --git a/cli/compat/testdata/not_esm/node_modules/foo/package.json b/cli/compat/testdata/not_esm/node_modules/foo/package.json deleted file mode 100644 index a74d52fd3..000000000 --- a/cli/compat/testdata/not_esm/node_modules/foo/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "foo", - "type": "module", - "exports": "./index.js" -} diff --git a/cli/compat/testdata/not_esm/package.json b/cli/compat/testdata/not_esm/package.json deleted file mode 100644 index 4b03fc938..000000000 --- a/cli/compat/testdata/not_esm/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "bar", - "dependencies": { - "foo": "1.0.0" - } -} diff --git a/cli/compat/testdata/subpath/main.js b/cli/compat/testdata/subpath/main.js deleted file mode 100644 index ed1fe019e..000000000 --- a/cli/compat/testdata/subpath/main.js +++ /dev/null @@ -1,2 +0,0 @@ -import "foo"; -import "foo/server.js"; diff --git a/cli/compat/testdata/subpath/node_modules/foo/index.js b/cli/compat/testdata/subpath/node_modules/foo/index.js deleted file mode 100644 index e69de29bb..000000000 --- a/cli/compat/testdata/subpath/node_modules/foo/index.js +++ /dev/null diff --git a/cli/compat/testdata/subpath/node_modules/foo/package.json b/cli/compat/testdata/subpath/node_modules/foo/package.json deleted file mode 100644 index 26f2d565a..000000000 --- a/cli/compat/testdata/subpath/node_modules/foo/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "foo", - "main": "index.js" -}
\ No newline at end of file diff --git a/cli/compat/testdata/subpath/node_modules/foo/server.js b/cli/compat/testdata/subpath/node_modules/foo/server.js deleted file mode 100644 index e69de29bb..000000000 --- a/cli/compat/testdata/subpath/node_modules/foo/server.js +++ /dev/null diff --git a/cli/graph_util.rs b/cli/graph_util.rs index 1f49c22a3..f73fd5559 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -441,20 +441,6 @@ impl GraphData { None } - // TODO(bartlomieju): after saving translated source - // it's never removed, potentially leading to excessive - // memory consumption - pub fn add_cjs_esm_translation( - &mut self, - specifier: &ModuleSpecifier, - source: String, - ) { - let prev = self - .cjs_esm_translations - .insert(specifier.to_owned(), source); - assert!(prev.is_none()); - } - pub fn get_cjs_esm_translation<'a>( &'a self, specifier: &ModuleSpecifier, diff --git a/cli/main.rs b/cli/main.rs index f089eeed6..98b5325b0 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -5,7 +5,6 @@ mod auth_tokens; mod cache; mod cdp; mod checksum; -mod compat; mod deno_dir; mod deno_std; mod diagnostics; @@ -806,8 +805,6 @@ async fn run_command( return run_with_watch(flags, run_flags.script).await; } - // TODO(bartlomieju): it should not be resolved here if we're in compat mode - // because it might be a bare specifier // TODO(bartlomieju): actually I think it will also fail if there's an import // map specified and bare specifier is used on the command line - this should // probably call `ProcState::resolve` instead diff --git a/cli/node/errors.rs b/cli/node/errors.rs index d7d1bbd05..f14e6e92e 100644 --- a/cli/node/errors.rs +++ b/cli/node/errors.rs @@ -22,27 +22,6 @@ pub fn err_invalid_module_specifier( type_error(msg) } -pub 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 fn err_module_not_found(path: &str, base: &str, typ: &str) -> AnyError { generic_error(format!( "[ERR_MODULE_NOT_FOUND] Cannot find {} \"{}\" imported from \"{}\"", @@ -69,73 +48,3 @@ pub fn err_unsupported_esm_url_scheme(url: &Url) -> AnyError { msg = format!("{}. Received protocol '{}'", msg, url.scheme()); generic_error(msg) } - -pub 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 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 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) -} diff --git a/cli/proc_state.rs b/cli/proc_state.rs index 7d29cd89f..dc0072c4a 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -9,8 +9,6 @@ use crate::cache::EmitCache; use crate::cache::FastInsecureHasher; use crate::cache::ParsedSourceCache; use crate::cache::TypeCheckCache; -use crate::compat; -use crate::compat::NodeEsmResolver; use crate::deno_dir; use crate::emit::emit_parsed_source; use crate::emit::TsConfigType; @@ -186,9 +184,6 @@ impl ProcState { // FIXME(bartlomieju): `NodeEsmResolver` is not aware of JSX resolver // created below - let node_resolver = NodeEsmResolver::new( - maybe_import_map.clone().map(ImportMapResolver::new), - ); let maybe_import_map_resolver = maybe_import_map.clone().map(ImportMapResolver::new); let maybe_jsx_resolver = cli_options @@ -196,9 +191,7 @@ impl ProcState { .map(|cfg| JsxResolver::new(cfg, maybe_import_map_resolver.clone())); let maybe_resolver: Option< Arc<dyn deno_graph::source::Resolver + Send + Sync>, - > = if cli_options.compat() { - Some(Arc::new(node_resolver)) - } else if let Some(jsx_resolver) = maybe_jsx_resolver { + > = if let Some(jsx_resolver) = maybe_jsx_resolver { // the JSX resolver offloads to the import map if present, otherwise uses // the default Deno explicit import resolution. Some(Arc::new(jsx_resolver)) @@ -286,7 +279,7 @@ impl ProcState { // One might argue that this is a code smell, and I would agree. However // due to flux in "Node compatibility" it's not clear where it should be // decided what `ModuleKind` is decided for root specifier. - let roots = roots + let roots: Vec<(deno_core::url::Url, deno_graph::ModuleKind)> = roots .into_iter() .map(|r| { if let Some(resolver) = &maybe_resolver { @@ -306,13 +299,6 @@ impl ProcState { // TODO(bartlomieju): this is very make-shift, is there an existing API // that we could include it like with "maybe_imports"? - let roots = if self.options.compat() { - let mut r = vec![(compat::GLOBAL_URL.clone(), ModuleKind::Esm)]; - r.extend(roots); - r - } else { - roots - }; if !reload_on_watch { let graph_data = self.graph_data.read(); if self.options.type_check_mode() == TypeCheckMode::None @@ -389,32 +375,6 @@ impl ProcState { ) .await; - let needs_cjs_esm_translation = graph - .modules() - .iter() - .any(|m| m.kind == ModuleKind::CommonJs); - - if needs_cjs_esm_translation { - for module in graph.modules() { - // TODO(bartlomieju): this is overly simplistic heuristic, once we are - // in compat mode, all files ending with plain `.js` extension are - // considered CommonJs modules. Which leads to situation where valid - // ESM modules with `.js` extension might undergo translation (it won't - // work in this situation). - if module.kind == ModuleKind::CommonJs { - let translated_source = compat::translate_cjs_to_esm( - &self.file_fetcher, - &module.specifier, - module.maybe_source.as_ref().unwrap().to_string(), - module.media_type, - )?; - let mut graph_data = self.graph_data.write(); - graph_data - .add_cjs_esm_translation(&module.specifier, translated_source); - } - } - } - // If there was a locker, validate the integrity of all the modules in the // locker. graph_lock_or_exit(&graph); diff --git a/cli/tests/integration/compat_tests.rs b/cli/tests/integration/compat_tests.rs deleted file mode 100644 index 88514832f..000000000 --- a/cli/tests/integration/compat_tests.rs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. - -use crate::itest; -use deno_core::url::Url; -use test_util as util; - -/// Tests in this file should use `std_file_url` to override `DENO_NODE_COMPAT_URL` -/// env variable. This speeds up tests significantly as they no longer -/// download contents of `deno_std` from `https://deno.land` in each test. - -/// Return a file URL pointing to "std" submodule -/// in "test_util" directory. It must have a trailing slash. -fn std_file_url() -> String { - let u = Url::from_directory_path(util::std_path()).unwrap(); - u.to_string() -} - -itest!(globals { - args: "run --compat --no-check --unstable --allow-read --allow-env compat/globals.ts", - output: "compat/globals.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(fs_promises { - args: "run --compat --no-check --unstable -A compat/fs_promises.mjs", - output: "compat/fs_promises.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -// https://github.com/denoland/deno/issues/12494 -itest_flaky!(node_prefix_fs_promises { - args: "run --compat --no-check --unstable -A compat/node_fs_promises.mjs", - output: "compat/fs_promises.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(compat_with_import_map_and_https_imports { - args: "run --quiet --no-check --compat --unstable -A --import-map=compat/import_map.json compat/import_map_https_imports.mjs", - output: "compat/import_map_https_imports.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(compat_dyn_import_rejects_with_node_compatible_error { - args: - "run --quiet --no-check --compat --unstable -A compat/dyn_import_reject.js", - output: "compat/dyn_import_reject.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(import_esm_from_cjs { - args: - "run --compat --unstable -A --quiet compat/import_esm_from_cjs/index.js", - output_str: Some("function\n"), - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(test_runner_cjs { - args: "test --compat --unstable -A --quiet compat/test_runner/cjs.js", - exit_code: 1, - output: "compat/test_runner/cjs.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(test_runner_esm { - args: "test --compat --unstable -A --quiet compat/test_runner/esm.mjs", - exit_code: 1, - output: "compat/test_runner/esm.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -// Top level assertion test mostly just make sure that the test runner finishes correctly on compat mode -// when there is no tests -itest!(top_level_assertion_cjs { - args: "test --compat --unstable -A --quiet compat/test_runner/top_level_assertion_cjs.js", - exit_code: 0, - output: "compat/test_runner/top_level_assertion_cjs.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(top_level_assertion_esm { - args: "test --compat --unstable -A --quiet compat/test_runner/top_level_assertion_esm.mjs", - exit_code: 0, - output: "compat/test_runner/top_level_assertion_esm.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(top_level_fail_cjs { - args: "test --compat --unstable -A --quiet compat/test_runner/top_level_fail_cjs.js", - exit_code: 1, - output: "compat/test_runner/top_level_fail_cjs.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(top_level_fail_esm { - args: "test --compat --unstable -A --quiet compat/test_runner/top_level_fail_esm.mjs", - exit_code: 1, - output: "compat/test_runner/top_level_fail_esm.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(compat_worker { - args: "run --compat --unstable -A --quiet --no-check compat/worker/worker_test.mjs", - output: "compat/worker/worker_test.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(cjs_esm_interop { - args: - "run --compat --unstable -A --quiet --no-check compat/import_cjs_from_esm/main.mjs", - output: "compat/import_cjs_from_esm.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -itest!(cjs_esm_interop_dynamic { - args: - "run --compat --unstable -A --quiet --no-check compat/import_cjs_from_esm/main_dynamic.mjs", - output: "compat/import_cjs_from_esm.out", - envs: vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())], -}); - -#[test] -fn globals_in_repl() { - let (out, _err) = util::run_and_collect_output_with_args( - true, - vec!["repl", "--compat", "--unstable", "--no-check", "--quiet"], - Some(vec!["global.window == window"]), - Some(vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())]), - false, - ); - assert!(out.contains("true")); -} - -#[test] -fn require_in_repl() { - let (out, _err) = util::run_and_collect_output_with_args( - true, - vec!["repl", "--compat", "--unstable", "--quiet"], - Some(vec![ - "const foo = require('./compat/import_esm_from_cjs/index');", - ]), - Some(vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())]), - false, - ); - assert!(out.contains("function")); -} - -#[test] -fn node_compat_url() { - let (out, err) = util::run_and_collect_output_with_args( - false, - vec!["repl", "--compat", "--unstable", "--no-check", "--quiet"], - None, - Some(vec![( - "DENO_NODE_COMPAT_URL".to_string(), - "file:///non_existent/".to_string(), - )]), - false, - ); - assert!(out.is_empty()); - assert!(!err.is_empty()); - assert!(err.contains("file:///non_existent/node/global.ts")); -} - -#[test] -fn native_modules_as_global_vars() { - let (out, _err) = util::run_and_collect_output_with_args( - true, - vec!["repl", "--compat", "--unstable", "--quiet"], - Some(vec!["if(cluster && v8 && sys) { true } else { false }"]), - Some(vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())]), - false, - ); - assert!(out.contains("true")); -} - -#[ignore] // todo(dsherret): re-enable -#[test] -fn ext_node_cjs_execution() { - let (out, _err) = util::run_and_collect_output_with_args( - true, - vec![ - "run", - "-A", - "--unstable", - "--quiet", - "commonjs/init.js", - "./example.js", - ], - None, - Some(vec![("DENO_NODE_COMPAT_URL".to_string(), std_file_url())]), - false, - ); - assert!(out.contains("{ hello: \"world\" }")); -} diff --git a/cli/tests/integration/mod.rs b/cli/tests/integration/mod.rs index 742c0e3a7..84ec34f2b 100644 --- a/cli/tests/integration/mod.rs +++ b/cli/tests/integration/mod.rs @@ -60,8 +60,6 @@ mod bundle; mod cache; #[path = "check_tests.rs"] mod check; -#[path = "compat_tests.rs"] -mod compat; #[path = "compile_tests.rs"] mod compile; #[path = "coverage_tests.rs"] diff --git a/cli/tests/testdata/compat/dyn_import_reject.js b/cli/tests/testdata/compat/dyn_import_reject.js deleted file mode 100644 index f9a99f0da..000000000 --- a/cli/tests/testdata/compat/dyn_import_reject.js +++ /dev/null @@ -1,4 +0,0 @@ -import("./foobar.js").catch((e) => { - console.log(e); - console.log(e.code); -}); diff --git a/cli/tests/testdata/compat/dyn_import_reject.out b/cli/tests/testdata/compat/dyn_import_reject.out deleted file mode 100644 index 1324c8aeb..000000000 --- a/cli/tests/testdata/compat/dyn_import_reject.out +++ /dev/null @@ -1,2 +0,0 @@ -TypeError: [ERR_MODULE_NOT_FOUND] Cannot find module "file://[WILDCARD]/testdata/compat/foobar.js" imported from "file://[WILDCARD]/testdata/compat/dyn_import_reject.js" -ERR_MODULE_NOT_FOUND diff --git a/cli/tests/testdata/compat/fs_promises.mjs b/cli/tests/testdata/compat/fs_promises.mjs deleted file mode 100644 index 3f7b4c935..000000000 --- a/cli/tests/testdata/compat/fs_promises.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import fs from "fs/promises"; -const data = await fs.readFile("compat/test.txt", "utf-8"); -console.log(data); diff --git a/cli/tests/testdata/compat/fs_promises.out b/cli/tests/testdata/compat/fs_promises.out deleted file mode 100644 index 368d06776..000000000 --- a/cli/tests/testdata/compat/fs_promises.out +++ /dev/null @@ -1,2 +0,0 @@ -[WILDCARD] -This is some example text that will be read using compatiblity mode. diff --git a/cli/tests/testdata/compat/globals.out b/cli/tests/testdata/compat/globals.out deleted file mode 100644 index 32230fda3..000000000 --- a/cli/tests/testdata/compat/globals.out +++ /dev/null @@ -1,9 +0,0 @@ -[WILDCARD] -process { -[WILDCARD] -} -[Function: Buffer] { -[WILDCARD] -} -[Function: setImmediate] -[Function: clearTimeout] diff --git a/cli/tests/testdata/compat/globals.ts b/cli/tests/testdata/compat/globals.ts deleted file mode 100644 index bd80fb3d7..000000000 --- a/cli/tests/testdata/compat/globals.ts +++ /dev/null @@ -1,4 +0,0 @@ -console.log(process); -console.log(Buffer); -console.log(setImmediate); -console.log(clearImmediate); diff --git a/cli/tests/testdata/compat/import_cjs_from_esm.out b/cli/tests/testdata/compat/import_cjs_from_esm.out deleted file mode 100644 index ffaa5e406..000000000 --- a/cli/tests/testdata/compat/import_cjs_from_esm.out +++ /dev/null @@ -1 +0,0 @@ -{ a: "A", b: "B", foo: "foo", bar: "bar", fizz: { buzz: "buzz", fizz: "FIZZ" } } diff --git a/cli/tests/testdata/compat/import_cjs_from_esm/imported.js b/cli/tests/testdata/compat/import_cjs_from_esm/imported.js deleted file mode 100644 index 49ab4c782..000000000 --- a/cli/tests/testdata/compat/import_cjs_from_esm/imported.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = { - a: "A", - b: "B", -}; -exports.foo = "foo"; -exports.bar = "bar"; -exports.fizz = require("./reexports.js"); - -console.log(exports); diff --git a/cli/tests/testdata/compat/import_cjs_from_esm/main.mjs b/cli/tests/testdata/compat/import_cjs_from_esm/main.mjs deleted file mode 100644 index 6fbed1b7c..000000000 --- a/cli/tests/testdata/compat/import_cjs_from_esm/main.mjs +++ /dev/null @@ -1 +0,0 @@ -import "./imported.js"; diff --git a/cli/tests/testdata/compat/import_cjs_from_esm/main_dynamic.mjs b/cli/tests/testdata/compat/import_cjs_from_esm/main_dynamic.mjs deleted file mode 100644 index b94033268..000000000 --- a/cli/tests/testdata/compat/import_cjs_from_esm/main_dynamic.mjs +++ /dev/null @@ -1,2 +0,0 @@ -const url = import.meta.resolve("./imported.js"); -await import(url); diff --git a/cli/tests/testdata/compat/import_cjs_from_esm/reexports.js b/cli/tests/testdata/compat/import_cjs_from_esm/reexports.js deleted file mode 100644 index 62edb7708..000000000 --- a/cli/tests/testdata/compat/import_cjs_from_esm/reexports.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("./reexports2.js"); diff --git a/cli/tests/testdata/compat/import_cjs_from_esm/reexports2.js b/cli/tests/testdata/compat/import_cjs_from_esm/reexports2.js deleted file mode 100644 index 183d833b0..000000000 --- a/cli/tests/testdata/compat/import_cjs_from_esm/reexports2.js +++ /dev/null @@ -1,2 +0,0 @@ -exports.buzz = "buzz"; -exports.fizz = "FIZZ"; diff --git a/cli/tests/testdata/compat/import_esm_from_cjs/index.js b/cli/tests/testdata/compat/import_esm_from_cjs/index.js deleted file mode 100644 index 4ba03e104..000000000 --- a/cli/tests/testdata/compat/import_esm_from_cjs/index.js +++ /dev/null @@ -1 +0,0 @@ -require("pure-cjs"); diff --git a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-cjs/index.js b/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-cjs/index.js deleted file mode 100644 index 35f7c3774..000000000 --- a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-cjs/index.js +++ /dev/null @@ -1,4 +0,0 @@ -async function run() { - const _result = await import('pure-esm'); -} -run() diff --git a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-cjs/package.json b/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-cjs/package.json deleted file mode 100644 index e854fd992..000000000 --- a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-cjs/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "pure-cjs", - "main": "./index.js" -} diff --git a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-esm/index.js b/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-esm/index.js deleted file mode 100644 index 898097cb5..000000000 --- a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-esm/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import fs from 'node:fs'; -console.log(typeof fs.chmod); diff --git a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-esm/package.json b/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-esm/package.json deleted file mode 100644 index a373d3ad9..000000000 --- a/cli/tests/testdata/compat/import_esm_from_cjs/node_modules/pure-esm/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "pure-esm", - "type": "module", - "main": "./index.js" -} diff --git a/cli/tests/testdata/compat/import_map.json b/cli/tests/testdata/compat/import_map.json deleted file mode 100644 index 8488f0140..000000000 --- a/cli/tests/testdata/compat/import_map.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "imports": { - "std/": "https://deno.land/std@0.126.0/" - } -} diff --git a/cli/tests/testdata/compat/import_map_https_imports.mjs b/cli/tests/testdata/compat/import_map_https_imports.mjs deleted file mode 100644 index d8c2a89c2..000000000 --- a/cli/tests/testdata/compat/import_map_https_imports.mjs +++ /dev/null @@ -1,7 +0,0 @@ -import { sortBy } from "std/collections/sort_by.ts"; -import { findSingle } from "https://deno.land/std@0.126.0/collections/find_single.ts"; -import os from "node:os"; - -console.log(sortBy([2, 3, 1], (it) => it)); -console.log(findSingle([2, 3, 1], (it) => it == 2)); -console.log("arch", os.arch()); diff --git a/cli/tests/testdata/compat/import_map_https_imports.out b/cli/tests/testdata/compat/import_map_https_imports.out deleted file mode 100644 index 7ee30676e..000000000 --- a/cli/tests/testdata/compat/import_map_https_imports.out +++ /dev/null @@ -1,3 +0,0 @@ -[ 1, 2, 3 ] -2 -arch [WILDCARD] diff --git a/cli/tests/testdata/compat/node_fs_promises.mjs b/cli/tests/testdata/compat/node_fs_promises.mjs deleted file mode 100644 index b2174b22b..000000000 --- a/cli/tests/testdata/compat/node_fs_promises.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import fs from "node:fs/promises"; -const data = await fs.readFile("compat/test.txt", "utf-8"); -console.log(data); diff --git a/cli/tests/testdata/compat/test.txt b/cli/tests/testdata/compat/test.txt deleted file mode 100644 index 422e7b0c0..000000000 --- a/cli/tests/testdata/compat/test.txt +++ /dev/null @@ -1 +0,0 @@ -This is some example text that will be read using compatiblity mode.
\ No newline at end of file diff --git a/cli/tests/testdata/compat/test_runner/cjs.js b/cli/tests/testdata/compat/test_runner/cjs.js deleted file mode 100644 index 96a1b5112..000000000 --- a/cli/tests/testdata/compat/test_runner/cjs.js +++ /dev/null @@ -1,9 +0,0 @@ -const { strictEqual } = require("assert"); - -Deno.test("Correct assertion", () => { - strictEqual(20, 20); -}); - -Deno.test("Failed assertion", () => { - strictEqual(10, 20); -}); diff --git a/cli/tests/testdata/compat/test_runner/cjs.out b/cli/tests/testdata/compat/test_runner/cjs.out deleted file mode 100644 index 2e1e29e61..000000000 --- a/cli/tests/testdata/compat/test_runner/cjs.out +++ /dev/null @@ -1,27 +0,0 @@ -running 2 tests from ./compat/test_runner/cjs.js -Correct assertion ... ok ([WILDCARD]) -Failed assertion ... FAILED ([WILDCARD]) - - ERRORS - -Failed assertion => ./compat/test_runner/cjs.js:[WILDCARD] -error: AssertionError: Values are not strictly equal: - - - [Diff] Actual / Expected - - -- 10 -+ 20 - - Error.captureStackTrace(this, stackStartFn || stackStartFunction); - ^ -[WILDCARD] - - FAILURES - -Failed assertion => ./compat/test_runner/cjs.js:[WILDCARD] - -FAILED | 1 passed | 1 failed ([WILDCARD]) - -error: Test failed diff --git a/cli/tests/testdata/compat/test_runner/esm.mjs b/cli/tests/testdata/compat/test_runner/esm.mjs deleted file mode 100644 index 54a9468a4..000000000 --- a/cli/tests/testdata/compat/test_runner/esm.mjs +++ /dev/null @@ -1,9 +0,0 @@ -import { strictEqual } from "assert"; - -Deno.test("Correct assertion", () => { - strictEqual(20, 20); -}); - -Deno.test("Failed assertion", () => { - strictEqual(10, 20); -}); diff --git a/cli/tests/testdata/compat/test_runner/esm.out b/cli/tests/testdata/compat/test_runner/esm.out deleted file mode 100644 index e69573da1..000000000 --- a/cli/tests/testdata/compat/test_runner/esm.out +++ /dev/null @@ -1,27 +0,0 @@ -running 2 tests from ./compat/test_runner/esm.mjs -Correct assertion ... ok ([WILDCARD]) -Failed assertion ... FAILED ([WILDCARD]) - - ERRORS - -Failed assertion => ./compat/test_runner/esm.mjs:[WILDCARD] -error: AssertionError: Values are not strictly equal: - - - [Diff] Actual / Expected - - -- 10 -+ 20 - - Error.captureStackTrace(this, stackStartFn || stackStartFunction); - ^ -[WILDCARD] - - FAILURES - -Failed assertion => ./compat/test_runner/esm.mjs:[WILDCARD] - -FAILED | 1 passed | 1 failed ([WILDCARD]) - -error: Test failed diff --git a/cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.js b/cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.js deleted file mode 100644 index 318e72d86..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.js +++ /dev/null @@ -1,4 +0,0 @@ -const { notStrictEqual, strictEqual } = require("assert"); - -notStrictEqual(require.main, module, "The module was loaded as a main module"); -strictEqual(20, 20); diff --git a/cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.out b/cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.out deleted file mode 100644 index f74853cfd..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.out +++ /dev/null @@ -1,4 +0,0 @@ -running 0 tests from [WILDCARD] - -ok | 0 passed | 0 failed ([WILDCARD]) - diff --git a/cli/tests/testdata/compat/test_runner/top_level_assertion_esm.mjs b/cli/tests/testdata/compat/test_runner/top_level_assertion_esm.mjs deleted file mode 100644 index 8c217fd55..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_assertion_esm.mjs +++ /dev/null @@ -1,4 +0,0 @@ -import assert, { strictEqual } from "assert"; - -assert(!import.meta.main, "The module was loaded as a main module"); -strictEqual(20, 20); diff --git a/cli/tests/testdata/compat/test_runner/top_level_assertion_esm.out b/cli/tests/testdata/compat/test_runner/top_level_assertion_esm.out deleted file mode 100644 index f74853cfd..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_assertion_esm.out +++ /dev/null @@ -1,4 +0,0 @@ -running 0 tests from [WILDCARD] - -ok | 0 passed | 0 failed ([WILDCARD]) - diff --git a/cli/tests/testdata/compat/test_runner/top_level_fail_cjs.js b/cli/tests/testdata/compat/test_runner/top_level_fail_cjs.js deleted file mode 100644 index 20f809794..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_fail_cjs.js +++ /dev/null @@ -1,4 +0,0 @@ -const { notStrictEqual, strictEqual } = require("assert"); - -notStrictEqual(require.main, module, "The module was loaded as a main module"); -strictEqual(10, 20); diff --git a/cli/tests/testdata/compat/test_runner/top_level_fail_cjs.out b/cli/tests/testdata/compat/test_runner/top_level_fail_cjs.out deleted file mode 100644 index e1777d98a..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_fail_cjs.out +++ /dev/null @@ -1,27 +0,0 @@ -Uncaught error from ./compat/test_runner/top_level_fail_cjs.js FAILED - - ERRORS - -./compat/test_runner/top_level_fail_cjs.js (uncaught error) -error: (in promise) AssertionError: Values are not strictly equal: - - - [Diff] Actual / Expected - - -- 10 -+ 20 - - Error.captureStackTrace(this, stackStartFn || stackStartFunction); - ^ - at [WILDCARD] -This error was not caught from a test and caused the test runner to fail on the referenced module. -It most likely originated from a dangling promise, event/timeout handler or top-level code. - - FAILURES - -./compat/test_runner/top_level_fail_cjs.js (uncaught error) - -FAILED | 0 passed | 1 failed ([WILDCARD]) - -error: Test failed diff --git a/cli/tests/testdata/compat/test_runner/top_level_fail_esm.mjs b/cli/tests/testdata/compat/test_runner/top_level_fail_esm.mjs deleted file mode 100644 index 918d8c6a8..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_fail_esm.mjs +++ /dev/null @@ -1,4 +0,0 @@ -import assert, { strictEqual } from "assert"; - -assert(!import.meta.main, "The module was loaded as a main module"); -strictEqual(10, 20); diff --git a/cli/tests/testdata/compat/test_runner/top_level_fail_esm.out b/cli/tests/testdata/compat/test_runner/top_level_fail_esm.out deleted file mode 100644 index d34de2c21..000000000 --- a/cli/tests/testdata/compat/test_runner/top_level_fail_esm.out +++ /dev/null @@ -1,27 +0,0 @@ -Uncaught error from ./compat/test_runner/top_level_fail_esm.mjs FAILED - - ERRORS - -./compat/test_runner/top_level_fail_esm.mjs (uncaught error) -error: AssertionError: Values are not strictly equal: - - - [Diff] Actual / Expected - - -- 10 -+ 20 - - Error.captureStackTrace(this, stackStartFn || stackStartFunction); - ^ - at [WILDCARD] -This error was not caught from a test and caused the test runner to fail on the referenced module. -It most likely originated from a dangling promise, event/timeout handler or top-level code. - - FAILURES - -./compat/test_runner/top_level_fail_esm.mjs (uncaught error) - -FAILED | 0 passed | 1 failed ([WILDCARD]) - -error: Test failed diff --git a/cli/tests/testdata/compat/worker/worker.mjs b/cli/tests/testdata/compat/worker/worker.mjs deleted file mode 100644 index eb7cfed19..000000000 --- a/cli/tests/testdata/compat/worker/worker.mjs +++ /dev/null @@ -1,9 +0,0 @@ -console.log("hello from worker"); - -self.onmessage = (e) => { - if (e.data != "hello") { - throw new Error("wrong message"); - } - - self.postMessage({ pid: process.pid }); -} diff --git a/cli/tests/testdata/compat/worker/worker_test.mjs b/cli/tests/testdata/compat/worker/worker_test.mjs deleted file mode 100644 index 8613dde0c..000000000 --- a/cli/tests/testdata/compat/worker/worker_test.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { deferred } from "../../../../../test_util/std/async/deferred.ts"; - -const promise = deferred(); -const url = import.meta.resolve("./worker.mjs"); -const worker = new Worker(url, { type: "module" }); - -worker.onmessage = (e) => { - const pid = e.data.pid; - if (typeof pid != "number") { - throw new Error("pid is not a number"); - } - console.log("process.pid from worker:", pid); - promise.resolve(); -}; - -worker.postMessage("hello"); -await promise; -worker.terminate(); diff --git a/cli/tests/testdata/compat/worker/worker_test.out b/cli/tests/testdata/compat/worker/worker_test.out deleted file mode 100644 index 373841945..000000000 --- a/cli/tests/testdata/compat/worker/worker_test.out +++ /dev/null @@ -1,2 +0,0 @@ -hello from worker -process.pid from worker: [WILDCARD] diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs index df4b46332..6928624ea 100644 --- a/cli/tools/installer.rs +++ b/cli/tools/installer.rs @@ -333,10 +333,6 @@ fn resolve_shim_data( executable_args.push("--no-prompt".to_string()); } - if flags.compat { - executable_args.push("--compat".to_string()); - } - if !flags.v8_flags.is_empty() { executable_args.push(format!("--v8-flags={}", flags.v8_flags.join(","))); } @@ -592,7 +588,6 @@ mod tests { allow_read: Some(vec![]), type_check_mode: TypeCheckMode::None, log_level: Some(Level::Error), - compat: true, ..Flags::default() }, &InstallFlags { @@ -613,7 +608,6 @@ mod tests { "--allow-read", "--allow-net", "--quiet", - "--compat", "http://localhost:4545/echo_server.ts", "--foobar", ] diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs index 99f2ce33d..6046654b9 100644 --- a/cli/tools/standalone.rs +++ b/cli/tools/standalone.rs @@ -275,7 +275,6 @@ pub fn compile_to_runtime_flags( lock: None, log_level: flags.log_level, type_check_mode: TypeCheckMode::Local, - compat: flags.compat, unsafely_ignore_certificate_errors: flags .unsafely_ignore_certificate_errors .clone(), diff --git a/cli/worker.rs b/cli/worker.rs index d36639821..22070fc18 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -23,7 +23,6 @@ use deno_runtime::BootstrapOptions; use crate::args::DenoSubcommand; use crate::checksum; -use crate::compat; use crate::errors; use crate::module_loader::CliModuleLoader; use crate::node; @@ -52,15 +51,6 @@ impl CliMainWorker { } pub async fn setup_repl(&mut self) -> Result<(), AnyError> { - if self.ps.options.compat() { - self.worker.execute_side_module(&compat::GLOBAL_URL).await?; - compat::add_global_require( - &mut self.worker.js_runtime, - self.main_module.as_str(), - )?; - self.worker.run_event_loop(false).await?; - compat::setup_builtin_modules(&mut self.worker.js_runtime)?; - } self.worker.run_event_loop(false).await?; Ok(()) } @@ -70,39 +60,7 @@ impl CliMainWorker { self.maybe_setup_coverage_collector().await?; log::debug!("main_module {}", self.main_module); - if self.ps.options.compat() { - // TODO(bartlomieju): fix me - assert_eq!(self.main_module.scheme(), "file"); - - // Set up Node globals - self.worker.execute_side_module(&compat::GLOBAL_URL).await?; - // And `module` module that we'll use for checking which - // loader to use and potentially load CJS module with. - // This allows to skip permission check for `--allow-net` - // which would otherwise be requested by dynamically importing - // this file. - self.worker.execute_side_module(&compat::MODULE_URL).await?; - - let use_esm_loader = - compat::check_if_should_use_esm_loader(&self.main_module)?; - - if use_esm_loader { - // ES module execution in Node compatiblity mode - self.worker.execute_main_module(&self.main_module).await?; - } else { - // CJS module execution in Node compatiblity mode - compat::load_cjs_module( - &mut self.worker.js_runtime, - &self - .main_module - .to_file_path() - .unwrap() - .display() - .to_string(), - true, - )?; - } - } else if self.is_main_cjs { + if self.is_main_cjs { self.initialize_main_module_for_node().await?; node::load_cjs_module_from_ext_node( &mut self.worker.js_runtime, @@ -160,13 +118,6 @@ impl CliMainWorker { /// Execute the given main module emitting load and unload events before and after execution /// respectively. pub async fn execute(&mut self) -> Result<(), AnyError> { - if self.inner.ps.options.compat() { - self - .inner - .worker - .execute_side_module(&compat::GLOBAL_URL) - .await?; - } self.inner.execute_main_module_possibly_with_npm().await?; self .inner @@ -240,32 +191,8 @@ impl CliMainWorker { // We only execute the specifier as a module if it is tagged with TestMode::Module or // TestMode::Both. if mode != TestMode::Documentation { - if self.ps.options.compat() { - self.worker.execute_side_module(&compat::GLOBAL_URL).await?; - self.worker.execute_side_module(&compat::MODULE_URL).await?; - - let use_esm_loader = - compat::check_if_should_use_esm_loader(&self.main_module)?; - - if use_esm_loader { - self.worker.execute_side_module(&self.main_module).await?; - } else { - compat::load_cjs_module( - &mut self.worker.js_runtime, - &self - .main_module - .to_file_path() - .unwrap() - .display() - .to_string(), - false, - )?; - self.worker.run_event_loop(false).await?; - } - } else { - // We execute the module module as a side module so that import.meta.main is not set. - self.execute_side_module_possibly_with_npm().await?; - } + // We execute the module module as a side module so that import.meta.main is not set. + self.execute_side_module_possibly_with_npm().await?; } self.worker.dispatch_load_event(&located_script_name!())?; @@ -331,32 +258,8 @@ impl CliMainWorker { pub async fn run_bench_specifier(&mut self) -> Result<(), AnyError> { self.worker.enable_bench(); - if self.ps.options.compat() { - self.worker.execute_side_module(&compat::GLOBAL_URL).await?; - self.worker.execute_side_module(&compat::MODULE_URL).await?; - - let use_esm_loader = - compat::check_if_should_use_esm_loader(&self.main_module)?; - - if use_esm_loader { - self.worker.execute_side_module(&self.main_module).await?; - } else { - compat::load_cjs_module( - &mut self.worker.js_runtime, - &self - .main_module - .to_file_path() - .unwrap() - .display() - .to_string(), - false, - )?; - self.worker.run_event_loop(false).await?; - } - } else { - // We execute the module module as a side module so that import.meta.main is not set. - self.execute_side_module_possibly_with_npm().await?; - } + // We execute the module module as a side module so that import.meta.main is not set. + self.execute_side_module_possibly_with_npm().await?; self.worker.dispatch_load_event(&located_script_name!())?; self.worker.run_benchmarks().await?; @@ -543,20 +446,13 @@ pub async fn create_main_worker( }) } +// TODO(bartlomieju): this callback could have default value +// and not be required fn create_web_worker_preload_module_callback( - ps: ProcState, + _ps: ProcState, ) -> Arc<WorkerEventCb> { - let compat = ps.options.compat(); - - Arc::new(move |mut worker| { - let fut = async move { - if compat { - worker.execute_side_module(&compat::GLOBAL_URL).await?; - worker.execute_side_module(&compat::MODULE_URL).await?; - } - - Ok(worker) - }; + Arc::new(move |worker| { + let fut = async move { Ok(worker) }; LocalFutureObj::new(Box::new(fut)) }) } |