mirror of
https://github.com/denoland/deno.git
synced 2024-11-30 16:40:57 -05:00
refactor(ext/node): CjsCodeAnalyzer - analyze_cjs optionally pass source text (#19896)
This commit is contained in:
parent
e14281cf51
commit
36cce3f287
4 changed files with 43 additions and 29 deletions
|
@ -475,7 +475,8 @@ impl CliFactory {
|
||||||
let caches = self.caches()?;
|
let caches = self.caches()?;
|
||||||
let node_analysis_cache =
|
let node_analysis_cache =
|
||||||
NodeAnalysisCache::new(caches.node_analysis_db());
|
NodeAnalysisCache::new(caches.node_analysis_db());
|
||||||
let cjs_esm_analyzer = CliCjsCodeAnalyzer::new(node_analysis_cache);
|
let cjs_esm_analyzer =
|
||||||
|
CliCjsCodeAnalyzer::new(node_analysis_cache, self.fs().clone());
|
||||||
|
|
||||||
Ok(Arc::new(NodeCodeTranslator::new(
|
Ok(Arc::new(NodeCodeTranslator::new(
|
||||||
cjs_esm_analyzer,
|
cjs_esm_analyzer,
|
||||||
|
|
18
cli/node.rs
18
cli/node.rs
|
@ -1,9 +1,12 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use deno_ast::CjsAnalysis;
|
use deno_ast::CjsAnalysis;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::error::AnyError;
|
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::CjsAnalysis as ExtNodeCjsAnalysis;
|
||||||
use deno_runtime::deno_node::analyze::CjsCodeAnalyzer;
|
use deno_runtime::deno_node::analyze::CjsCodeAnalyzer;
|
||||||
use deno_runtime::deno_node::analyze::NodeCodeTranslator;
|
use deno_runtime::deno_node::analyze::NodeCodeTranslator;
|
||||||
|
@ -34,11 +37,12 @@ pub fn resolve_specifier_into_node_modules(
|
||||||
|
|
||||||
pub struct CliCjsCodeAnalyzer {
|
pub struct CliCjsCodeAnalyzer {
|
||||||
cache: NodeAnalysisCache,
|
cache: NodeAnalysisCache,
|
||||||
|
fs: deno_fs::FileSystemRc,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliCjsCodeAnalyzer {
|
impl CliCjsCodeAnalyzer {
|
||||||
pub fn new(cache: NodeAnalysisCache) -> Self {
|
pub fn new(cache: NodeAnalysisCache, fs: deno_fs::FileSystemRc) -> Self {
|
||||||
Self { cache }
|
Self { cache, fs }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inner_cjs_analysis(
|
fn inner_cjs_analysis(
|
||||||
|
@ -83,9 +87,15 @@ impl CjsCodeAnalyzer for CliCjsCodeAnalyzer {
|
||||||
fn analyze_cjs(
|
fn analyze_cjs(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
source: &str,
|
source: Option<&str>,
|
||||||
) -> Result<ExtNodeCjsAnalysis, AnyError> {
|
) -> Result<ExtNodeCjsAnalysis, AnyError> {
|
||||||
let analysis = self.inner_cjs_analysis(specifier, source)?;
|
let source = match source {
|
||||||
|
Some(source) => Cow::Borrowed(source),
|
||||||
|
None => {
|
||||||
|
Cow::Owned(self.fs.read_to_string(&specifier.to_file_path().unwrap())?)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let analysis = self.inner_cjs_analysis(specifier, &source)?;
|
||||||
Ok(ExtNodeCjsAnalysis {
|
Ok(ExtNodeCjsAnalysis {
|
||||||
exports: analysis.exports,
|
exports: analysis.exports,
|
||||||
reexports: analysis.reexports,
|
reexports: analysis.reexports,
|
||||||
|
|
|
@ -366,7 +366,8 @@ pub async fn run(
|
||||||
let cjs_resolutions = Arc::new(CjsResolutionStore::default());
|
let cjs_resolutions = Arc::new(CjsResolutionStore::default());
|
||||||
let cache_db = Caches::new(deno_dir_provider.clone());
|
let cache_db = Caches::new(deno_dir_provider.clone());
|
||||||
let node_analysis_cache = NodeAnalysisCache::new(cache_db.node_analysis_db());
|
let node_analysis_cache = NodeAnalysisCache::new(cache_db.node_analysis_db());
|
||||||
let cjs_esm_code_analyzer = CliCjsCodeAnalyzer::new(node_analysis_cache);
|
let cjs_esm_code_analyzer =
|
||||||
|
CliCjsCodeAnalyzer::new(node_analysis_cache, fs.clone());
|
||||||
let node_code_translator = Arc::new(NodeCodeTranslator::new(
|
let node_code_translator = Arc::new(NodeCodeTranslator::new(
|
||||||
cjs_esm_code_analyzer,
|
cjs_esm_code_analyzer,
|
||||||
fs.clone(),
|
fs.clone(),
|
||||||
|
|
|
@ -29,10 +29,15 @@ pub struct CjsAnalysis {
|
||||||
pub trait CjsCodeAnalyzer {
|
pub trait CjsCodeAnalyzer {
|
||||||
/// Analyzes CommonJs code for exports and reexports, which is
|
/// Analyzes CommonJs code for exports and reexports, which is
|
||||||
/// then used to determine the wrapper ESM module exports.
|
/// then used to determine the wrapper ESM module exports.
|
||||||
|
///
|
||||||
|
/// Note that the source is provided by the caller when the caller
|
||||||
|
/// already has it. If the source is needed by the implementation,
|
||||||
|
/// then it can use the provided source, or otherwise load it if
|
||||||
|
/// necessary.
|
||||||
fn analyze_cjs(
|
fn analyze_cjs(
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
source: &str,
|
maybe_source: Option<&str>,
|
||||||
) -> Result<CjsAnalysis, AnyError>;
|
) -> Result<CjsAnalysis, AnyError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +78,9 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
|
||||||
let mut temp_var_count = 0;
|
let mut temp_var_count = 0;
|
||||||
let mut handled_reexports: HashSet<String> = HashSet::default();
|
let mut handled_reexports: HashSet<String> = HashSet::default();
|
||||||
|
|
||||||
let analysis = self.cjs_code_analyzer.analyze_cjs(specifier, source)?;
|
let analysis = self
|
||||||
|
.cjs_code_analyzer
|
||||||
|
.analyze_cjs(specifier, Some(source))?;
|
||||||
|
|
||||||
let mut source = vec![
|
let mut source = vec![
|
||||||
r#"import {createRequire as __internalCreateRequire} from "node:module";
|
r#"import {createRequire as __internalCreateRequire} from "node:module";
|
||||||
|
@ -100,7 +107,7 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
|
||||||
|
|
||||||
handled_reexports.insert(reexport.to_string());
|
handled_reexports.insert(reexport.to_string());
|
||||||
|
|
||||||
// First, resolve relate reexport specifier
|
// First, resolve the reexport specifier
|
||||||
let resolved_reexport = self.resolve(
|
let resolved_reexport = self.resolve(
|
||||||
&reexport,
|
&reexport,
|
||||||
&referrer,
|
&referrer,
|
||||||
|
@ -110,35 +117,30 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer> NodeCodeTranslator<TCjsCodeAnalyzer> {
|
||||||
NodeResolutionMode::Execution,
|
NodeResolutionMode::Execution,
|
||||||
permissions,
|
permissions,
|
||||||
)?;
|
)?;
|
||||||
// Second, read the source code from disk
|
|
||||||
|
// Second, resolve its exports and re-exports
|
||||||
let reexport_specifier =
|
let reexport_specifier =
|
||||||
ModuleSpecifier::from_file_path(&resolved_reexport).unwrap();
|
ModuleSpecifier::from_file_path(&resolved_reexport).unwrap();
|
||||||
let reexport_file_text = self
|
let analysis = self
|
||||||
.fs
|
.cjs_code_analyzer
|
||||||
.read_to_string(&resolved_reexport)
|
.analyze_cjs(&reexport_specifier, None)
|
||||||
.map_err(AnyError::from)
|
|
||||||
.with_context(|| {
|
.with_context(|| {
|
||||||
format!(
|
format!(
|
||||||
"Could not find '{}' ({}) referenced from {}",
|
"Could not load '{}' ({}) referenced from {}",
|
||||||
reexport, reexport_specifier, referrer
|
reexport, reexport_specifier, referrer
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
{
|
|
||||||
let analysis = self
|
|
||||||
.cjs_code_analyzer
|
|
||||||
.analyze_cjs(&reexport_specifier, &reexport_file_text)?;
|
|
||||||
|
|
||||||
for reexport in analysis.reexports {
|
for reexport in analysis.reexports {
|
||||||
reexports_to_handle.push_back((reexport, reexport_specifier.clone()));
|
reexports_to_handle.push_back((reexport, reexport_specifier.clone()));
|
||||||
}
|
|
||||||
|
|
||||||
all_exports.extend(
|
|
||||||
analysis
|
|
||||||
.exports
|
|
||||||
.into_iter()
|
|
||||||
.filter(|e| e.as_str() != "default"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
all_exports.extend(
|
||||||
|
analysis
|
||||||
|
.exports
|
||||||
|
.into_iter()
|
||||||
|
.filter(|e| e.as_str() != "default"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
source.push(format!(
|
source.push(format!(
|
||||||
|
|
Loading…
Reference in a new issue