refactor(loader): extract out more module loading code from cli crate (#30084)
Some checks are pending
ci / test release macos-aarch64 (push) Blocked by required conditions
ci / bench release linux-x86_64 (push) Blocked by required conditions
ci / lint debug linux-x86_64 (push) Blocked by required conditions
ci / lint debug macos-x86_64 (push) Blocked by required conditions
ci / lint debug windows-x86_64 (push) Blocked by required conditions
ci / test debug linux-x86_64 (push) Blocked by required conditions
ci / test release linux-x86_64 (push) Blocked by required conditions
ci / test debug macos-x86_64 (push) Blocked by required conditions
ci / test release macos-x86_64 (push) Blocked by required conditions
ci / test debug windows-x86_64 (push) Blocked by required conditions
ci / test release windows-x86_64 (push) Blocked by required conditions
ci / pre-build (push) Waiting to run
ci / test debug linux-aarch64 (push) Blocked by required conditions
ci / test release linux-aarch64 (push) Blocked by required conditions
ci / test debug macos-aarch64 (push) Blocked by required conditions
ci / build libs (push) Blocked by required conditions
ci / publish canary (push) Blocked by required conditions

This commit is contained in:
David Sherret 2025-07-14 11:27:51 -04:00 committed by GitHub
parent 46009f7368
commit 489d9bbdcf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 324 additions and 267 deletions

View file

@ -947,11 +947,10 @@ impl CliFactory {
in_npm_pkg_checker.clone(), in_npm_pkg_checker.clone(),
self.main_module_graph_container().await?.clone(), self.main_module_graph_container().await?.clone(),
self.module_load_preparer().await?.clone(), self.module_load_preparer().await?.clone(),
resolver_factory.npm_module_loader()?.clone(),
npm_registry_permission_checker, npm_registry_permission_checker,
cli_npm_resolver.clone(), cli_npm_resolver.clone(),
resolver_factory.parsed_source_cache().clone(), resolver_factory.parsed_source_cache().clone(),
resolver_factory.prepared_module_loader()?.clone(), resolver_factory.module_loader()?.clone(),
self.resolver().await?.clone(), self.resolver().await?.clone(),
self.sys(), self.sys(),
maybe_eszip_loader, maybe_eszip_loader,

View file

@ -15,12 +15,12 @@ use std::sync::atomic::AtomicU16;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::time::SystemTime; use std::time::SystemTime;
use boxed_error::Boxed;
use deno_ast::MediaType; use deno_ast::MediaType;
use deno_ast::ModuleKind; use deno_ast::ModuleKind;
use deno_cache_dir::file_fetcher::FetchLocalOptions; use deno_cache_dir::file_fetcher::FetchLocalOptions;
use deno_core::FastString; use deno_core::FastString;
use deno_core::ModuleLoader; use deno_core::ModuleLoader;
use deno_core::ModuleResolutionError;
use deno_core::ModuleSource; use deno_core::ModuleSource;
use deno_core::ModuleSourceCode; use deno_core::ModuleSourceCode;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
@ -50,18 +50,18 @@ use deno_lib::npm::NpmRegistryReadPermissionChecker;
use deno_lib::util::hash::FastInsecureHasher; use deno_lib::util::hash::FastInsecureHasher;
use deno_lib::worker::CreateModuleLoaderResult; use deno_lib::worker::CreateModuleLoaderResult;
use deno_lib::worker::ModuleLoaderFactory; use deno_lib::worker::ModuleLoaderFactory;
use deno_path_util::PathToUrlError;
use deno_resolver::cache::ParsedSourceCache; use deno_resolver::cache::ParsedSourceCache;
use deno_resolver::file_fetcher::FetchOptions; use deno_resolver::file_fetcher::FetchOptions;
use deno_resolver::file_fetcher::FetchPermissionsOptionRef; use deno_resolver::file_fetcher::FetchPermissionsOptionRef;
use deno_resolver::graph::ResolveWithGraphErrorKind; use deno_resolver::graph::ResolveWithGraphErrorKind;
use deno_resolver::graph::ResolveWithGraphOptions; use deno_resolver::graph::ResolveWithGraphOptions;
use deno_resolver::loader::LoadCodeSourceError;
use deno_resolver::loader::LoadPreparedModuleError; use deno_resolver::loader::LoadPreparedModuleError;
use deno_resolver::loader::LoadedModule; use deno_resolver::loader::LoadedModule;
use deno_resolver::loader::LoadedModuleOrAsset; use deno_resolver::loader::LoadedModuleOrAsset;
use deno_resolver::loader::NpmModuleLoadError;
use deno_resolver::loader::StrippingTypesNodeModulesError; use deno_resolver::loader::StrippingTypesNodeModulesError;
use deno_resolver::npm::DenoInNpmPackageChecker; use deno_resolver::npm::DenoInNpmPackageChecker;
use deno_resolver::npm::ResolveNpmReqRefError;
use deno_runtime::code_cache; use deno_runtime::code_cache;
use deno_runtime::deno_node::NodeRequireLoader; use deno_runtime::deno_node::NodeRequireLoader;
use deno_runtime::deno_node::create_host_defined_options; use deno_runtime::deno_node::create_host_defined_options;
@ -103,12 +103,10 @@ use crate::util::progress_bar::ProgressBar;
use crate::util::text_encoding::code_without_source_map; use crate::util::text_encoding::code_without_source_map;
use crate::util::text_encoding::source_map_from_code; use crate::util::text_encoding::source_map_from_code;
pub type CliNpmModuleLoader =
deno_resolver::loader::DenoNpmModuleLoader<CliSys>;
pub type CliEmitter = pub type CliEmitter =
deno_resolver::emit::Emitter<DenoInNpmPackageChecker, CliSys>; deno_resolver::emit::Emitter<DenoInNpmPackageChecker, CliSys>;
pub type CliPreparedModuleLoader = pub type CliDenoResolverModuleLoader =
deno_resolver::loader::PreparedModuleLoader<DenoInNpmPackageChecker, CliSys>; deno_resolver::loader::ModuleLoader<CliSys>;
#[derive(Debug, thiserror::Error, deno_error::JsError)] #[derive(Debug, thiserror::Error, deno_error::JsError)]
pub enum PrepareModuleLoadError { pub enum PrepareModuleLoadError {
@ -330,12 +328,11 @@ struct SharedCliModuleLoaderState {
in_npm_pkg_checker: DenoInNpmPackageChecker, in_npm_pkg_checker: DenoInNpmPackageChecker,
main_module_graph_container: Arc<MainModuleGraphContainer>, main_module_graph_container: Arc<MainModuleGraphContainer>,
module_load_preparer: Arc<ModuleLoadPreparer>, module_load_preparer: Arc<ModuleLoadPreparer>,
npm_module_loader: Arc<CliNpmModuleLoader>,
npm_registry_permission_checker: npm_registry_permission_checker:
Arc<NpmRegistryReadPermissionChecker<CliSys>>, Arc<NpmRegistryReadPermissionChecker<CliSys>>,
npm_resolver: CliNpmResolver, npm_resolver: CliNpmResolver,
parsed_source_cache: Arc<ParsedSourceCache>, parsed_source_cache: Arc<ParsedSourceCache>,
prepared_module_loader: Arc<CliPreparedModuleLoader>, module_loader: Arc<CliDenoResolverModuleLoader>,
resolver: Arc<CliResolver>, resolver: Arc<CliResolver>,
sys: CliSys, sys: CliSys,
in_flight_loads_tracker: InFlightModuleLoadsTracker, in_flight_loads_tracker: InFlightModuleLoadsTracker,
@ -392,13 +389,12 @@ impl CliModuleLoaderFactory {
in_npm_pkg_checker: DenoInNpmPackageChecker, in_npm_pkg_checker: DenoInNpmPackageChecker,
main_module_graph_container: Arc<MainModuleGraphContainer>, main_module_graph_container: Arc<MainModuleGraphContainer>,
module_load_preparer: Arc<ModuleLoadPreparer>, module_load_preparer: Arc<ModuleLoadPreparer>,
npm_module_loader: Arc<CliNpmModuleLoader>,
npm_registry_permission_checker: Arc< npm_registry_permission_checker: Arc<
NpmRegistryReadPermissionChecker<CliSys>, NpmRegistryReadPermissionChecker<CliSys>,
>, >,
npm_resolver: CliNpmResolver, npm_resolver: CliNpmResolver,
parsed_source_cache: Arc<ParsedSourceCache>, parsed_source_cache: Arc<ParsedSourceCache>,
prepared_module_loader: Arc<CliPreparedModuleLoader>, module_loader: Arc<CliDenoResolverModuleLoader>,
resolver: Arc<CliResolver>, resolver: Arc<CliResolver>,
sys: CliSys, sys: CliSys,
maybe_eszip_loader: Option<Arc<EszipModuleLoader>>, maybe_eszip_loader: Option<Arc<EszipModuleLoader>>,
@ -421,11 +417,10 @@ impl CliModuleLoaderFactory {
in_npm_pkg_checker, in_npm_pkg_checker,
main_module_graph_container, main_module_graph_container,
module_load_preparer, module_load_preparer,
npm_module_loader,
npm_registry_permission_checker, npm_registry_permission_checker,
npm_resolver, npm_resolver,
parsed_source_cache, parsed_source_cache,
prepared_module_loader, module_loader,
resolver, resolver,
sys, sys,
in_flight_loads_tracker: InFlightModuleLoadsTracker { in_flight_loads_tracker: InFlightModuleLoadsTracker {
@ -530,14 +525,6 @@ struct ModuleCodeStringSource {
pub module_type: ModuleType, pub module_type: ModuleType,
} }
#[derive(Debug, thiserror::Error, deno_error::JsError)]
#[class(generic)]
#[error("Loading unprepared module: {}{}", .specifier, .maybe_referrer.as_ref().map(|r| format!(", imported from: {}", r)).unwrap_or_default())]
pub struct LoadUnpreparedModuleError {
specifier: ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>,
}
struct CliModuleLoaderInner<TGraphContainer: ModuleGraphContainer> { struct CliModuleLoaderInner<TGraphContainer: ModuleGraphContainer> {
lib: TsTypeLib, lib: TsTypeLib,
is_worker: bool, is_worker: bool,
@ -551,43 +538,30 @@ struct CliModuleLoaderInner<TGraphContainer: ModuleGraphContainer> {
loaded_files: RefCell<HashSet<ModuleSpecifier>>, loaded_files: RefCell<HashSet<ModuleSpecifier>>,
} }
#[derive(Debug, deno_error::JsError, Boxed)]
#[class(inherit)]
pub struct LoadCodeSourceError(pub Box<LoadCodeSourceErrorKind>);
#[derive(Debug, thiserror::Error, deno_error::JsError)] #[derive(Debug, thiserror::Error, deno_error::JsError)]
pub enum LoadCodeSourceErrorKind { pub enum ResolveReferrerError {
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
NpmModuleLoad(#[from] NpmModuleLoadError), UnableToGetCwd(#[from] UnableToGetCwdError),
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
LoadPreparedModule(#[from] LoadPreparedModuleError), PathToUrl(#[from] PathToUrlError),
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
LoadUnpreparedModule(#[from] LoadUnpreparedModuleError), ModuleResolution(#[from] ModuleResolutionError),
#[class(inherit)]
#[error(transparent)]
Core(#[from] deno_core::error::ModuleLoaderError),
#[class(inherit)]
#[error(transparent)]
PathToUrl(#[from] deno_path_util::PathToUrlError),
#[class(inherit)]
#[error(transparent)]
NpmReqRef(#[from] ResolveNpmReqRefError),
#[class(inherit)]
#[error(transparent)]
Fetch(#[from] deno_resolver::file_fetcher::FetchError),
} }
#[derive(Debug, thiserror::Error, deno_error::JsError)] #[derive(Debug, thiserror::Error, deno_error::JsError)]
pub enum CliModuleLoaderError { pub enum CliModuleLoaderError {
#[class(inherit)]
#[error(transparent)]
Fetch(deno_resolver::file_fetcher::FetchError),
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
LoadCodeSource(#[from] LoadCodeSourceError), LoadCodeSource(#[from] LoadCodeSourceError),
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
LoadPreparedModule(#[from] Box<LoadPreparedModuleError>), LoadPreparedModule(#[from] LoadPreparedModuleError),
#[class(generic)] #[class(generic)]
#[error( #[error(
"Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement." "Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement."
@ -595,10 +569,13 @@ pub enum CliModuleLoaderError {
MissingJsonAttribute, MissingJsonAttribute,
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
Core(#[from] Box<deno_core::error::ModuleLoaderError>), PathToUrl(#[from] PathToUrlError),
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
Other(#[from] JsErrorBox), ResolveNpmReqRef(#[from] deno_resolver::npm::ResolveNpmReqRefError),
#[class(inherit)]
#[error(transparent)]
ResolveReferrer(#[from] ResolveReferrerError),
} }
impl<TGraphContainer: ModuleGraphContainer> CliModuleLoader<TGraphContainer> { impl<TGraphContainer: ModuleGraphContainer> CliModuleLoader<TGraphContainer> {
@ -711,39 +688,10 @@ impl<TGraphContainer: ModuleGraphContainer>
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
maybe_referrer: Option<&ModuleSpecifier>, maybe_referrer: Option<&ModuleSpecifier>,
requested_module_type: &RequestedModuleType, requested_module_type: &RequestedModuleType,
) -> Result<ModuleCodeStringSource, LoadCodeSourceError> { ) -> Result<ModuleCodeStringSource, CliModuleLoaderError> {
let graph = self.graph_container.graph(); // this loader maintains npm specifiers in dynamic imports when resolving
let deno_resolver_requested_module_type = // so that they can be properly preloaded, but now we might receive them
as_deno_resolver_requested_module_type(requested_module_type); // here, so we need to actually resolve them to a file: specifier here
match self
.shared
.prepared_module_loader
.load_prepared_module(
&graph,
specifier,
&deno_resolver_requested_module_type,
)
.await
.map_err(LoadCodeSourceError::from)?
{
Some(module_or_asset) => match module_or_asset {
LoadedModuleOrAsset::Module(prepared_module) => {
Ok(self.loaded_module_to_module_code_string_source(
prepared_module,
requested_module_type,
))
}
LoadedModuleOrAsset::ExternalAsset { specifier } => {
self.load_asset(
specifier,
/* do not use dynamic import permissions because this was statically analyzable */ CheckSpecifierKind::Static,
requested_module_type
)
.await
.map_err(|err| LoadCodeSourceErrorKind::Fetch(err).into_box())
}
},
None => {
let specifier = if let Ok(reference) = let specifier = if let Ok(reference) =
NpmPackageReqReference::from_specifier(specifier) NpmPackageReqReference::from_specifier(specifier)
{ {
@ -753,11 +701,7 @@ impl<TGraphContainer: ModuleGraphContainer>
Some(r) => Cow::Borrowed(r), Some(r) => Cow::Borrowed(r),
// but the repl may also end up here and it won't have // but the repl may also end up here and it won't have
// a referrer so create a referrer for it here // a referrer so create a referrer for it here
None => Cow::Owned( None => Cow::Owned(self.resolve_referrer("")?),
self
.resolve_referrer("")
.map_err(LoadCodeSourceError::from)?,
),
}; };
Cow::Owned( Cow::Owned(
self self
@ -768,47 +712,50 @@ impl<TGraphContainer: ModuleGraphContainer>
&referrer, &referrer,
ResolutionMode::Import, ResolutionMode::Import,
NodeResolutionKind::Execution, NodeResolutionKind::Execution,
) )?
.map_err(LoadCodeSourceError::from)? .into_url()?,
.unwrap()
.into_url()
.map_err(LoadCodeSourceError::from)?,
) )
} else { } else {
Cow::Borrowed(specifier) Cow::Borrowed(specifier)
}; };
if self.shared.in_npm_pkg_checker.in_npm_package(&specifier) { let graph = self.graph_container.graph();
let loaded_module = self let deno_resolver_requested_module_type =
as_deno_resolver_requested_module_type(requested_module_type);
match self
.shared .shared
.npm_module_loader .module_loader
.load( .load(
&graph,
&specifier, &specifier,
maybe_referrer, maybe_referrer,
&deno_resolver_requested_module_type, &deno_resolver_requested_module_type,
) )
.await .await?
.map_err(LoadCodeSourceError::from)?; {
return Ok(self.loaded_module_to_module_code_string_source( LoadedModuleOrAsset::Module(prepared_module) => {
loaded_module, Ok(self.loaded_module_to_module_code_string_source(
prepared_module,
requested_module_type, requested_module_type,
)); ))
} }
LoadedModuleOrAsset::ExternalAsset {
match requested_module_type { specifier,
RequestedModuleType::Text | RequestedModuleType::Bytes => self statically_analyzable,
} => {
self
.load_asset( .load_asset(
&specifier, &specifier,
/* force using permissions because this was not statically analyzable */ CheckSpecifierKind::Dynamic, if statically_analyzable {
requested_module_type CheckSpecifierKind::Static
} else {
// force permissions
CheckSpecifierKind::Dynamic
},
requested_module_type,
) )
.await .await
.map_err(LoadCodeSourceError::from), .map_err(CliModuleLoaderError::Fetch)
_ => Err(LoadCodeSourceError::from(LoadUnpreparedModuleError {
specifier: specifier.into_owned(),
maybe_referrer: maybe_referrer.cloned(),
})),
}
} }
} }
} }
@ -820,7 +767,7 @@ impl<TGraphContainer: ModuleGraphContainer>
) -> ModuleCodeStringSource { ) -> ModuleCodeStringSource {
ModuleCodeStringSource { ModuleCodeStringSource {
code: loaded_module_source_to_module_source_code(loaded_module.source), code: loaded_module_source_to_module_source_code(loaded_module.source),
found_url: loaded_module.specifier.clone(), found_url: loaded_module.specifier.into_owned(),
module_type: module_type_from_media_and_requested_type( module_type: module_type_from_media_and_requested_type(
loaded_module.media_type, loaded_module.media_type,
requested_module_type, requested_module_type,
@ -976,7 +923,7 @@ impl<TGraphContainer: ModuleGraphContainer>
fn resolve_referrer( fn resolve_referrer(
&self, &self,
referrer: &str, referrer: &str,
) -> Result<ModuleSpecifier, ModuleLoaderError> { ) -> Result<ModuleSpecifier, ResolveReferrerError> {
let referrer = if referrer.is_empty() && self.shared.is_repl { let referrer = if referrer.is_empty() && self.shared.is_repl {
// FIXME(bartlomieju): this is a hacky way to provide compatibility with REPL // FIXME(bartlomieju): this is a hacky way to provide compatibility with REPL
// and `Deno.core.evalContext` API. Ideally we should always have a referrer filled // and `Deno.core.evalContext` API. Ideally we should always have a referrer filled
@ -985,19 +932,16 @@ impl<TGraphContainer: ModuleGraphContainer>
referrer referrer
}; };
if deno_core::specifier_has_uri_scheme(referrer) { Ok(if deno_path_util::specifier_has_uri_scheme(referrer) {
deno_core::resolve_url(referrer).map_err(|e| e.into()) deno_core::resolve_url(referrer)?
} else if referrer == "." { } else if referrer == "." {
// main module, use the initial cwd // main module, use the initial cwd
deno_core::resolve_path(referrer, &self.shared.initial_cwd) deno_path_util::resolve_path(referrer, &self.shared.initial_cwd)?
.map_err(|e| JsErrorBox::from_err(e).into())
} else { } else {
// this cwd check is slow, so try to avoid it // this cwd check is slow, so try to avoid it
let cwd = std::env::current_dir() let cwd = std::env::current_dir().map_err(UnableToGetCwdError)?;
.map_err(|e| JsErrorBox::from_err(UnableToGetCwdError(e)))?; deno_path_util::resolve_path(referrer, &cwd)?
deno_core::resolve_path(referrer, &cwd) })
.map_err(|e| JsErrorBox::from_err(e).into())
}
} }
#[allow(clippy::result_large_err)] #[allow(clippy::result_large_err)]
@ -1024,7 +968,9 @@ impl<TGraphContainer: ModuleGraphContainer>
Ok(()) Ok(())
} }
let referrer = self.resolve_referrer(raw_referrer)?; let referrer = self
.resolve_referrer(raw_referrer)
.map_err(JsErrorBox::from_err)?;
let graph = self.graph_container.graph(); let graph = self.graph_container.graph();
let result = self.shared.resolver.resolve_with_graph( let result = self.shared.resolver.resolve_with_graph(
graph.as_ref(), graph.as_ref(),
@ -1310,7 +1256,7 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
let source = self let source = self
.0 .0
.shared .shared
.prepared_module_loader .module_loader
.load_prepared_module_for_source_map_sync(&graph, &specifier) .load_prepared_module_for_source_map_sync(&graph, &specifier)
.ok()??; .ok()??;
source_map_from_code(source.source.as_bytes()).map(Cow::Owned) source_map_from_code(source.source.as_bytes()).map(Cow::Owned)

View file

@ -408,7 +408,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
let code_source = shared let code_source = shared
.npm_module_loader .npm_module_loader
.load( .load(
&original_specifier, Cow::Borrowed(&original_specifier),
maybe_referrer.as_ref(), maybe_referrer.as_ref(),
&as_deno_resolver_requested_module_type(&requested_module_type), &as_deno_resolver_requested_module_type(&requested_module_type),
) )
@ -416,7 +416,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
.map_err(JsErrorBox::from_err)?; .map_err(JsErrorBox::from_err)?;
let code_cache_entry = match requested_module_type { let code_cache_entry = match requested_module_type {
RequestedModuleType::None => shared.get_code_cache( RequestedModuleType::None => shared.get_code_cache(
code_source.specifier, &code_source.specifier,
code_source.source.as_bytes(), code_source.source.as_bytes(),
), ),
RequestedModuleType::Other(_) RequestedModuleType::Other(_)
@ -431,7 +431,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
), ),
loaded_module_source_to_module_source_code(code_source.source), loaded_module_source_to_module_source_code(code_source.source),
&original_specifier, &original_specifier,
code_source.specifier, &code_source.specifier,
code_cache_entry, code_cache_entry,
)) ))
} }

View file

@ -28,7 +28,9 @@ use deno_graph::ModuleErrorKind;
use deno_graph::Position; use deno_graph::Position;
use deno_resolver::graph::ResolveWithGraphError; use deno_resolver::graph::ResolveWithGraphError;
use deno_resolver::graph::ResolveWithGraphOptions; use deno_resolver::graph::ResolveWithGraphOptions;
use deno_resolver::loader::LoadPreparedModuleError; use deno_resolver::loader::LoadCodeSourceError;
use deno_resolver::loader::LoadCodeSourceErrorKind;
use deno_resolver::loader::LoadPreparedModuleErrorKind;
use deno_resolver::npm::managed::ResolvePkgFolderFromDenoModuleError; use deno_resolver::npm::managed::ResolvePkgFolderFromDenoModuleError;
use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::deno_permissions::PermissionsContainer;
use deno_semver::npm::NpmPackageReqReference; use deno_semver::npm::NpmPackageReqReference;
@ -55,8 +57,6 @@ use crate::graph_container::ModuleGraphContainer;
use crate::graph_container::ModuleGraphUpdatePermit; use crate::graph_container::ModuleGraphUpdatePermit;
use crate::module_loader::CliModuleLoader; use crate::module_loader::CliModuleLoader;
use crate::module_loader::CliModuleLoaderError; use crate::module_loader::CliModuleLoaderError;
use crate::module_loader::LoadCodeSourceError;
use crate::module_loader::LoadCodeSourceErrorKind;
use crate::module_loader::ModuleLoadPreparer; use crate::module_loader::ModuleLoadPreparer;
use crate::module_loader::PrepareModuleLoadOptions; use crate::module_loader::PrepareModuleLoadOptions;
use crate::node::CliNodeResolver; use crate::node::CliNodeResolver;
@ -669,15 +669,16 @@ impl BundleLoadError {
BundleLoadError::CliModuleLoader( BundleLoadError::CliModuleLoader(
CliModuleLoaderError::LoadCodeSource(LoadCodeSourceError(e)), CliModuleLoaderError::LoadCodeSource(LoadCodeSourceError(e)),
) => match &**e { ) => match &**e {
LoadCodeSourceErrorKind::LoadPreparedModule( LoadCodeSourceErrorKind::LoadPreparedModule(e) => match e.as_kind() {
LoadPreparedModuleError::Graph(e), LoadPreparedModuleErrorKind::Graph(e) => matches!(
) => matches!(
e.error.as_kind(), e.error.as_kind(),
ModuleErrorKind::UnsupportedMediaType { .. }, ModuleErrorKind::UnsupportedMediaType { .. },
), ),
_ => false, _ => false,
}, },
_ => false, _ => false,
},
_ => false,
} }
} }
} }

View file

@ -125,9 +125,8 @@ impl<TNpmCacheHttpClient: NpmCacheHttpClient, TSys: NpmInstallerSys>
} }
} }
None => { None => {
let err = Arc::new(JsErrorBox::generic( let err =
"npm specifiers were requested; but --no-npm is specified", Arc::new(JsErrorBox::from_err(deno_resolver::npm::NoNpmError));
));
NpmResolvePkgReqsResult { NpmResolvePkgReqsResult {
results: package_reqs results: package_reqs
.iter() .iter()

View file

@ -719,9 +719,7 @@ pub struct ResolverFactory<TSys: WorkspaceFactorySys> {
parsed_source_cache: crate::cache::ParsedSourceCacheRc, parsed_source_cache: crate::cache::ParsedSourceCacheRc,
pkg_json_resolver: Deferred<PackageJsonResolverRc<TSys>>, pkg_json_resolver: Deferred<PackageJsonResolverRc<TSys>>,
#[cfg(all(feature = "graph", feature = "deno_ast"))] #[cfg(all(feature = "graph", feature = "deno_ast"))]
prepared_module_loader: Deferred< module_loader: Deferred<crate::loader::ModuleLoaderRc<TSys>>,
crate::loader::PreparedModuleLoaderRc<DenoInNpmPackageChecker, TSys>,
>,
raw_deno_resolver: async_once_cell::OnceCell<DefaultRawDenoResolverRc<TSys>>, raw_deno_resolver: async_once_cell::OnceCell<DefaultRawDenoResolverRc<TSys>>,
workspace_factory: WorkspaceFactoryRc<TSys>, workspace_factory: WorkspaceFactoryRc<TSys>,
workspace_resolver: async_once_cell::OnceCell<WorkspaceResolverRc<TSys>>, workspace_resolver: async_once_cell::OnceCell<WorkspaceResolverRc<TSys>>,
@ -758,7 +756,7 @@ impl<TSys: WorkspaceFactorySys> ResolverFactory<TSys> {
parsed_source_cache: Default::default(), parsed_source_cache: Default::default(),
pkg_json_resolver: Default::default(), pkg_json_resolver: Default::default(),
#[cfg(all(feature = "graph", feature = "deno_ast"))] #[cfg(all(feature = "graph", feature = "deno_ast"))]
prepared_module_loader: Default::default(), module_loader: Default::default(),
workspace_factory, workspace_factory,
workspace_resolver: Default::default(), workspace_resolver: Default::default(),
options, options,
@ -1041,18 +1039,17 @@ impl<TSys: WorkspaceFactorySys> ResolverFactory<TSys> {
} }
#[cfg(all(feature = "graph", feature = "deno_ast"))] #[cfg(all(feature = "graph", feature = "deno_ast"))]
pub fn prepared_module_loader( pub fn module_loader(
&self, &self,
) -> Result< ) -> Result<&crate::loader::ModuleLoaderRc<TSys>, anyhow::Error> {
&crate::loader::PreparedModuleLoaderRc<DenoInNpmPackageChecker, TSys>, self.module_loader.get_or_try_init(|| {
anyhow::Error,
> {
self.prepared_module_loader.get_or_try_init(|| {
let cjs_tracker = self.cjs_tracker()?; let cjs_tracker = self.cjs_tracker()?;
Ok(new_rc(crate::loader::PreparedModuleLoader::new( Ok(new_rc(crate::loader::ModuleLoader::new(
cjs_tracker.clone(), cjs_tracker.clone(),
self.emitter()?.clone(), self.emitter()?.clone(),
self.in_npm_package_checker()?.clone(),
self.node_code_translator()?.clone(), self.node_code_translator()?.clone(),
self.npm_module_loader()?.clone(),
self.parsed_source_cache.clone(), self.parsed_source_cache.clone(),
self.workspace_factory.sys.clone(), self.workspace_factory.sys.clone(),
))) )))

View file

@ -302,18 +302,14 @@ impl<
} else { } else {
match NpmPackageReqReference::from_specifier(&specifier) { match NpmPackageReqReference::from_specifier(&specifier) {
Ok(reference) => { Ok(reference) => {
if let Some(url) = let url =
self.resolver.resolve_non_workspace_npm_req_ref_to_file( self.resolver.resolve_non_workspace_npm_req_ref_to_file(
&reference, &reference,
referrer, referrer,
options.mode, options.mode,
options.kind, options.kind,
)? )?;
{
url.into_url()? url.into_url()?
} else {
specifier.into_owned()
}
} }
_ => specifier.into_owned(), _ => specifier.into_owned(),
} }
@ -329,7 +325,7 @@ impl<
referrer: &Url, referrer: &Url,
resolution_mode: node_resolver::ResolutionMode, resolution_mode: node_resolver::ResolutionMode,
resolution_kind: node_resolver::NodeResolutionKind, resolution_kind: node_resolver::NodeResolutionKind,
) -> Result<Option<node_resolver::UrlOrPath>, npm::ResolveNpmReqRefError> { ) -> Result<node_resolver::UrlOrPath, npm::ResolveNpmReqRefError> {
self.resolver.resolve_non_workspace_npm_req_ref_to_file( self.resolver.resolve_non_workspace_npm_req_ref_to_file(
npm_req_ref, npm_req_ref,
referrer, referrer,

View file

@ -633,20 +633,22 @@ impl<
referrer: &Url, referrer: &Url,
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
resolution_kind: NodeResolutionKind, resolution_kind: NodeResolutionKind,
) -> Result<Option<node_resolver::UrlOrPath>, npm::ResolveNpmReqRefError> { ) -> Result<node_resolver::UrlOrPath, npm::ResolveNpmReqRefError> {
let Some(NodeAndNpmResolvers { let Some(NodeAndNpmResolvers {
npm_req_resolver, .. npm_req_resolver, ..
}) = &self.node_and_npm_resolver }) = &self.node_and_npm_resolver
else { else {
return Ok(None); return Err(npm::ResolveNpmReqRefError {
npm_req_ref: npm_req_ref.clone(),
err: npm::ResolveReqWithSubPathErrorKind::NoNpm(npm::NoNpmError)
.into_box(),
});
}; };
npm_req_resolver npm_req_resolver.resolve_req_reference(
.resolve_req_reference(
npm_req_ref, npm_req_ref,
referrer, referrer,
resolution_mode, resolution_mode,
resolution_kind, resolution_kind,
) )
.map(Some)
} }
} }

View file

@ -3,14 +3,14 @@
mod npm; mod npm;
#[cfg(all(feature = "graph", feature = "deno_ast"))] #[cfg(all(feature = "graph", feature = "deno_ast"))]
mod prepared; mod module_loader;
use std::borrow::Cow; use std::borrow::Cow;
use deno_media_type::MediaType; use deno_media_type::MediaType;
pub use npm::*;
#[cfg(all(feature = "graph", feature = "deno_ast"))] #[cfg(all(feature = "graph", feature = "deno_ast"))]
pub use prepared::*; pub use module_loader::*;
pub use npm::*;
use url::Url; use url::Url;
pub enum RequestedModuleType<'a> { pub enum RequestedModuleType<'a> {
@ -26,8 +26,18 @@ type ArcStr = std::sync::Arc<str>;
#[allow(clippy::disallowed_types)] #[allow(clippy::disallowed_types)]
type ArcBytes = std::sync::Arc<[u8]>; type ArcBytes = std::sync::Arc<[u8]>;
pub enum LoadedModuleOrAsset<'a> {
Module(LoadedModule<'a>),
/// An external asset that the caller must fetch.
ExternalAsset {
specifier: Cow<'a, Url>,
/// Whether this was a module the graph knows about.
statically_analyzable: bool,
},
}
pub struct LoadedModule<'a> { pub struct LoadedModule<'a> {
pub specifier: &'a Url, pub specifier: Cow<'a, Url>,
pub media_type: MediaType, pub media_type: MediaType,
pub source: LoadedModuleSource, pub source: LoadedModuleSource,
} }

View file

@ -2,32 +2,31 @@
use std::borrow::Cow; use std::borrow::Cow;
use deno_ast::MediaType; use boxed_error::Boxed;
use deno_ast::ModuleKind; use deno_ast::ModuleKind;
use deno_error::JsError;
use deno_graph::JsModule; use deno_graph::JsModule;
use deno_graph::JsonModule; use deno_graph::JsonModule;
use deno_graph::ModuleGraph; use deno_graph::ModuleGraph;
use deno_graph::WasmModule; use deno_graph::WasmModule;
use deno_media_type::MediaType;
use node_resolver::InNpmPackageChecker; use node_resolver::InNpmPackageChecker;
use node_resolver::analyze::NodeCodeTranslatorSys;
use node_resolver::errors::ClosestPkgJsonError; use node_resolver::errors::ClosestPkgJsonError;
use thiserror::Error;
use url::Url; use url::Url;
use super::DenoNpmModuleLoaderRc;
use super::LoadedModule; use super::LoadedModule;
use super::LoadedModuleOrAsset;
use super::LoadedModuleSource; use super::LoadedModuleSource;
use super::NpmModuleLoadError;
use super::RequestedModuleType; use super::RequestedModuleType;
use crate::cache::ParsedSourceCacheRc; use crate::cache::ParsedSourceCacheRc;
use crate::cjs::CjsTrackerRc; use crate::cjs::CjsTrackerRc;
use crate::cjs::analyzer::DenoCjsCodeAnalyzerSys;
use crate::emit::EmitParsedSourceHelperError; use crate::emit::EmitParsedSourceHelperError;
use crate::emit::EmitterRc; use crate::emit::EmitterRc;
use crate::emit::EmitterSys;
use crate::factory::DenoNodeCodeTranslatorRc; use crate::factory::DenoNodeCodeTranslatorRc;
use crate::graph::EnhanceGraphErrorMode; use crate::graph::EnhanceGraphErrorMode;
use crate::graph::enhance_graph_error; use crate::graph::enhance_graph_error;
use crate::npm::NpmResolverSys; use crate::npm::DenoInNpmPackageChecker;
#[allow(clippy::disallowed_types)] #[allow(clippy::disallowed_types)]
type ArcStr = std::sync::Arc<str>; type ArcStr = std::sync::Arc<str>;
@ -41,8 +40,12 @@ pub struct EnhancedGraphError {
pub message: String, pub message: String,
} }
#[derive(Debug, Error, JsError)] #[derive(Debug, deno_error::JsError, Boxed)]
pub enum LoadPreparedModuleError { #[class(inherit)]
pub struct LoadPreparedModuleError(pub Box<LoadPreparedModuleErrorKind>);
#[derive(Debug, thiserror::Error, deno_error::JsError)]
pub enum LoadPreparedModuleErrorKind {
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
Graph(#[from] EnhancedGraphError), Graph(#[from] EnhancedGraphError),
@ -67,24 +70,45 @@ pub enum LoadMaybeCjsError {
TranslateCjsToEsm(#[from] node_resolver::analyze::TranslateCjsToEsmError), TranslateCjsToEsm(#[from] node_resolver::analyze::TranslateCjsToEsmError),
} }
#[allow(clippy::disallowed_types)] #[derive(Debug, deno_error::JsError, Boxed)]
pub type PreparedModuleLoaderRc<TInNpmPackageChecker, TSys> = #[class(inherit)]
crate::sync::MaybeArc<PreparedModuleLoader<TInNpmPackageChecker, TSys>>; pub struct LoadCodeSourceError(pub Box<LoadCodeSourceErrorKind>);
#[sys_traits::auto_impl] #[derive(Debug, thiserror::Error, deno_error::JsError)]
pub trait PreparedModuleLoaderSys: pub enum LoadCodeSourceErrorKind {
EmitterSys + NodeCodeTranslatorSys + DenoCjsCodeAnalyzerSys + NpmResolverSys #[class(inherit)]
{ #[error(transparent)]
LoadPreparedModule(#[from] LoadPreparedModuleError),
#[class(inherit)]
#[error(transparent)]
NpmModuleLoad(#[from] NpmModuleLoadError),
#[class(inherit)]
#[error(transparent)]
PathToUrl(#[from] deno_path_util::PathToUrlError),
#[class(inherit)]
#[error(transparent)]
LoadUnpreparedModule(#[from] LoadUnpreparedModuleError),
} }
pub enum LoadedModuleOrAsset<'graph> { #[derive(Debug, thiserror::Error, deno_error::JsError)]
Module(LoadedModule<'graph>), #[class(generic)]
/// A module that the graph knows about, but the data #[error("Loading unprepared module: {}{}", .specifier, .maybe_referrer.as_ref().map(|r| format!(", imported from: {}", r)).unwrap_or_default())]
/// is not stored in the graph itself. It's up to the caller pub struct LoadUnpreparedModuleError {
/// to fetch this data. specifier: Url,
ExternalAsset { maybe_referrer: Option<Url>,
specifier: &'graph Url, }
},
#[allow(clippy::disallowed_types)]
pub type ModuleLoaderRc<TSys> = crate::sync::MaybeArc<ModuleLoader<TSys>>;
#[sys_traits::auto_impl]
pub trait ModuleLoaderSys:
super::NpmModuleLoaderSys
+ crate::emit::EmitterSys
+ node_resolver::analyze::NodeCodeTranslatorSys
+ crate::cjs::analyzer::DenoCjsCodeAnalyzerSys
+ crate::npm::NpmResolverSys
{
} }
enum CodeOrDeferredEmit<'a> { enum CodeOrDeferredEmit<'a> {
@ -104,36 +128,106 @@ enum CodeOrDeferredEmit<'a> {
}, },
} }
pub struct PreparedModuleLoader< pub struct ModuleLoader<TSys: ModuleLoaderSys> {
TInNpmPackageChecker: InNpmPackageChecker, in_npm_pkg_checker: DenoInNpmPackageChecker,
TSys: PreparedModuleLoaderSys, npm_module_loader: DenoNpmModuleLoaderRc<TSys>,
> { prepared_module_loader: PreparedModuleLoader<TSys>,
cjs_tracker: CjsTrackerRc<TInNpmPackageChecker, TSys>,
emitter: EmitterRc<TInNpmPackageChecker, TSys>,
node_code_translator: DenoNodeCodeTranslatorRc<TSys>,
parsed_source_cache: ParsedSourceCacheRc,
sys: TSys,
} }
impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys> impl<TSys: ModuleLoaderSys> ModuleLoader<TSys> {
PreparedModuleLoader<TInNpmPackageChecker, TSys> #[allow(clippy::too_many_arguments)]
{
pub fn new( pub fn new(
cjs_tracker: CjsTrackerRc<TInNpmPackageChecker, TSys>, cjs_tracker: CjsTrackerRc<DenoInNpmPackageChecker, TSys>,
emitter: EmitterRc<TInNpmPackageChecker, TSys>, emitter: EmitterRc<DenoInNpmPackageChecker, TSys>,
in_npm_pkg_checker: DenoInNpmPackageChecker,
node_code_translator: DenoNodeCodeTranslatorRc<TSys>, node_code_translator: DenoNodeCodeTranslatorRc<TSys>,
npm_module_loader: DenoNpmModuleLoaderRc<TSys>,
parsed_source_cache: ParsedSourceCacheRc, parsed_source_cache: ParsedSourceCacheRc,
sys: TSys, sys: TSys,
) -> Self { ) -> Self {
Self { Self {
in_npm_pkg_checker,
npm_module_loader,
prepared_module_loader: PreparedModuleLoader {
cjs_tracker, cjs_tracker,
emitter, emitter,
node_code_translator, node_code_translator,
parsed_source_cache, parsed_source_cache,
sys, sys,
},
} }
} }
/// Loads a module using the graph or file system.
///
/// Note that the referrer is only used to enhance error messages and
/// doesn't need to be provided.
pub async fn load<'a>(
&self,
graph: &'a ModuleGraph,
specifier: &'a Url,
// todo(#30074): we should remove passing the referrer in here and remove the
// referrer from all error messages. This should be up to deno_core to display.
maybe_referrer: Option<&Url>,
requested_module_type: &RequestedModuleType<'_>,
) -> Result<LoadedModuleOrAsset<'a>, LoadCodeSourceError> {
match self
.prepared_module_loader
.load_prepared_module(graph, specifier, requested_module_type)
.await
.map_err(LoadCodeSourceError::from)?
{
Some(module_or_asset) => Ok(module_or_asset),
None => {
if self.in_npm_pkg_checker.in_npm_package(specifier) {
let loaded_module = self
.npm_module_loader
.load(
Cow::Borrowed(specifier),
maybe_referrer,
requested_module_type,
)
.await
.map_err(LoadCodeSourceError::from)?;
return Ok(LoadedModuleOrAsset::Module(loaded_module));
}
match requested_module_type {
RequestedModuleType::Text | RequestedModuleType::Bytes => {
Ok(LoadedModuleOrAsset::ExternalAsset {
specifier: Cow::Borrowed(specifier),
statically_analyzable: false,
})
}
_ => Err(LoadCodeSourceError::from(LoadUnpreparedModuleError {
specifier: specifier.clone(),
maybe_referrer: maybe_referrer.cloned(),
})),
}
}
}
}
pub fn load_prepared_module_for_source_map_sync<'graph>(
&self,
graph: &'graph ModuleGraph,
specifier: &Url,
) -> Result<Option<LoadedModule<'graph>>, anyhow::Error> {
self
.prepared_module_loader
.load_prepared_module_for_source_map_sync(graph, specifier)
}
}
struct PreparedModuleLoader<TSys: ModuleLoaderSys> {
cjs_tracker: CjsTrackerRc<DenoInNpmPackageChecker, TSys>,
emitter: EmitterRc<DenoInNpmPackageChecker, TSys>,
node_code_translator: DenoNodeCodeTranslatorRc<TSys>,
parsed_source_cache: ParsedSourceCacheRc,
sys: TSys,
}
impl<TSys: ModuleLoaderSys> PreparedModuleLoader<TSys> {
pub async fn load_prepared_module<'graph>( pub async fn load_prepared_module<'graph>(
&self, &self,
graph: &'graph ModuleGraph, graph: &'graph ModuleGraph,
@ -165,7 +259,7 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
Ok(Some(LoadedModuleOrAsset::Module(LoadedModule { Ok(Some(LoadedModuleOrAsset::Module(LoadedModule {
// note: it's faster to provide a string to v8 if we know it's a string // note: it's faster to provide a string to v8 if we know it's a string
source: LoadedModuleSource::ArcStr(transpile_result), source: LoadedModuleSource::ArcStr(transpile_result),
specifier, specifier: Cow::Borrowed(specifier),
media_type, media_type,
}))) })))
} }
@ -178,14 +272,18 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
.await .await
.map(|text| { .map(|text| {
Some(LoadedModuleOrAsset::Module(LoadedModule { Some(LoadedModuleOrAsset::Module(LoadedModule {
specifier, specifier: Cow::Borrowed(specifier),
media_type, media_type,
source: LoadedModuleSource::ArcStr(text), source: LoadedModuleSource::ArcStr(text),
})) }))
}) })
.map_err(LoadPreparedModuleError::LoadMaybeCjs), .map_err(|e| LoadPreparedModuleErrorKind::LoadMaybeCjs(e).into_box()),
Some(CodeOrDeferredEmit::ExternalAsset { specifier }) => { Some(CodeOrDeferredEmit::ExternalAsset { specifier }) => {
Ok(Some(LoadedModuleOrAsset::ExternalAsset { specifier })) Ok(Some(LoadedModuleOrAsset::ExternalAsset {
specifier: Cow::Borrowed(specifier),
// came from graph, so yes
statically_analyzable: true,
}))
} }
None => Ok(None), None => Ok(None),
} }
@ -221,7 +319,7 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
Ok(Some(LoadedModule { Ok(Some(LoadedModule {
// note: it's faster to provide a string if we know it's a string // note: it's faster to provide a string if we know it's a string
source: LoadedModuleSource::ArcStr(transpile_result), source: LoadedModuleSource::ArcStr(transpile_result),
specifier, specifier: Cow::Borrowed(specifier),
media_type, media_type,
})) }))
} }
@ -263,7 +361,7 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
RequestedModuleType::Bytes => match source.try_get_original_bytes() { RequestedModuleType::Bytes => match source.try_get_original_bytes() {
Some(bytes) => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule { Some(bytes) => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule {
source: LoadedModuleSource::ArcBytes(bytes), source: LoadedModuleSource::ArcBytes(bytes),
specifier, specifier: Cow::Borrowed(specifier),
media_type: *media_type, media_type: *media_type,
}))), }))),
None => Ok(Some(CodeOrDeferredEmit::ExternalAsset { specifier })), None => Ok(Some(CodeOrDeferredEmit::ExternalAsset { specifier })),
@ -271,13 +369,13 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
RequestedModuleType::Text => { RequestedModuleType::Text => {
Ok(Some(CodeOrDeferredEmit::Source(LoadedModule { Ok(Some(CodeOrDeferredEmit::Source(LoadedModule {
source: LoadedModuleSource::ArcStr(source.text.clone()), source: LoadedModuleSource::ArcStr(source.text.clone()),
specifier, specifier: Cow::Borrowed(specifier),
media_type: *media_type, media_type: *media_type,
}))) })))
} }
_ => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule { _ => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule {
source: LoadedModuleSource::ArcStr(source.text.clone()), source: LoadedModuleSource::ArcStr(source.text.clone()),
specifier, specifier: Cow::Borrowed(specifier),
media_type: *media_type, media_type: *media_type,
}))), }))),
}, },
@ -291,7 +389,7 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
RequestedModuleType::Bytes => match source.try_get_original_bytes() { RequestedModuleType::Bytes => match source.try_get_original_bytes() {
Some(bytes) => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule { Some(bytes) => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule {
source: LoadedModuleSource::ArcBytes(bytes), source: LoadedModuleSource::ArcBytes(bytes),
specifier, specifier: Cow::Borrowed(specifier),
media_type: *media_type, media_type: *media_type,
}))), }))),
None => Ok(Some(CodeOrDeferredEmit::ExternalAsset { specifier })), None => Ok(Some(CodeOrDeferredEmit::ExternalAsset { specifier })),
@ -299,7 +397,7 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
RequestedModuleType::Text => { RequestedModuleType::Text => {
Ok(Some(CodeOrDeferredEmit::Source(LoadedModule { Ok(Some(CodeOrDeferredEmit::Source(LoadedModule {
source: LoadedModuleSource::ArcStr(source.text.clone()), source: LoadedModuleSource::ArcStr(source.text.clone()),
specifier, specifier: Cow::Borrowed(specifier),
media_type: *media_type, media_type: *media_type,
}))) })))
} }
@ -354,7 +452,7 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
Ok(Some(CodeOrDeferredEmit::Source(LoadedModule { Ok(Some(CodeOrDeferredEmit::Source(LoadedModule {
source: LoadedModuleSource::ArcStr(code), source: LoadedModuleSource::ArcStr(code),
specifier, specifier: Cow::Borrowed(specifier),
media_type: *media_type, media_type: *media_type,
}))) })))
} }
@ -363,7 +461,7 @@ impl<TInNpmPackageChecker: InNpmPackageChecker, TSys: PreparedModuleLoaderSys>
source, specifier, .. source, specifier, ..
})) => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule { })) => Ok(Some(CodeOrDeferredEmit::Source(LoadedModule {
source: LoadedModuleSource::ArcBytes(source.clone()), source: LoadedModuleSource::ArcBytes(source.clone()),
specifier, specifier: Cow::Borrowed(specifier),
media_type: MediaType::Wasm, media_type: MediaType::Wasm,
}))), }))),
Some(deno_graph::Module::External(module)) Some(deno_graph::Module::External(module))

View file

@ -82,12 +82,12 @@ fn format_dir_import_message(
if let Some(referrer) = maybe_referrer { if let Some(referrer) = maybe_referrer {
msg.push_str(" is not supported resolving import from "); msg.push_str(" is not supported resolving import from ");
msg.push_str(referrer.as_str()); msg.push_str(referrer.as_str());
}
if let Some(entrypoint_name) = suggestion { if let Some(entrypoint_name) = suggestion {
msg.push_str("\nDid you mean to import "); msg.push_str("\nDid you mean to import ");
msg.push_str(entrypoint_name); msg.push_str(entrypoint_name);
msg.push_str(" within the directory?"); msg.push_str(" within the directory?");
} }
}
msg msg
} }
@ -160,11 +160,11 @@ impl<
pub async fn load<'a>( pub async fn load<'a>(
&self, &self,
specifier: &'a Url, specifier: Cow<'a, Url>,
maybe_referrer: Option<&Url>, maybe_referrer: Option<&Url>,
requested_module_type: &RequestedModuleType<'_>, requested_module_type: &RequestedModuleType<'_>,
) -> Result<LoadedModule<'a>, NpmModuleLoadError> { ) -> Result<LoadedModule<'a>, NpmModuleLoadError> {
let file_path = deno_path_util::url_to_file_path(specifier)?; let file_path = deno_path_util::url_to_file_path(&specifier)?;
let code = self.sys.fs_read(&file_path).map_err(|source| { let code = self.sys.fs_read(&file_path).map_err(|source| {
if self.sys.fs_is_dir_no_err(&file_path) { if self.sys.fs_is_dir_no_err(&file_path) {
let suggestion = ["index.mjs", "index.js", "index.cjs"] let suggestion = ["index.mjs", "index.js", "index.cjs"]
@ -185,7 +185,7 @@ impl<
} }
})?; })?;
let media_type = MediaType::from_specifier(specifier); let media_type = MediaType::from_specifier(&specifier);
match requested_module_type { match requested_module_type {
RequestedModuleType::Text | RequestedModuleType::Bytes => { RequestedModuleType::Text | RequestedModuleType::Bytes => {
Ok(LoadedModule { Ok(LoadedModule {
@ -200,18 +200,18 @@ impl<
if media_type.is_emittable() { if media_type.is_emittable() {
return Err(NpmModuleLoadError::StrippingTypesNodeModules( return Err(NpmModuleLoadError::StrippingTypesNodeModules(
StrippingTypesNodeModulesError { StrippingTypesNodeModulesError {
specifier: specifier.clone(), specifier: specifier.into_owned(),
}, },
)); ));
} }
let source = if self.cjs_tracker.is_maybe_cjs(specifier, media_type)? { let source = if self.cjs_tracker.is_maybe_cjs(&specifier, media_type)? {
// translate cjs to esm if it's cjs and inject node globals // translate cjs to esm if it's cjs and inject node globals
let code = from_utf8_lossy_cow(code); let code = from_utf8_lossy_cow(code);
LoadedModuleSource::String( LoadedModuleSource::String(
self self
.node_code_translator .node_code_translator
.translate_cjs_to_esm(specifier, Some(code)) .translate_cjs_to_esm(&specifier, Some(code))
.await? .await?
.into_owned() .into_owned()
.into(), .into(),

View file

@ -125,6 +125,11 @@ pub enum ResolveIfForNpmPackageErrorKind {
NodeModulesOutOfDate(#[from] NodeModulesOutOfDateError), NodeModulesOutOfDate(#[from] NodeModulesOutOfDateError),
} }
#[derive(Debug, Error, JsError)]
#[error("npm specifiers were requested; but --no-npm is specified")]
#[class("generic")]
pub struct NoNpmError;
#[derive(Debug, JsError)] #[derive(Debug, JsError)]
#[class(inherit)] #[class(inherit)]
pub struct ResolveNpmReqRefError { pub struct ResolveNpmReqRefError {
@ -151,6 +156,7 @@ pub struct ResolveReqWithSubPathError(pub Box<ResolveReqWithSubPathErrorKind>);
impl ResolveReqWithSubPathError { impl ResolveReqWithSubPathError {
pub fn maybe_specifier(&self) -> Option<Cow<UrlOrPath>> { pub fn maybe_specifier(&self) -> Option<Cow<UrlOrPath>> {
match self.as_kind() { match self.as_kind() {
ResolveReqWithSubPathErrorKind::NoNpm(_) => None,
ResolveReqWithSubPathErrorKind::MissingPackageNodeModulesFolder(err) => { ResolveReqWithSubPathErrorKind::MissingPackageNodeModulesFolder(err) => {
err.inner.maybe_specifier() err.inner.maybe_specifier()
} }
@ -171,6 +177,9 @@ pub enum ResolveReqWithSubPathErrorKind {
MissingPackageNodeModulesFolder(#[from] MissingPackageNodeModulesFolderError), MissingPackageNodeModulesFolder(#[from] MissingPackageNodeModulesFolderError),
#[class(inherit)] #[class(inherit)]
#[error(transparent)] #[error(transparent)]
NoNpm(NoNpmError),
#[class(inherit)]
#[error(transparent)]
ResolvePkgFolderFromDenoReq( ResolvePkgFolderFromDenoReq(
#[from] ContextedResolvePkgFolderFromDenoReqError, #[from] ContextedResolvePkgFolderFromDenoReqError,
), ),
@ -182,6 +191,7 @@ pub enum ResolveReqWithSubPathErrorKind {
impl ResolveReqWithSubPathErrorKind { impl ResolveReqWithSubPathErrorKind {
pub fn as_types_not_found(&self) -> Option<&TypesNotFoundError> { pub fn as_types_not_found(&self) -> Option<&TypesNotFoundError> {
match self { match self {
ResolveReqWithSubPathErrorKind::NoNpm(_) => None,
ResolveReqWithSubPathErrorKind::MissingPackageNodeModulesFolder(_) ResolveReqWithSubPathErrorKind::MissingPackageNodeModulesFolder(_)
| ResolveReqWithSubPathErrorKind::ResolvePkgFolderFromDenoReq(_) => None, | ResolveReqWithSubPathErrorKind::ResolvePkgFolderFromDenoReq(_) => None,
ResolveReqWithSubPathErrorKind::PackageSubpathResolve( ResolveReqWithSubPathErrorKind::PackageSubpathResolve(
@ -192,6 +202,7 @@ impl ResolveReqWithSubPathErrorKind {
pub fn maybe_code(&self) -> Option<NodeJsErrorCode> { pub fn maybe_code(&self) -> Option<NodeJsErrorCode> {
match self { match self {
ResolveReqWithSubPathErrorKind::NoNpm(_) => None,
ResolveReqWithSubPathErrorKind::MissingPackageNodeModulesFolder(_) => { ResolveReqWithSubPathErrorKind::MissingPackageNodeModulesFolder(_) => {
None None
} }

View file

@ -856,8 +856,6 @@ pub enum ResolutionKind {
Execution, Execution,
/// Resolving for code that will be used for type information. /// Resolving for code that will be used for type information.
Types, Types,
/// Resolving for code that will be bundled.
Bundling,
} }
impl ResolutionKind { impl ResolutionKind {