summaryrefslogtreecommitdiff
path: root/ext/node
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-11-13 10:10:09 -0500
committerGitHub <noreply@github.com>2024-11-13 15:10:09 +0000
commitf091d1ad69b4e5217ae3272b641171781a372c4f (patch)
tree4ef4f90ec8a6b5c977efb187449f8c59c45de5e1 /ext/node
parent6a4c6d83bacf5f03628a494778a30bce970f7cbc (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.rs7
-rw-r--r--ext/node/ops/require.rs44
-rw-r--r--ext/node/polyfills/01_require.js31
-rw-r--r--ext/node/polyfills/process.ts2
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");
}
},
});