Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dprint.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"cli/tsc/dts/lib.es*.d.ts",
"cli/tsc/dts/lib.scripthost.d.ts",
"cli/tsc/dts/lib.webworker*.d.ts",
"cli/tsc/dts/node",
"cli/tsc/dts/typescript.d.ts",
"cli/tools/doc/prism.css",
"cli/tools/doc/prism.js",
Expand Down
73 changes: 70 additions & 3 deletions cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ fn compress_decls(out_dir: &Path) {
"lib.deno.window.d.ts",
"lib.deno.worker.d.ts",
"lib.deno.shared_globals.d.ts",
"lib.deno.ns.d.ts",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate (see above)

"lib.deno.unstable.d.ts",
"lib.deno_console.d.ts",
"lib.deno_url.d.ts",
Expand Down Expand Up @@ -122,6 +121,7 @@ fn compress_decls(out_dir: &Path) {
"lib.esnext.iterator.d.ts",
"lib.esnext.promise.d.ts",
"lib.esnext.sharedmemory.d.ts",
"lib.node.d.ts",
"lib.scripthost.d.ts",
"lib.webworker.asynciterable.d.ts",
"lib.webworker.d.ts",
Expand All @@ -134,6 +134,71 @@ fn compress_decls(out_dir: &Path) {
}
}

fn process_node_types(out_dir: &Path) {
Copy link
Member Author

@dsherret dsherret Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should see about extracting the libs out to a separate crate so it can be done in parallel (I haven't measured if it's worth it yet though).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I measured it and it was 873ms. It's probably worth extracting out to a separate crate after this lands.

let root_dir = Path::new(".").canonicalize().unwrap();
let dts_dir = root_dir.join("tsc").join("dts");
let node_dir = dts_dir.join("node");

// Recursively find all .d.ts files in the node directory
fn visit_dirs(dir: &Path, cb: &mut dyn FnMut(&Path)) -> std::io::Result<()> {
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, cb)?;
} else if path.extension().and_then(|s| s.to_str()) == Some("ts")
|| path.extension().and_then(|s| s.to_str()) == Some("cts")
{
cb(&path);
}
}
Ok(())
}

println!("cargo:rerun-if-changed={}", node_dir.display());

let mut paths = Vec::new();
visit_dirs(&node_dir, &mut |path| {
paths.push(path.to_path_buf());
})
.unwrap();

// Sort for deterministic builds
paths.sort();

// Compress all the files if release
if !cfg!(debug_assertions) && std::env::var("CARGO_FEATURE_HMR").is_err() {
for path in &paths {
let relative = path.strip_prefix(&root_dir).unwrap();
compress_source(out_dir, &relative.to_string_lossy());
}
}

// Generate a Rust file with the node type entries (always, for both debug and release)
let mut generated = String::from("// Auto-generated by build.rs\n");
generated.push_str(
"// This macro expands to an array of maybe_compressed_lib! entries\n",
);
generated.push_str("macro_rules! node_type_libs {\n");
generated.push_str(" () => {\n");
generated.push_str(" [\n");

for path in paths {
let relative = path.strip_prefix(&dts_dir).unwrap();
let relative_str = relative.to_string_lossy().replace('\\', "/");
generated.push_str(&format!(
" maybe_compressed_lib!(\"{}\"),\n",
relative_str
));
}

generated.push_str(" ]\n");
generated.push_str(" };\n");
generated.push_str("}\n");

std::fs::write(out_dir.join("node_types.rs"), generated).unwrap();
}

fn compress_source(out_dir: &Path, file: &str) {
let path = Path::new(file)
.canonicalize()
Expand Down Expand Up @@ -200,9 +265,11 @@ fn main() {
// To debug snapshot issues uncomment:
// op_fetch_asset::trace_serializer();

let out_dir = std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap());

process_node_types(&out_dir);

if !cfg!(debug_assertions) && std::env::var("CARGO_FEATURE_HMR").is_err() {
let out_dir =
std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
compress_sources(&out_dir);
}

Expand Down
1 change: 0 additions & 1 deletion cli/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,6 @@ impl CliFactory {
.clone(),
})),
bare_node_builtins: options.unstable_bare_node_builtins(),
types_node_version_req: Some(crate::npm::get_types_node_version_req()),
unstable_sloppy_imports: options.unstable_sloppy_imports(),
on_mapped_resolution_diagnostic: Some(Arc::new(
on_resolve_diagnostic,
Expand Down
9 changes: 0 additions & 9 deletions cli/graph_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,15 +788,6 @@ impl ModuleGraphBuilder {
)
.await?;

if let Some(npm_installer) = &self.npm_installer
&& graph.has_node_specifier
&& graph.graph_kind().include_types()
{
npm_installer
.inject_synthetic_types_node_package(options.npm_caching)
.await?;
}

Ok(())
}

Expand Down
1 change: 0 additions & 1 deletion cli/lsp/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1452,7 +1452,6 @@ impl ConfigData {
package_json_cache: None,
package_json_dep_resolution: None,
specified_import_map: None,
types_node_version_req: Some(crate::npm::get_types_node_version_req()),
unstable_sloppy_imports: false,
require_modules: vec![],
},
Expand Down
11 changes: 0 additions & 11 deletions cli/lsp/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1012,17 +1012,6 @@ fn diagnose_resolution(
module_name.to_string(),
));
}
} else if let Some(npm_resolver) = managed_npm_resolver {
// check that a @types/node package exists in the resolver
let types_node_req =
PackageReq::from_str("@types/node").unwrap();
if !npm_resolver.is_pkg_req_folder_cached(&types_node_req)
{
diagnostics.push(DenoDiagnostic::NotInstalledNpm(
types_node_req,
ModuleSpecifier::parse("npm:@types/node").unwrap(),
));
}
}
} else {
// When the document is not available, it means that it cannot be found
Expand Down
15 changes: 0 additions & 15 deletions cli/lsp/documents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fs;
use std::future::Future;
use std::ops::Range;
Expand Down Expand Up @@ -1507,11 +1506,6 @@ impl DocumentModules {
for dependency in module.dependencies.values() {
let code_specifier = dependency.get_code();
let type_specifier = dependency.get_type();
if let Some(dep) = code_specifier
&& dep.scheme() == "node"
{
dep_info.has_node_specifier = true;
}
if dependency.maybe_deno_types_specifier.is_some()
&& let (Some(code_specifier), Some(type_specifier)) =
(code_specifier, type_specifier)
Expand Down Expand Up @@ -1593,15 +1587,6 @@ impl DocumentModules {
.clone()
}

pub fn scopes_with_node_specifier(&self) -> HashSet<Option<Arc<Url>>> {
self
.dep_info_by_scope()
.iter()
.filter(|(_, i)| i.has_node_specifier)
.map(|(s, _)| s.clone())
.collect::<HashSet<_>>()
}

#[cfg_attr(feature = "lsp-tracing", tracing::instrument(skip_all))]
pub fn resolve(
&self,
Expand Down
5 changes: 2 additions & 3 deletions cli/lsp/language_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ use crate::lsp::diagnostics::generate_module_diagnostics;
use crate::lsp::lint::LspLinterResolver;
use crate::lsp::logging::init_log_file;
use crate::lsp::tsc::file_text_changes_to_workspace_edit;
use crate::npm::get_types_node_version_req;
use crate::sys::CliSys;
use crate::tools::fmt::format_file;
use crate::tools::fmt::format_parsed_source;
Expand Down Expand Up @@ -578,7 +577,7 @@ impl Inner {
let npm_search_api = CliNpmSearchApi::new(
module_registry.file_fetcher.clone(),
Arc::new(NpmVersionResolver {
types_node_version_req: Some(get_types_node_version_req()),
types_node_version_req: None,
link_packages: Default::default(),
newest_dependency_date_options: Default::default(),
}),
Expand Down Expand Up @@ -834,7 +833,7 @@ impl Inner {
self.npm_search_api = CliNpmSearchApi::new(
self.module_registry.file_fetcher.clone(),
Arc::new(NpmVersionResolver {
types_node_version_req: Some(get_types_node_version_req()),
types_node_version_req: None,
// todo(dsherret): the npm_search_api should probably be specific
// to each workspace so that the link packages can be properly
// hooked up
Expand Down
14 changes: 1 addition & 13 deletions cli/lsp/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ use crate::npm::CliNpmInstaller;
use crate::npm::CliNpmRegistryInfoProvider;
use crate::npm::CliNpmResolver;
use crate::npm::CliNpmResolverCreateOptions;
use crate::npm::get_types_node_version_req;
use crate::resolver::CliIsCjsResolver;
use crate::resolver::CliNpmReqResolver;
use crate::resolver::CliResolver;
Expand Down Expand Up @@ -567,16 +566,6 @@ impl LspResolver {
.cloned()
.unwrap_or_default();
{
if resolver.npm_installer.is_some() && dep_info.has_node_specifier {
let has_types_node = {
let npm_installer_reqs = resolver.npm_installer_reqs.lock();
npm_installer_reqs.iter().any(|r| r.name == "@types/node")
};
if !has_types_node {
resolver
.add_npm_reqs(vec![PackageReq::from_str("@types/node").unwrap()]);
}
}
let mut resolver_dep_info = resolver.dep_info.lock();
*resolver_dep_info = dep_info.clone();
}
Expand Down Expand Up @@ -613,7 +602,6 @@ impl LspResolver {
#[derive(Debug, Default, Clone)]
pub struct ScopeDepInfo {
pub deno_types_to_code_resolutions: HashMap<ModuleSpecifier, ModuleSpecifier>,
pub has_node_specifier: bool,
}

#[derive(Debug, Clone, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -953,7 +941,7 @@ impl<'a> ResolverFactory<'a> {
None,
));
let npm_version_resolver = Arc::new(NpmVersionResolver {
types_node_version_req: Some(get_types_node_version_req()),
types_node_version_req: None,
link_packages: link_packages.0.clone(),
newest_dependency_date_options: Default::default(),
});
Expand Down
18 changes: 8 additions & 10 deletions cli/lsp/tsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4728,7 +4728,10 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
let state = state.borrow::<State>();
let mark = state.performance.mark("tsc.op.op_is_node_file");
let r = match state.specifier_map.normalize(path) {
Ok(specifier) => state.state_snapshot.resolver.in_node_modules(&specifier),
Ok(specifier) => {
state.state_snapshot.resolver.in_node_modules(&specifier)
|| specifier.as_str().starts_with("asset:///node/")
}
Err(_) => false,
};
state.performance.measure(mark);
Expand All @@ -4740,7 +4743,10 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
fn op_libs() -> Vec<String> {
let mut out =
Vec::with_capacity(crate::tsc::LAZILY_LOADED_STATIC_ASSETS.len());
for key in crate::tsc::LAZILY_LOADED_STATIC_ASSETS.keys() {
for (key, value) in crate::tsc::LAZILY_LOADED_STATIC_ASSETS.iter() {
if !value.is_lib {
continue;
}
let lib = key
.replace("lib.", "")
.replace(".d.ts", "")
Expand Down Expand Up @@ -5101,11 +5107,6 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
by_notebook_uri: Default::default(),
};

let scopes_with_node_specifier = state
.state_snapshot
.document_modules
.scopes_with_node_specifier();

// Insert global scripts.
for (compiler_options_key, compiler_options_data) in
state.state_snapshot.compiler_options_resolver.entries()
Expand All @@ -5119,9 +5120,6 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
.as_ref()
.and_then(|s| state.state_snapshot.config.tree.scope_for_specifier(s))
.cloned();
if scopes_with_node_specifier.contains(&scope) {
script_names.insert("asset:///node_types.d.ts".to_string());
}
let scoped_resolver = state
.state_snapshot
.resolver
Expand Down
7 changes: 0 additions & 7 deletions cli/npm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ use deno_npm_installer::lifecycle_scripts::is_broken_default_install_script;
use deno_resolver::npm::ByonmNpmResolverCreateOptions;
use deno_resolver::npm::ManagedNpmResolverRc;
use deno_runtime::deno_io::FromRawIoHandle;
use deno_semver::VersionReq;
use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use deno_task_shell::KillSignal;
Expand Down Expand Up @@ -583,9 +582,3 @@ impl DenoTaskLifeCycleScriptsExecutor {
.await
}
}

pub fn get_types_node_version_req() -> VersionReq {
// WARNING: When bumping this version, check if anything needs to be
// updated in the `setNodeOnlyGlobalNames` call in 99_main_compiler.js
VersionReq::parse_from_npm("24.0.4 - 24.2.0").unwrap()
}
5 changes: 3 additions & 2 deletions cli/schemas/config-file.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@
"description": "Specify a set of bundled library declaration files that describe the target runtime environment.",
"type": "array",
"uniqueItems": true,
"default": ["deno.window"],
"default": ["deno.window", "deno.unstable", "node"],
"items": {
"type": "string",
"examples": [
Expand Down Expand Up @@ -270,7 +270,8 @@
"es2022",
"es2023",
"es2024",
"esnext"
"esnext",
"node"
]
},
"markdownDescription": "Specify a set of bundled library declaration files that describe the target runtime environment.\n\nSee more: https://www.typescriptlang.org/tsconfig#lib"
Expand Down
12 changes: 1 addition & 11 deletions cli/tools/repl/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ use deno_graph::Position;
use deno_graph::PositionRange;
use deno_graph::analysis::SpecifierWithRange;
use deno_lib::util::result::any_and_jserrorbox_downcast_ref;
use deno_npm_installer::graph::NpmCachingStrategy;
use deno_resolver::deno_json::CompilerOptionsResolver;
use deno_runtime::worker::MainWorker;
use deno_semver::npm::NpmPackageReqReference;
Expand Down Expand Up @@ -890,19 +889,10 @@ impl ReplSession {
.flat_map(|url| NpmPackageReqReference::from_specifier(url).ok())
.map(|r| r.into_inner().req)
.collect::<Vec<_>>();
let has_node_specifier =
resolved_imports.iter().any(|url| url.scheme() == "node");
if !npm_imports.is_empty() || has_node_specifier {
if !npm_imports.is_empty() {
npm_installer
.add_and_cache_package_reqs(&npm_imports)
.await?;

// prevent messages in the repl about @types/node not being cached
if has_node_specifier {
npm_installer
.inject_synthetic_types_node_package(NpmCachingStrategy::Eager)
.await?;
}
}
Ok(())
}
Expand Down
Loading
Loading