summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-03-21 11:35:51 -0700
committerGitHub <noreply@github.com>2024-03-21 11:35:51 -0700
commit9abc722cc3a998b4f73103c4394b53cccdb5c83b (patch)
tree228a9eb9665439e52b9588830a80dd6c8ef1499e /cli
parenta90a6f3b291d2a30750c2578fc3763246a182dea (diff)
feat(node): load ES modules defined as CJS (#22945)
Changes the behaviour in Deno to just always load ES modules in npm packages even if they're defined as CJS. Closes #22818
Diffstat (limited to 'cli')
-rw-r--r--cli/cache/node.rs19
-rw-r--r--cli/node.rs58
-rw-r--r--cli/resolver.rs2
3 files changed, 50 insertions, 29 deletions
diff --git a/cli/cache/node.rs b/cli/cache/node.rs
index c9286c382..29658bd90 100644
--- a/cli/cache/node.rs
+++ b/cli/cache/node.rs
@@ -1,10 +1,11 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use deno_ast::CjsAnalysis;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_runtime::deno_webstorage::rusqlite::params;
+use crate::node::CliCjsAnalysis;
+
use super::cache_db::CacheDB;
use super::cache_db::CacheDBConfiguration;
use super::cache_db::CacheFailure;
@@ -59,7 +60,7 @@ impl NodeAnalysisCache {
&self,
specifier: &str,
expected_source_hash: &str,
- ) -> Option<CjsAnalysis> {
+ ) -> Option<CliCjsAnalysis> {
Self::ensure_ok(
self.inner.get_cjs_analysis(specifier, expected_source_hash),
)
@@ -69,7 +70,7 @@ impl NodeAnalysisCache {
&self,
specifier: &str,
source_hash: &str,
- cjs_analysis: &CjsAnalysis,
+ cjs_analysis: &CliCjsAnalysis,
) {
Self::ensure_ok(self.inner.set_cjs_analysis(
specifier,
@@ -93,7 +94,7 @@ impl NodeAnalysisCacheInner {
&self,
specifier: &str,
expected_source_hash: &str,
- ) -> Result<Option<CjsAnalysis>, AnyError> {
+ ) -> Result<Option<CliCjsAnalysis>, AnyError> {
let query = "
SELECT
data
@@ -118,7 +119,7 @@ impl NodeAnalysisCacheInner {
&self,
specifier: &str,
source_hash: &str,
- cjs_analysis: &CjsAnalysis,
+ cjs_analysis: &CliCjsAnalysis,
) -> Result<(), AnyError> {
let sql = "
INSERT OR REPLACE INTO
@@ -147,7 +148,7 @@ mod test {
let cache = NodeAnalysisCacheInner::new(conn);
assert!(cache.get_cjs_analysis("file.js", "2").unwrap().is_none());
- let cjs_analysis = CjsAnalysis {
+ let cjs_analysis = CliCjsAnalysis::Cjs {
exports: vec!["export1".to_string()],
reexports: vec!["re-export1".to_string()],
};
@@ -157,8 +158,7 @@ mod test {
assert!(cache.get_cjs_analysis("file.js", "3").unwrap().is_none()); // different hash
let actual_cjs_analysis =
cache.get_cjs_analysis("file.js", "2").unwrap().unwrap();
- assert_eq!(actual_cjs_analysis.exports, cjs_analysis.exports);
- assert_eq!(actual_cjs_analysis.reexports, cjs_analysis.reexports);
+ assert_eq!(actual_cjs_analysis, cjs_analysis);
// adding when already exists should not cause issue
cache
@@ -170,8 +170,7 @@ mod test {
let cache = NodeAnalysisCacheInner::new(conn);
let actual_analysis =
cache.get_cjs_analysis("file.js", "2").unwrap().unwrap();
- assert_eq!(actual_analysis.exports, cjs_analysis.exports);
- assert_eq!(actual_analysis.reexports, cjs_analysis.reexports);
+ assert_eq!(actual_analysis, cjs_analysis);
// now changing the cli version should clear it
let conn = cache.conn.recreate_with_version("2.0.0");
diff --git a/cli/node.rs b/cli/node.rs
index cbe0aaaf1..5f0ecc653 100644
--- a/cli/node.rs
+++ b/cli/node.rs
@@ -1,15 +1,15 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use std::borrow::Cow;
-
-use deno_ast::CjsAnalysis;
use deno_ast::MediaType;
use deno_ast::ModuleSpecifier;
use deno_core::error::AnyError;
use deno_runtime::deno_fs;
use deno_runtime::deno_node::analyze::CjsAnalysis as ExtNodeCjsAnalysis;
+use deno_runtime::deno_node::analyze::CjsAnalysisExports;
use deno_runtime::deno_node::analyze::CjsCodeAnalyzer;
use deno_runtime::deno_node::analyze::NodeCodeTranslator;
+use serde::Deserialize;
+use serde::Serialize;
use crate::cache::NodeAnalysisCache;
use crate::util::fs::canonicalize_path_maybe_not_exists;
@@ -35,6 +35,17 @@ pub fn resolve_specifier_into_node_modules(
.unwrap_or_else(|| specifier.clone())
}
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub enum CliCjsAnalysis {
+ /// The module was found to be an ES module.
+ Esm,
+ /// The module was CJS.
+ Cjs {
+ exports: Vec<String>,
+ reexports: Vec<String>,
+ },
+}
+
pub struct CliCjsCodeAnalyzer {
cache: NodeAnalysisCache,
fs: deno_fs::FileSystemRc,
@@ -49,7 +60,7 @@ impl CliCjsCodeAnalyzer {
&self,
specifier: &ModuleSpecifier,
source: &str,
- ) -> Result<CjsAnalysis, AnyError> {
+ ) -> Result<CliCjsAnalysis, AnyError> {
let source_hash = NodeAnalysisCache::compute_source_hash(source);
if let Some(analysis) = self
.cache
@@ -60,13 +71,13 @@ impl CliCjsCodeAnalyzer {
let media_type = MediaType::from_specifier(specifier);
if media_type == MediaType::Json {
- return Ok(CjsAnalysis {
+ return Ok(CliCjsAnalysis::Cjs {
exports: vec![],
reexports: vec![],
});
}
- let parsed_source = deno_ast::parse_script(deno_ast::ParseParams {
+ let parsed_source = deno_ast::parse_program(deno_ast::ParseParams {
specifier: specifier.clone(),
text_info: deno_ast::SourceTextInfo::new(source.into()),
media_type,
@@ -74,7 +85,15 @@ impl CliCjsCodeAnalyzer {
scope_analysis: false,
maybe_syntax: None,
})?;
- let analysis = parsed_source.analyze_cjs();
+ let analysis = if parsed_source.is_script() {
+ let analysis = parsed_source.analyze_cjs();
+ CliCjsAnalysis::Cjs {
+ exports: analysis.exports,
+ reexports: analysis.reexports,
+ }
+ } else {
+ CliCjsAnalysis::Esm
+ };
self
.cache
.set_cjs_analysis(specifier.as_str(), &source_hash, &analysis);
@@ -87,20 +106,23 @@ impl CjsCodeAnalyzer for CliCjsCodeAnalyzer {
fn analyze_cjs(
&self,
specifier: &ModuleSpecifier,
- source: Option<&str>,
+ source: Option<String>,
) -> Result<ExtNodeCjsAnalysis, AnyError> {
let source = match source {
- Some(source) => Cow::Borrowed(source),
- None => Cow::Owned(
- self
- .fs
- .read_text_file_sync(&specifier.to_file_path().unwrap())?,
- ),
+ Some(source) => source,
+ None => self
+ .fs
+ .read_text_file_sync(&specifier.to_file_path().unwrap())?,
};
let analysis = self.inner_cjs_analysis(specifier, &source)?;
- Ok(ExtNodeCjsAnalysis {
- exports: analysis.exports,
- reexports: analysis.reexports,
- })
+ match analysis {
+ CliCjsAnalysis::Esm => Ok(ExtNodeCjsAnalysis::Esm(source)),
+ CliCjsAnalysis::Cjs { exports, reexports } => {
+ Ok(ExtNodeCjsAnalysis::Cjs(CjsAnalysisExports {
+ exports,
+ reexports,
+ }))
+ }
+ }
}
}
diff --git a/cli/resolver.rs b/cli/resolver.rs
index 495b3f9b5..6594bf2d4 100644
--- a/cli/resolver.rs
+++ b/cli/resolver.rs
@@ -334,7 +334,7 @@ impl NpmModuleLoader {
// translate cjs to esm if it's cjs and inject node globals
self.node_code_translator.translate_cjs_to_esm(
specifier,
- Some(code.as_str()),
+ Some(code),
permissions,
)?
} else {