diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-11-13 10:10:09 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-13 15:10:09 +0000 |
commit | f091d1ad69b4e5217ae3272b641171781a372c4f (patch) | |
tree | 4ef4f90ec8a6b5c977efb187449f8c59c45de5e1 /ext/node | |
parent | 6a4c6d83bacf5f03628a494778a30bce970f7cbc (diff) |
feat(node): stabilize detecting if CJS via `"type": "commonjs"` in a package.json (#26439)
This will respect `"type": "commonjs"` in a package.json to determine if
`.js`/`.jsx`/`.ts`/.tsx` files are CJS or ESM. If the file is found to
be ESM it will be loaded as ESM though.
Diffstat (limited to 'ext/node')
-rw-r--r-- | ext/node/lib.rs | 7 | ||||
-rw-r--r-- | ext/node/ops/require.rs | 44 | ||||
-rw-r--r-- | ext/node/polyfills/01_require.js | 31 | ||||
-rw-r--r-- | ext/node/polyfills/process.ts | 2 |
4 files changed, 33 insertions, 51 deletions
diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 6d320b92c..702c919f4 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -14,6 +14,7 @@ use deno_core::url::Url; #[allow(unused_imports)] use deno_core::v8; use deno_core::v8::ExternalReference; +use node_resolver::errors::ClosestPkgJsonError; use node_resolver::NpmResolverRc; use once_cell::sync::Lazy; @@ -157,6 +158,10 @@ pub trait NodeRequireLoader { ) -> Result<Cow<'a, Path>, AnyError>; fn load_text_file_lossy(&self, path: &Path) -> Result<String, AnyError>; + + /// Get if the module kind is maybe CJS and loading should determine + /// if its CJS or ESM. + fn is_maybe_cjs(&self, specifier: &Url) -> Result<bool, ClosestPkgJsonError>; } pub static NODE_ENV_VAR_ALLOWLIST: Lazy<HashSet<String>> = Lazy::new(|| { @@ -385,6 +390,7 @@ deno_core::extension!(deno_node, ops::require::op_require_proxy_path, ops::require::op_require_is_deno_dir_package, ops::require::op_require_resolve_deno_dir, + ops::require::op_require_is_maybe_cjs, ops::require::op_require_is_request_relative, ops::require::op_require_resolve_lookup_paths, ops::require::op_require_try_self_parent_path<P>, @@ -398,7 +404,6 @@ deno_core::extension!(deno_node, ops::require::op_require_read_file<P>, ops::require::op_require_as_file_path, ops::require::op_require_resolve_exports<P>, - ops::require::op_require_read_closest_package_json<P>, ops::require::op_require_read_package_scope<P>, ops::require::op_require_package_imports_resolve<P>, ops::require::op_require_break_on_next_statement, diff --git a/ext/node/ops/require.rs b/ext/node/ops/require.rs index 30db8b629..b7fa8feb2 100644 --- a/ext/node/ops/require.rs +++ b/ext/node/ops/require.rs @@ -1,16 +1,18 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use deno_core::error::AnyError; use deno_core::op2; use deno_core::url::Url; use deno_core::v8; use deno_core::JsRuntimeInspector; -use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_fs::FileSystemRc; +use deno_package_json::NodeModuleKind; use deno_package_json::PackageJsonRc; use deno_path_util::normalize_path; +use deno_path_util::url_from_file_path; use deno_path_util::url_to_file_path; -use node_resolver::NodeModuleKind; +use node_resolver::errors::ClosestPkgJsonError; use node_resolver::NodeResolutionMode; use node_resolver::REQUIRE_CONDITIONS; use std::borrow::Cow; @@ -217,17 +219,17 @@ pub fn op_require_resolve_deno_dir( state: &mut OpState, #[string] request: String, #[string] parent_filename: String, -) -> Option<String> { +) -> Result<Option<String>, AnyError> { let resolver = state.borrow::<NpmResolverRc>(); - resolver - .resolve_package_folder_from_package( - &request, - &ModuleSpecifier::from_file_path(&parent_filename).unwrap_or_else(|_| { - panic!("Url::from_file_path: [{:?}]", parent_filename) - }), - ) - .ok() - .map(|p| p.to_string_lossy().into_owned()) + Ok( + resolver + .resolve_package_folder_from_package( + &request, + &url_from_file_path(&PathBuf::from(parent_filename))?, + ) + .ok() + .map(|p| p.to_string_lossy().into_owned()), + ) } #[op2(fast)] @@ -564,19 +566,17 @@ where })) } -#[op2] -#[serde] -pub fn op_require_read_closest_package_json<P>( +#[op2(fast)] +pub fn op_require_is_maybe_cjs( state: &mut OpState, #[string] filename: String, -) -> Result<Option<PackageJsonRc>, node_resolver::errors::ClosestPkgJsonError> -where - P: NodePermissions + 'static, -{ +) -> Result<bool, ClosestPkgJsonError> { let filename = PathBuf::from(filename); - // permissions: allow reading the closest package.json files - let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>(); - pkg_json_resolver.get_closest_package_json_from_path(&filename) + let Ok(url) = url_from_file_path(&filename) else { + return Ok(false); + }; + let loader = state.borrow::<NodeRequireLoaderRc>(); + loader.is_maybe_cjs(&url) } #[op2] diff --git a/ext/node/polyfills/01_require.js b/ext/node/polyfills/01_require.js index 0d267ca44..083d4e49b 100644 --- a/ext/node/polyfills/01_require.js +++ b/ext/node/polyfills/01_require.js @@ -11,6 +11,7 @@ import { op_require_can_parse_as_esm, op_require_init_paths, op_require_is_deno_dir_package, + op_require_is_maybe_cjs, op_require_is_request_relative, op_require_node_module_paths, op_require_package_imports_resolve, @@ -19,7 +20,6 @@ import { op_require_path_is_absolute, op_require_path_resolve, op_require_proxy_path, - op_require_read_closest_package_json, op_require_read_file, op_require_read_package_scope, op_require_real_path, @@ -1060,36 +1060,13 @@ Module.prototype._compile = function (content, filename, format) { return result; }; -Module._extensions[".js"] = function (module, filename) { - const content = op_require_read_file(filename); - - let format; - if (StringPrototypeEndsWith(filename, ".js")) { - const pkg = op_require_read_closest_package_json(filename); - if (pkg?.type === "module") { - format = "module"; - } else if (pkg?.type === "commonjs") { - format = "commonjs"; - } - } - - module._compile(content, filename, format); -}; - -Module._extensions[".ts"] = +Module._extensions[".js"] = + Module._extensions[".ts"] = Module._extensions[".jsx"] = Module._extensions[".tsx"] = function (module, filename) { const content = op_require_read_file(filename); - - let format; - const pkg = op_require_read_closest_package_json(filename); - if (pkg?.type === "module") { - format = "module"; - } else if (pkg?.type === "commonjs") { - format = "commonjs"; - } - + const format = op_require_is_maybe_cjs(filename) ? undefined : "module"; module._compile(content, filename, format); }; diff --git a/ext/node/polyfills/process.ts b/ext/node/polyfills/process.ts index bf626e410..647376d5c 100644 --- a/ext/node/polyfills/process.ts +++ b/ext/node/polyfills/process.ts @@ -919,7 +919,7 @@ Object.defineProperty(argv, "1", { if (Deno.mainModule?.startsWith("file:")) { return pathFromURL(new URL(Deno.mainModule)); } else { - return join(Deno.cwd(), "$deno$node.js"); + return join(Deno.cwd(), "$deno$node.mjs"); } }, }); |