summaryrefslogtreecommitdiff
path: root/cli/standalone/mod.rs
diff options
context:
space:
mode:
authorhaturau <135221985+haturatu@users.noreply.github.com>2024-11-20 01:20:47 +0900
committerGitHub <noreply@github.com>2024-11-20 01:20:47 +0900
commit85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch)
treeface0aecaac53e93ce2f23b53c48859bcf1a36ec /cli/standalone/mod.rs
parent67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff)
parent186b52731c6bb326c4d32905c5e732d082e83465 (diff)
Merge branch 'denoland:main' into main
Diffstat (limited to 'cli/standalone/mod.rs')
-rw-r--r--cli/standalone/mod.rs586
1 files changed, 379 insertions, 207 deletions
diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs
index 258de0dad..b9f0b1d5b 100644
--- a/cli/standalone/mod.rs
+++ b/cli/standalone/mod.rs
@@ -5,6 +5,9 @@
#![allow(dead_code)]
#![allow(unused_imports)]
+use binary::StandaloneData;
+use binary::StandaloneModules;
+use code_cache::DenoCompileCodeCache;
use deno_ast::MediaType;
use deno_cache_dir::npm::NpmCacheDir;
use deno_config::workspace::MappedResolution;
@@ -15,8 +18,10 @@ use deno_core::anyhow::Context;
use deno_core::error::generic_error;
use deno_core::error::type_error;
use deno_core::error::AnyError;
+use deno_core::futures::future::LocalBoxFuture;
use deno_core::futures::FutureExt;
use deno_core::v8_set_flags;
+use deno_core::FastString;
use deno_core::FeatureChecker;
use deno_core::ModuleLoader;
use deno_core::ModuleSourceCode;
@@ -24,11 +29,15 @@ use deno_core::ModuleSpecifier;
use deno_core::ModuleType;
use deno_core::RequestedModuleType;
use deno_core::ResolutionKind;
+use deno_core::SourceCodeCacheInfo;
use deno_npm::npm_rc::ResolvedNpmRc;
use deno_package_json::PackageJsonDepValue;
+use deno_resolver::npm::NpmReqResolverOptions;
use deno_runtime::deno_fs;
use deno_runtime::deno_node::create_host_defined_options;
+use deno_runtime::deno_node::NodeRequireLoader;
use deno_runtime::deno_node::NodeResolver;
+use deno_runtime::deno_node::PackageJsonResolver;
use deno_runtime::deno_permissions::Permissions;
use deno_runtime::deno_permissions::PermissionsContainer;
use deno_runtime::deno_tls::rustls::RootCertStore;
@@ -38,10 +47,12 @@ use deno_runtime::permissions::RuntimePermissionDescriptorParser;
use deno_runtime::WorkerExecutionMode;
use deno_runtime::WorkerLogLevel;
use deno_semver::npm::NpmPackageReqReference;
-use eszip::EszipRelativeFileBaseUrl;
use import_map::parse_from_json;
use node_resolver::analyze::NodeCodeTranslator;
+use node_resolver::errors::ClosestPkgJsonError;
+use node_resolver::NodeModuleKind;
use node_resolver::NodeResolutionMode;
+use serialization::DenoCompileModuleSource;
use std::borrow::Cow;
use std::rc::Rc;
use std::sync::Arc;
@@ -54,86 +65,102 @@ use crate::args::CacheSetting;
use crate::args::NpmInstallDepsProvider;
use crate::args::StorageKeyResolver;
use crate::cache::Caches;
+use crate::cache::DenoCacheEnvFsAdapter;
use crate::cache::DenoDirProvider;
+use crate::cache::FastInsecureHasher;
use crate::cache::NodeAnalysisCache;
use crate::cache::RealDenoCacheEnv;
use crate::http_util::HttpClientProvider;
use crate::node::CliCjsCodeAnalyzer;
+use crate::node::CliNodeCodeTranslator;
use crate::npm::create_cli_npm_resolver;
+use crate::npm::create_in_npm_pkg_checker;
use crate::npm::CliByonmNpmResolverCreateOptions;
+use crate::npm::CliManagedInNpmPkgCheckerCreateOptions;
+use crate::npm::CliManagedNpmResolverCreateOptions;
+use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
-use crate::npm::CliNpmResolverManagedCreateOptions;
use crate::npm::CliNpmResolverManagedSnapshotOption;
-use crate::resolver::CjsResolutionStore;
+use crate::npm::CreateInNpmPkgCheckerOptions;
+use crate::resolver::CjsTracker;
use crate::resolver::CliDenoResolverFs;
-use crate::resolver::CliNodeResolver;
+use crate::resolver::CliNpmReqResolver;
+use crate::resolver::IsCjsResolverOptions;
use crate::resolver::NpmModuleLoader;
use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle;
use crate::util::v8::construct_v8_flags;
+use crate::worker::CliCodeCache;
use crate::worker::CliMainWorkerFactory;
use crate::worker::CliMainWorkerOptions;
-use crate::worker::ModuleLoaderAndSourceMapGetter;
+use crate::worker::CreateModuleLoaderResult;
use crate::worker::ModuleLoaderFactory;
pub mod binary;
+mod code_cache;
mod file_system;
+mod serialization;
mod virtual_fs;
pub use binary::extract_standalone;
pub use binary::is_standalone_binary;
pub use binary::DenoCompileBinaryWriter;
-use self::binary::load_npm_vfs;
use self::binary::Metadata;
use self::file_system::DenoCompileFileSystem;
-struct WorkspaceEszipModule {
- specifier: ModuleSpecifier,
- inner: eszip::Module,
-}
-
-struct WorkspaceEszip {
- eszip: eszip::EszipV2,
- root_dir_url: Arc<ModuleSpecifier>,
+struct SharedModuleLoaderState {
+ cjs_tracker: Arc<CjsTracker>,
+ fs: Arc<dyn deno_fs::FileSystem>,
+ modules: StandaloneModules,
+ node_code_translator: Arc<CliNodeCodeTranslator>,
+ node_resolver: Arc<NodeResolver>,
+ npm_module_loader: Arc<NpmModuleLoader>,
+ npm_req_resolver: Arc<CliNpmReqResolver>,
+ npm_resolver: Arc<dyn CliNpmResolver>,
+ workspace_resolver: WorkspaceResolver,
+ code_cache: Option<Arc<dyn CliCodeCache>>,
}
-impl WorkspaceEszip {
- pub fn get_module(
+impl SharedModuleLoaderState {
+ fn get_code_cache(
&self,
specifier: &ModuleSpecifier,
- ) -> Option<WorkspaceEszipModule> {
- if specifier.scheme() == "file" {
- let specifier_key = EszipRelativeFileBaseUrl::new(&self.root_dir_url)
- .specifier_key(specifier);
- let module = self.eszip.get_module(&specifier_key)?;
- let specifier = self.root_dir_url.join(&module.specifier).unwrap();
- Some(WorkspaceEszipModule {
- specifier,
- inner: module,
- })
- } else {
- let module = self.eszip.get_module(specifier.as_str())?;
- Some(WorkspaceEszipModule {
- specifier: ModuleSpecifier::parse(&module.specifier).unwrap(),
- inner: module,
- })
+ source: &[u8],
+ ) -> Option<SourceCodeCacheInfo> {
+ let Some(code_cache) = &self.code_cache else {
+ return None;
+ };
+ if !code_cache.enabled() {
+ return None;
}
+ // deno version is already included in the root cache key
+ let hash = FastInsecureHasher::new_without_deno_version()
+ .write_hashable(source)
+ .finish();
+ let data = code_cache.get_sync(
+ specifier,
+ deno_runtime::code_cache::CodeCacheType::EsModule,
+ hash,
+ );
+ Some(SourceCodeCacheInfo {
+ hash,
+ data: data.map(Cow::Owned),
+ })
}
}
-struct SharedModuleLoaderState {
- eszip: WorkspaceEszip,
- workspace_resolver: WorkspaceResolver,
- node_resolver: Arc<CliNodeResolver>,
- npm_module_loader: Arc<NpmModuleLoader>,
-}
-
#[derive(Clone)]
struct EmbeddedModuleLoader {
shared: Arc<SharedModuleLoaderState>,
}
+impl std::fmt::Debug for EmbeddedModuleLoader {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("EmbeddedModuleLoader").finish()
+ }
+}
+
pub const MODULE_NOT_FOUND: &str = "Module not found";
pub const UNSUPPORTED_SCHEME: &str = "Unsupported scheme";
@@ -158,13 +185,27 @@ impl ModuleLoader for EmbeddedModuleLoader {
type_error(format!("Referrer uses invalid specifier: {}", err))
})?
};
+ let referrer_kind = if self
+ .shared
+ .cjs_tracker
+ .is_maybe_cjs(&referrer, MediaType::from_specifier(&referrer))?
+ {
+ NodeModuleKind::Cjs
+ } else {
+ NodeModuleKind::Esm
+ };
if self.shared.node_resolver.in_npm_package(&referrer) {
return Ok(
self
.shared
.node_resolver
- .resolve(raw_specifier, &referrer, NodeResolutionMode::Execution)?
+ .resolve(
+ raw_specifier,
+ &referrer,
+ referrer_kind,
+ NodeResolutionMode::Execution,
+ )?
.into_url(),
);
}
@@ -186,13 +227,13 @@ impl ModuleLoader for EmbeddedModuleLoader {
self
.shared
.node_resolver
- .resolve_package_sub_path_from_deno_module(
+ .resolve_package_subpath_from_deno_module(
pkg_json.dir_path(),
sub_path.as_deref(),
Some(&referrer),
+ referrer_kind,
NodeResolutionMode::Execution,
- )?
- .into_url(),
+ )?,
),
Ok(MappedResolution::PackageJson {
dep_result,
@@ -202,14 +243,15 @@ impl ModuleLoader for EmbeddedModuleLoader {
}) => match dep_result.as_ref().map_err(|e| AnyError::from(e.clone()))? {
PackageJsonDepValue::Req(req) => self
.shared
- .node_resolver
+ .npm_req_resolver
.resolve_req_with_sub_path(
req,
sub_path.as_deref(),
&referrer,
+ referrer_kind,
NodeResolutionMode::Execution,
)
- .map(|res| res.into_url()),
+ .map_err(AnyError::from),
PackageJsonDepValue::Workspace(version_req) => {
let pkg_folder = self
.shared
@@ -222,13 +264,13 @@ impl ModuleLoader for EmbeddedModuleLoader {
self
.shared
.node_resolver
- .resolve_package_sub_path_from_deno_module(
+ .resolve_package_subpath_from_deno_module(
pkg_folder,
sub_path.as_deref(),
Some(&referrer),
+ referrer_kind,
NodeResolutionMode::Execution,
- )?
- .into_url(),
+ )?,
)
}
},
@@ -237,20 +279,19 @@ impl ModuleLoader for EmbeddedModuleLoader {
if let Ok(reference) =
NpmPackageReqReference::from_specifier(&specifier)
{
- return self
- .shared
- .node_resolver
- .resolve_req_reference(
- &reference,
- &referrer,
- NodeResolutionMode::Execution,
- )
- .map(|res| res.into_url());
+ return Ok(self.shared.npm_req_resolver.resolve_req_reference(
+ &reference,
+ &referrer,
+ referrer_kind,
+ NodeResolutionMode::Execution,
+ )?);
}
if specifier.scheme() == "jsr" {
- if let Some(module) = self.shared.eszip.get_module(&specifier) {
- return Ok(module.specifier);
+ if let Some(specifier) =
+ self.shared.modules.resolve_specifier(&specifier)?
+ {
+ return Ok(specifier.clone());
}
}
@@ -258,16 +299,17 @@ impl ModuleLoader for EmbeddedModuleLoader {
self
.shared
.node_resolver
- .handle_if_in_node_modules(&specifier)?
+ .handle_if_in_node_modules(&specifier)
.unwrap_or(specifier),
)
}
Err(err)
if err.is_unmapped_bare_specifier() && referrer.scheme() == "file" =>
{
- let maybe_res = self.shared.node_resolver.resolve_if_for_npm_pkg(
+ let maybe_res = self.shared.npm_req_resolver.resolve_if_for_npm_pkg(
raw_specifier,
&referrer,
+ referrer_kind,
NodeResolutionMode::Execution,
)?;
if let Some(res) = maybe_res {
@@ -322,14 +364,19 @@ impl ModuleLoader for EmbeddedModuleLoader {
}
if self.shared.node_resolver.in_npm_package(original_specifier) {
- let npm_module_loader = self.shared.npm_module_loader.clone();
+ let shared = self.shared.clone();
let original_specifier = original_specifier.clone();
let maybe_referrer = maybe_referrer.cloned();
return deno_core::ModuleLoadResponse::Async(
async move {
- let code_source = npm_module_loader
+ let code_source = shared
+ .npm_module_loader
.load(&original_specifier, maybe_referrer.as_ref())
.await?;
+ let code_cache_entry = shared.get_code_cache(
+ &code_source.found_url,
+ code_source.code.as_bytes(),
+ );
Ok(deno_core::ModuleSource::new_with_redirect(
match code_source.media_type {
MediaType::Json => ModuleType::Json,
@@ -338,89 +385,177 @@ impl ModuleLoader for EmbeddedModuleLoader {
code_source.code,
&original_specifier,
&code_source.found_url,
- None,
+ code_cache_entry,
))
}
.boxed_local(),
);
}
- let Some(module) = self.shared.eszip.get_module(original_specifier) else {
- return deno_core::ModuleLoadResponse::Sync(Err(type_error(format!(
- "{MODULE_NOT_FOUND}: {}",
- original_specifier
- ))));
- };
- let original_specifier = original_specifier.clone();
-
- deno_core::ModuleLoadResponse::Async(
- async move {
- let code = module.inner.source().await.ok_or_else(|| {
- type_error(format!("Module not found: {}", original_specifier))
- })?;
- let code = arc_u8_to_arc_str(code)
- .map_err(|_| type_error("Module source is not utf-8"))?;
- Ok(deno_core::ModuleSource::new_with_redirect(
- match module.inner.kind {
- eszip::ModuleKind::JavaScript => ModuleType::JavaScript,
- eszip::ModuleKind::Json => ModuleType::Json,
- eszip::ModuleKind::Jsonc => {
- return Err(type_error("jsonc modules not supported"))
- }
- eszip::ModuleKind::OpaqueData => {
- unreachable!();
+ match self.shared.modules.read(original_specifier) {
+ Ok(Some(module)) => {
+ let media_type = module.media_type;
+ let (module_specifier, module_type, module_source) =
+ module.into_parts();
+ let is_maybe_cjs = match self
+ .shared
+ .cjs_tracker
+ .is_maybe_cjs(original_specifier, media_type)
+ {
+ Ok(is_maybe_cjs) => is_maybe_cjs,
+ Err(err) => {
+ return deno_core::ModuleLoadResponse::Sync(Err(type_error(
+ format!("{:?}", err),
+ )));
+ }
+ };
+ if is_maybe_cjs {
+ let original_specifier = original_specifier.clone();
+ let module_specifier = module_specifier.clone();
+ let shared = self.shared.clone();
+ deno_core::ModuleLoadResponse::Async(
+ async move {
+ let source = match module_source {
+ DenoCompileModuleSource::String(string) => {
+ Cow::Borrowed(string)
+ }
+ DenoCompileModuleSource::Bytes(module_code_bytes) => {
+ match module_code_bytes {
+ Cow::Owned(bytes) => Cow::Owned(
+ crate::util::text_encoding::from_utf8_lossy_owned(bytes),
+ ),
+ Cow::Borrowed(bytes) => String::from_utf8_lossy(bytes),
+ }
+ }
+ };
+ let source = shared
+ .node_code_translator
+ .translate_cjs_to_esm(&module_specifier, Some(source))
+ .await?;
+ let module_source = match source {
+ Cow::Owned(source) => ModuleSourceCode::String(source.into()),
+ Cow::Borrowed(source) => {
+ ModuleSourceCode::String(FastString::from_static(source))
+ }
+ };
+ let code_cache_entry = shared
+ .get_code_cache(&module_specifier, module_source.as_bytes());
+ Ok(deno_core::ModuleSource::new_with_redirect(
+ module_type,
+ module_source,
+ &original_specifier,
+ &module_specifier,
+ code_cache_entry,
+ ))
}
- },
- ModuleSourceCode::String(code.into()),
- &original_specifier,
- &module.specifier,
- None,
- ))
+ .boxed_local(),
+ )
+ } else {
+ let module_source = module_source.into_for_v8();
+ let code_cache_entry = self
+ .shared
+ .get_code_cache(module_specifier, module_source.as_bytes());
+ deno_core::ModuleLoadResponse::Sync(Ok(
+ deno_core::ModuleSource::new_with_redirect(
+ module_type,
+ module_source,
+ original_specifier,
+ module_specifier,
+ code_cache_entry,
+ ),
+ ))
+ }
}
- .boxed_local(),
- )
+ Ok(None) => deno_core::ModuleLoadResponse::Sync(Err(type_error(
+ format!("{MODULE_NOT_FOUND}: {}", original_specifier),
+ ))),
+ Err(err) => deno_core::ModuleLoadResponse::Sync(Err(type_error(
+ format!("{:?}", err),
+ ))),
+ }
+ }
+
+ fn code_cache_ready(
+ &self,
+ specifier: ModuleSpecifier,
+ source_hash: u64,
+ code_cache_data: &[u8],
+ ) -> LocalBoxFuture<'static, ()> {
+ if let Some(code_cache) = &self.shared.code_cache {
+ code_cache.set_sync(
+ specifier,
+ deno_runtime::code_cache::CodeCacheType::EsModule,
+ source_hash,
+ code_cache_data,
+ );
+ }
+ std::future::ready(()).boxed_local()
}
}
-fn arc_u8_to_arc_str(
- arc_u8: Arc<[u8]>,
-) -> Result<Arc<str>, std::str::Utf8Error> {
- // Check that the string is valid UTF-8.
- std::str::from_utf8(&arc_u8)?;
- // SAFETY: the string is valid UTF-8, and the layout Arc<[u8]> is the same as
- // Arc<str>. This is proven by the From<Arc<str>> impl for Arc<[u8]> from the
- // standard library.
- Ok(unsafe {
- std::mem::transmute::<std::sync::Arc<[u8]>, std::sync::Arc<str>>(arc_u8)
- })
+impl NodeRequireLoader for EmbeddedModuleLoader {
+ fn ensure_read_permission<'a>(
+ &self,
+ permissions: &mut dyn deno_runtime::deno_node::NodePermissions,
+ path: &'a std::path::Path,
+ ) -> Result<Cow<'a, std::path::Path>, AnyError> {
+ if self.shared.modules.has_file(path) {
+ // allow reading if the file is in the snapshot
+ return Ok(Cow::Borrowed(path));
+ }
+
+ self
+ .shared
+ .npm_resolver
+ .ensure_read_permission(permissions, path)
+ }
+
+ fn load_text_file_lossy(
+ &self,
+ path: &std::path::Path,
+ ) -> Result<String, AnyError> {
+ Ok(self.shared.fs.read_text_file_lossy_sync(path, None)?)
+ }
+
+ fn is_maybe_cjs(
+ &self,
+ specifier: &ModuleSpecifier,
+ ) -> Result<bool, ClosestPkgJsonError> {
+ let media_type = MediaType::from_specifier(specifier);
+ self.shared.cjs_tracker.is_maybe_cjs(specifier, media_type)
+ }
}
struct StandaloneModuleLoaderFactory {
shared: Arc<SharedModuleLoaderState>,
}
+impl StandaloneModuleLoaderFactory {
+ pub fn create_result(&self) -> CreateModuleLoaderResult {
+ let loader = Rc::new(EmbeddedModuleLoader {
+ shared: self.shared.clone(),
+ });
+ CreateModuleLoaderResult {
+ module_loader: loader.clone(),
+ node_require_loader: loader,
+ }
+ }
+}
+
impl ModuleLoaderFactory for StandaloneModuleLoaderFactory {
fn create_for_main(
&self,
_root_permissions: PermissionsContainer,
- ) -> ModuleLoaderAndSourceMapGetter {
- ModuleLoaderAndSourceMapGetter {
- module_loader: Rc::new(EmbeddedModuleLoader {
- shared: self.shared.clone(),
- }),
- }
+ ) -> CreateModuleLoaderResult {
+ self.create_result()
}
fn create_for_worker(
&self,
_parent_permissions: PermissionsContainer,
_permissions: PermissionsContainer,
- ) -> ModuleLoaderAndSourceMapGetter {
- ModuleLoaderAndSourceMapGetter {
- module_loader: Rc::new(EmbeddedModuleLoader {
- shared: self.shared.clone(),
- }),
- }
+ ) -> CreateModuleLoaderResult {
+ self.create_result()
}
}
@@ -439,13 +574,15 @@ impl RootCertStoreProvider for StandaloneRootCertStoreProvider {
}
}
-pub async fn run(
- mut eszip: eszip::EszipV2,
- metadata: Metadata,
-) -> Result<i32, AnyError> {
- let current_exe_path = std::env::current_exe().unwrap();
- let current_exe_name =
- current_exe_path.file_name().unwrap().to_string_lossy();
+pub async fn run(data: StandaloneData) -> Result<i32, AnyError> {
+ let StandaloneData {
+ fs,
+ metadata,
+ modules,
+ npm_snapshot,
+ root_path,
+ vfs,
+ } = data;
let deno_dir_provider = Arc::new(DenoDirProvider::new(None));
let root_cert_store_provider = Arc::new(StandaloneRootCertStoreProvider {
ca_stores: metadata.ca_stores,
@@ -459,44 +596,50 @@ pub async fn run(
));
// use a dummy npm registry url
let npm_registry_url = ModuleSpecifier::parse("https://localhost/").unwrap();
- let root_path =
- std::env::temp_dir().join(format!("deno-compile-{}", current_exe_name));
let root_dir_url =
Arc::new(ModuleSpecifier::from_directory_path(&root_path).unwrap());
let main_module = root_dir_url.join(&metadata.entrypoint_key).unwrap();
- let root_node_modules_path = root_path.join("node_modules");
- let npm_cache_dir = NpmCacheDir::new(
- &RealDenoCacheEnv,
- root_node_modules_path.clone(),
- vec![npm_registry_url.clone()],
- );
- let npm_global_cache_dir = npm_cache_dir.get_cache_location();
+ let npm_global_cache_dir = root_path.join(".deno_compile_node_modules");
let cache_setting = CacheSetting::Only;
- let (fs, npm_resolver, maybe_vfs_root) = match metadata.node_modules {
+ let pkg_json_resolver = Arc::new(PackageJsonResolver::new(
+ deno_runtime::deno_node::DenoFsNodeResolverEnv::new(fs.clone()),
+ ));
+ let (in_npm_pkg_checker, npm_resolver) = match metadata.node_modules {
Some(binary::NodeModules::Managed { node_modules_dir }) => {
- // this will always have a snapshot
- let snapshot = eszip.take_npm_snapshot().unwrap();
- let vfs_root_dir_path = if node_modules_dir.is_some() {
- root_path.clone()
- } else {
- npm_cache_dir.root_dir().to_owned()
- };
- let vfs = load_npm_vfs(vfs_root_dir_path.clone())
- .context("Failed to load npm vfs.")?;
+ // create an npmrc that uses the fake npm_registry_url to resolve packages
+ let npmrc = Arc::new(ResolvedNpmRc {
+ default_config: deno_npm::npm_rc::RegistryConfigWithUrl {
+ registry_url: npm_registry_url.clone(),
+ config: Default::default(),
+ },
+ scopes: Default::default(),
+ registry_configs: Default::default(),
+ });
+ let npm_cache_dir = Arc::new(NpmCacheDir::new(
+ &DenoCacheEnvFsAdapter(fs.as_ref()),
+ npm_global_cache_dir,
+ npmrc.get_all_known_registries_urls(),
+ ));
+ let snapshot = npm_snapshot.unwrap();
let maybe_node_modules_path = node_modules_dir
- .map(|node_modules_dir| vfs_root_dir_path.join(node_modules_dir));
- let fs = Arc::new(DenoCompileFileSystem::new(vfs))
- as Arc<dyn deno_fs::FileSystem>;
+ .map(|node_modules_dir| root_path.join(node_modules_dir));
+ let in_npm_pkg_checker =
+ create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed(
+ CliManagedInNpmPkgCheckerCreateOptions {
+ root_cache_dir_url: npm_cache_dir.root_dir_url(),
+ maybe_node_modules_path: maybe_node_modules_path.as_deref(),
+ },
+ ));
let npm_resolver =
create_cli_npm_resolver(CliNpmResolverCreateOptions::Managed(
- CliNpmResolverManagedCreateOptions {
+ CliManagedNpmResolverCreateOptions {
snapshot: CliNpmResolverManagedSnapshotOption::Specified(Some(
snapshot,
)),
maybe_lockfile: None,
fs: fs.clone(),
http_client_provider: http_client_provider.clone(),
- npm_global_cache_dir,
+ npm_cache_dir,
cache_setting,
text_only_progress_bar: progress_bar,
maybe_node_modules_path,
@@ -505,50 +648,54 @@ pub async fn run(
// this is only used for installing packages, which isn't necessary with deno compile
NpmInstallDepsProvider::empty(),
),
- // create an npmrc that uses the fake npm_registry_url to resolve packages
- npmrc: Arc::new(ResolvedNpmRc {
- default_config: deno_npm::npm_rc::RegistryConfigWithUrl {
- registry_url: npm_registry_url.clone(),
- config: Default::default(),
- },
- scopes: Default::default(),
- registry_configs: Default::default(),
- }),
+ npmrc,
lifecycle_scripts: Default::default(),
},
))
.await?;
- (fs, npm_resolver, Some(vfs_root_dir_path))
+ (in_npm_pkg_checker, npm_resolver)
}
Some(binary::NodeModules::Byonm {
root_node_modules_dir,
}) => {
- let vfs_root_dir_path = root_path.clone();
- let vfs = load_npm_vfs(vfs_root_dir_path.clone())
- .context("Failed to load vfs.")?;
let root_node_modules_dir =
root_node_modules_dir.map(|p| vfs.root().join(p));
- let fs = Arc::new(DenoCompileFileSystem::new(vfs))
- as Arc<dyn deno_fs::FileSystem>;
+ let in_npm_pkg_checker =
+ create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Byonm);
let npm_resolver = create_cli_npm_resolver(
CliNpmResolverCreateOptions::Byonm(CliByonmNpmResolverCreateOptions {
fs: CliDenoResolverFs(fs.clone()),
+ pkg_json_resolver: pkg_json_resolver.clone(),
root_node_modules_dir,
}),
)
.await?;
- (fs, npm_resolver, Some(vfs_root_dir_path))
+ (in_npm_pkg_checker, npm_resolver)
}
None => {
- let fs = Arc::new(deno_fs::RealFs) as Arc<dyn deno_fs::FileSystem>;
+ // Packages from different registries are already inlined in the binary,
+ // so no need to create actual `.npmrc` configuration.
+ let npmrc = create_default_npmrc();
+ let npm_cache_dir = Arc::new(NpmCacheDir::new(
+ &DenoCacheEnvFsAdapter(fs.as_ref()),
+ npm_global_cache_dir,
+ npmrc.get_all_known_registries_urls(),
+ ));
+ let in_npm_pkg_checker =
+ create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed(
+ CliManagedInNpmPkgCheckerCreateOptions {
+ root_cache_dir_url: npm_cache_dir.root_dir_url(),
+ maybe_node_modules_path: None,
+ },
+ ));
let npm_resolver =
create_cli_npm_resolver(CliNpmResolverCreateOptions::Managed(
- CliNpmResolverManagedCreateOptions {
+ CliManagedNpmResolverCreateOptions {
snapshot: CliNpmResolverManagedSnapshotOption::Specified(None),
maybe_lockfile: None,
fs: fs.clone(),
http_client_provider: http_client_provider.clone(),
- npm_global_cache_dir,
+ npm_cache_dir,
cache_setting,
text_only_progress_bar: progress_bar,
maybe_node_modules_path: None,
@@ -557,41 +704,53 @@ pub async fn run(
// this is only used for installing packages, which isn't necessary with deno compile
NpmInstallDepsProvider::empty(),
),
- // Packages from different registries are already inlined in the ESZip,
- // so no need to create actual `.npmrc` configuration.
npmrc: create_default_npmrc(),
lifecycle_scripts: Default::default(),
},
))
.await?;
- (fs, npm_resolver, None)
+ (in_npm_pkg_checker, npm_resolver)
}
};
let has_node_modules_dir = npm_resolver.root_node_modules_path().is_some();
let node_resolver = Arc::new(NodeResolver::new(
deno_runtime::deno_node::DenoFsNodeResolverEnv::new(fs.clone()),
- npm_resolver.clone().into_npm_resolver(),
+ in_npm_pkg_checker.clone(),
+ npm_resolver.clone().into_npm_pkg_folder_resolver(),
+ pkg_json_resolver.clone(),
+ ));
+ let cjs_tracker = Arc::new(CjsTracker::new(
+ in_npm_pkg_checker.clone(),
+ pkg_json_resolver.clone(),
+ IsCjsResolverOptions {
+ detect_cjs: !metadata.workspace_resolver.package_jsons.is_empty(),
+ is_node_main: false,
+ },
));
- let cjs_resolutions = Arc::new(CjsResolutionStore::default());
let cache_db = Caches::new(deno_dir_provider.clone());
let node_analysis_cache = NodeAnalysisCache::new(cache_db.node_analysis_db());
- let cli_node_resolver = Arc::new(CliNodeResolver::new(
- cjs_resolutions.clone(),
- fs.clone(),
- node_resolver.clone(),
- npm_resolver.clone(),
- ));
+ let npm_req_resolver =
+ Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions {
+ byonm_resolver: (npm_resolver.clone()).into_maybe_byonm(),
+ fs: CliDenoResolverFs(fs.clone()),
+ in_npm_pkg_checker: in_npm_pkg_checker.clone(),
+ node_resolver: node_resolver.clone(),
+ npm_req_resolver: npm_resolver.clone().into_npm_req_resolver(),
+ }));
let cjs_esm_code_analyzer = CliCjsCodeAnalyzer::new(
node_analysis_cache,
+ cjs_tracker.clone(),
fs.clone(),
- cli_node_resolver.clone(),
+ None,
);
let node_code_translator = Arc::new(NodeCodeTranslator::new(
cjs_esm_code_analyzer,
deno_runtime::deno_node::DenoFsNodeResolverEnv::new(fs.clone()),
+ in_npm_pkg_checker,
node_resolver.clone(),
- npm_resolver.clone().into_npm_resolver(),
+ npm_resolver.clone().into_npm_pkg_folder_resolver(),
+ pkg_json_resolver.clone(),
));
let workspace_resolver = {
let import_map = match metadata.workspace_resolver.import_map {
@@ -642,39 +801,52 @@ pub async fn run(
metadata.workspace_resolver.pkg_json_resolution,
)
};
+ let code_cache = match metadata.code_cache_key {
+ Some(code_cache_key) => Some(Arc::new(DenoCompileCodeCache::new(
+ root_path.with_file_name(format!(
+ "{}.cache",
+ root_path.file_name().unwrap().to_string_lossy()
+ )),
+ code_cache_key,
+ )) as Arc<dyn CliCodeCache>),
+ None => {
+ log::debug!("Code cache disabled.");
+ None
+ }
+ };
let module_loader_factory = StandaloneModuleLoaderFactory {
shared: Arc::new(SharedModuleLoaderState {
- eszip: WorkspaceEszip {
- eszip,
- root_dir_url,
- },
- workspace_resolver,
- node_resolver: cli_node_resolver.clone(),
+ cjs_tracker: cjs_tracker.clone(),
+ fs: fs.clone(),
+ modules,
+ node_code_translator: node_code_translator.clone(),
+ node_resolver: node_resolver.clone(),
npm_module_loader: Arc::new(NpmModuleLoader::new(
- cjs_resolutions,
- node_code_translator,
+ cjs_tracker.clone(),
fs.clone(),
- cli_node_resolver,
+ node_code_translator,
)),
+ code_cache: code_cache.clone(),
+ npm_resolver: npm_resolver.clone(),
+ workspace_resolver,
+ npm_req_resolver,
}),
};
let permissions = {
let mut permissions =
metadata.permissions.to_options(/* cli_arg_urls */ &[]);
- // if running with an npm vfs, grant read access to it
- if let Some(vfs_root) = maybe_vfs_root {
- match &mut permissions.allow_read {
- Some(vec) if vec.is_empty() => {
- // do nothing, already granted
- }
- Some(vec) => {
- vec.push(vfs_root.to_string_lossy().to_string());
- }
- None => {
- permissions.allow_read =
- Some(vec![vfs_root.to_string_lossy().to_string()]);
- }
+ // grant read access to the vfs
+ match &mut permissions.allow_read {
+ Some(vec) if vec.is_empty() => {
+ // do nothing, already granted
+ }
+ Some(vec) => {
+ vec.push(root_path.to_string_lossy().to_string());
+ }
+ None => {
+ permissions.allow_read =
+ Some(vec![root_path.to_string_lossy().to_string()]);
}
}
@@ -696,8 +868,7 @@ pub async fn run(
});
let worker_factory = CliMainWorkerFactory::new(
Arc::new(BlobStore::default()),
- // Code cache is not supported for standalone binary yet.
- None,
+ code_cache,
feature_checker,
fs,
None,
@@ -706,6 +877,7 @@ pub async fn run(
Box::new(module_loader_factory),
node_resolver,
npm_resolver,
+ pkg_json_resolver,
root_cert_store_provider,
permissions,
StorageKeyResolver::empty(),
@@ -721,7 +893,6 @@ pub async fn run(
inspect_wait: false,
strace_ops: None,
is_inspecting: false,
- is_npm_main: main_module.scheme() == "npm",
skip_op_registration: true,
location: metadata.location,
argv0: NpmPackageReqReference::from_specifier(&main_module)
@@ -739,6 +910,7 @@ pub async fn run(
serve_port: None,
serve_host: None,
},
+ metadata.otel_config,
);
// Initialize v8 once from the main thread.