Skip to content

Commit a49fdb5

Browse files
authored
feat: include @types/node type declarations out of the box (#31502)
This adds a new "node" lib that's included by default and can be excluded by providing a custom `"lib": [...]` typescript compiler option without the `"node"` value. If it detects a `@types/node` package in the files being type checked it will skip injecting the `lib.node.d.ts` file. * Uses `npm:@types/[email protected]` * See tools/update_types_node.ts for the build script. * denoland/deno_npm#127 (will integrate this one later) * denoland/typescript-go#16 * denoland/TypeScript#19 (last two commits) Closes #30963
1 parent 0bc213b commit a49fdb5

File tree

155 files changed

+55571
-463
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+55571
-463
lines changed

.dprint.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"cli/tsc/dts/lib.es*.d.ts",
3636
"cli/tsc/dts/lib.scripthost.d.ts",
3737
"cli/tsc/dts/lib.webworker*.d.ts",
38+
"cli/tsc/dts/node",
3839
"cli/tsc/dts/typescript.d.ts",
3940
"cli/tools/doc/prism.css",
4041
"cli/tools/doc/prism.js",

cli/build.rs

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ fn compress_decls(out_dir: &Path) {
1414
"lib.deno.window.d.ts",
1515
"lib.deno.worker.d.ts",
1616
"lib.deno.shared_globals.d.ts",
17-
"lib.deno.ns.d.ts",
1817
"lib.deno.unstable.d.ts",
1918
"lib.deno_console.d.ts",
2019
"lib.deno_url.d.ts",
@@ -122,6 +121,7 @@ fn compress_decls(out_dir: &Path) {
122121
"lib.esnext.iterator.d.ts",
123122
"lib.esnext.promise.d.ts",
124123
"lib.esnext.sharedmemory.d.ts",
124+
"lib.node.d.ts",
125125
"lib.scripthost.d.ts",
126126
"lib.webworker.asynciterable.d.ts",
127127
"lib.webworker.d.ts",
@@ -134,6 +134,68 @@ fn compress_decls(out_dir: &Path) {
134134
}
135135
}
136136

137+
fn process_node_types(out_dir: &Path) {
138+
let root_dir = Path::new(".").canonicalize().unwrap();
139+
let dts_dir = root_dir.join("tsc").join("dts");
140+
let node_dir = dts_dir.join("node");
141+
142+
// Recursively find all .d.ts files in the node directory
143+
fn visit_dirs(dir: &Path, cb: &mut dyn FnMut(&Path)) -> std::io::Result<()> {
144+
for entry in std::fs::read_dir(dir)? {
145+
let entry = entry?;
146+
let path = entry.path();
147+
if path.is_dir() {
148+
visit_dirs(&path, cb)?;
149+
} else if path.extension().and_then(|s| s.to_str()) == Some("ts")
150+
|| path.extension().and_then(|s| s.to_str()) == Some("cts")
151+
{
152+
cb(&path);
153+
}
154+
}
155+
Ok(())
156+
}
157+
158+
println!("cargo:rerun-if-changed={}", node_dir.display());
159+
160+
let mut paths = Vec::new();
161+
visit_dirs(&node_dir, &mut |path| {
162+
paths.push(path.to_path_buf());
163+
})
164+
.unwrap();
165+
166+
// Sort for deterministic builds
167+
paths.sort();
168+
169+
// Compress all the files if release
170+
if !cfg!(debug_assertions) && std::env::var("CARGO_FEATURE_HMR").is_err() {
171+
for path in &paths {
172+
let relative = path.strip_prefix(&root_dir).unwrap();
173+
compress_source(out_dir, &relative.to_string_lossy());
174+
}
175+
}
176+
177+
// Generate a Rust file with the node type entries (always, for both debug and release)
178+
let mut generated = String::from("// Auto-generated by build.rs\n");
179+
generated.push_str("macro_rules! node_type_libs {\n");
180+
generated.push_str(" () => {\n");
181+
generated.push_str(" [\n");
182+
183+
for path in paths {
184+
let relative = path.strip_prefix(&dts_dir).unwrap();
185+
let relative_str = relative.to_string_lossy().replace('\\', "/");
186+
generated.push_str(&format!(
187+
" maybe_compressed_static_asset!(\"{}\", false),\n",
188+
relative_str
189+
));
190+
}
191+
192+
generated.push_str(" ]\n");
193+
generated.push_str(" };\n");
194+
generated.push_str("}\n");
195+
196+
std::fs::write(out_dir.join("node_types.rs"), generated).unwrap();
197+
}
198+
137199
fn compress_source(out_dir: &Path, file: &str) {
138200
let path = Path::new(file)
139201
.canonicalize()
@@ -200,9 +262,11 @@ fn main() {
200262
// To debug snapshot issues uncomment:
201263
// op_fetch_asset::trace_serializer();
202264

265+
let out_dir = std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
266+
267+
process_node_types(&out_dir);
268+
203269
if !cfg!(debug_assertions) && std::env::var("CARGO_FEATURE_HMR").is_err() {
204-
let out_dir =
205-
std::path::PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
206270
compress_sources(&out_dir);
207271
}
208272

cli/factory.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,6 @@ impl CliFactory {
12471247
.clone(),
12481248
})),
12491249
bare_node_builtins: options.unstable_bare_node_builtins(),
1250-
types_node_version_req: Some(crate::npm::get_types_node_version_req()),
12511250
unstable_sloppy_imports: options.unstable_sloppy_imports(),
12521251
on_mapped_resolution_diagnostic: Some(Arc::new(
12531252
on_resolve_diagnostic,

cli/graph_util.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -788,15 +788,6 @@ impl ModuleGraphBuilder {
788788
)
789789
.await?;
790790

791-
if let Some(npm_installer) = &self.npm_installer
792-
&& graph.has_node_specifier
793-
&& graph.graph_kind().include_types()
794-
{
795-
npm_installer
796-
.inject_synthetic_types_node_package(options.npm_caching)
797-
.await?;
798-
}
799-
800791
Ok(())
801792
}
802793

cli/lsp/config.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1460,7 +1460,6 @@ impl ConfigData {
14601460
package_json_cache: None,
14611461
package_json_dep_resolution: None,
14621462
specified_import_map: None,
1463-
types_node_version_req: Some(crate::npm::get_types_node_version_req()),
14641463
unstable_sloppy_imports: false,
14651464
require_modules: vec![],
14661465
},

cli/lsp/diagnostics.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,17 +1012,6 @@ fn diagnose_resolution(
10121012
module_name.to_string(),
10131013
));
10141014
}
1015-
} else if let Some(npm_resolver) = managed_npm_resolver {
1016-
// check that a @types/node package exists in the resolver
1017-
let types_node_req =
1018-
PackageReq::from_str("@types/node").unwrap();
1019-
if !npm_resolver.is_pkg_req_folder_cached(&types_node_req)
1020-
{
1021-
diagnostics.push(DenoDiagnostic::NotInstalledNpm(
1022-
types_node_req,
1023-
ModuleSpecifier::parse("npm:@types/node").unwrap(),
1024-
));
1025-
}
10261015
}
10271016
} else {
10281017
// When the document is not available, it means that it cannot be found

cli/lsp/documents.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use std::borrow::Cow;
44
use std::collections::BTreeMap;
55
use std::collections::HashMap;
6-
use std::collections::HashSet;
76
use std::fs;
87
use std::future::Future;
98
use std::ops::Range;
@@ -1507,11 +1506,6 @@ impl DocumentModules {
15071506
for dependency in module.dependencies.values() {
15081507
let code_specifier = dependency.get_code();
15091508
let type_specifier = dependency.get_type();
1510-
if let Some(dep) = code_specifier
1511-
&& dep.scheme() == "node"
1512-
{
1513-
dep_info.has_node_specifier = true;
1514-
}
15151509
if dependency.maybe_deno_types_specifier.is_some()
15161510
&& let (Some(code_specifier), Some(type_specifier)) =
15171511
(code_specifier, type_specifier)
@@ -1593,15 +1587,6 @@ impl DocumentModules {
15931587
.clone()
15941588
}
15951589

1596-
pub fn scopes_with_node_specifier(&self) -> HashSet<Option<Arc<Url>>> {
1597-
self
1598-
.dep_info_by_scope()
1599-
.iter()
1600-
.filter(|(_, i)| i.has_node_specifier)
1601-
.map(|(s, _)| s.clone())
1602-
.collect::<HashSet<_>>()
1603-
}
1604-
16051590
#[cfg_attr(feature = "lsp-tracing", tracing::instrument(skip_all))]
16061591
pub fn resolve(
16071592
&self,

cli/lsp/language_server.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ use crate::lsp::diagnostics::generate_module_diagnostics;
116116
use crate::lsp::lint::LspLinterResolver;
117117
use crate::lsp::logging::init_log_file;
118118
use crate::lsp::tsc::file_text_changes_to_workspace_edit;
119-
use crate::npm::get_types_node_version_req;
120119
use crate::sys::CliSys;
121120
use crate::tools::fmt::format_file;
122121
use crate::tools::fmt::format_parsed_source;
@@ -578,7 +577,7 @@ impl Inner {
578577
let npm_search_api = CliNpmSearchApi::new(
579578
module_registry.file_fetcher.clone(),
580579
Arc::new(NpmVersionResolver {
581-
types_node_version_req: Some(get_types_node_version_req()),
580+
types_node_version_req: None,
582581
link_packages: Default::default(),
583582
newest_dependency_date_options: Default::default(),
584583
}),
@@ -834,7 +833,7 @@ impl Inner {
834833
self.npm_search_api = CliNpmSearchApi::new(
835834
self.module_registry.file_fetcher.clone(),
836835
Arc::new(NpmVersionResolver {
837-
types_node_version_req: Some(get_types_node_version_req()),
836+
types_node_version_req: None,
838837
// todo(dsherret): the npm_search_api should probably be specific
839838
// to each workspace so that the link packages can be properly
840839
// hooked up

cli/lsp/resolver.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ use crate::npm::CliNpmInstaller;
8080
use crate::npm::CliNpmRegistryInfoProvider;
8181
use crate::npm::CliNpmResolver;
8282
use crate::npm::CliNpmResolverCreateOptions;
83-
use crate::npm::get_types_node_version_req;
8483
use crate::resolver::CliIsCjsResolver;
8584
use crate::resolver::CliNpmReqResolver;
8685
use crate::resolver::CliResolver;
@@ -567,16 +566,6 @@ impl LspResolver {
567566
.cloned()
568567
.unwrap_or_default();
569568
{
570-
if resolver.npm_installer.is_some() && dep_info.has_node_specifier {
571-
let has_types_node = {
572-
let npm_installer_reqs = resolver.npm_installer_reqs.lock();
573-
npm_installer_reqs.iter().any(|r| r.name == "@types/node")
574-
};
575-
if !has_types_node {
576-
resolver
577-
.add_npm_reqs(vec![PackageReq::from_str("@types/node").unwrap()]);
578-
}
579-
}
580569
let mut resolver_dep_info = resolver.dep_info.lock();
581570
*resolver_dep_info = dep_info.clone();
582571
}
@@ -613,7 +602,6 @@ impl LspResolver {
613602
#[derive(Debug, Default, Clone)]
614603
pub struct ScopeDepInfo {
615604
pub deno_types_to_code_resolutions: HashMap<ModuleSpecifier, ModuleSpecifier>,
616-
pub has_node_specifier: bool,
617605
}
618606

619607
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
@@ -953,7 +941,7 @@ impl<'a> ResolverFactory<'a> {
953941
None,
954942
));
955943
let npm_version_resolver = Arc::new(NpmVersionResolver {
956-
types_node_version_req: Some(get_types_node_version_req()),
944+
types_node_version_req: None,
957945
link_packages: link_packages.0.clone(),
958946
newest_dependency_date_options: Default::default(),
959947
});

cli/lsp/tsc.rs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4728,7 +4728,10 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
47284728
let state = state.borrow::<State>();
47294729
let mark = state.performance.mark("tsc.op.op_is_node_file");
47304730
let r = match state.specifier_map.normalize(path) {
4731-
Ok(specifier) => state.state_snapshot.resolver.in_node_modules(&specifier),
4731+
Ok(specifier) => {
4732+
state.state_snapshot.resolver.in_node_modules(&specifier)
4733+
|| specifier.as_str().starts_with("asset:///node/")
4734+
}
47324735
Err(_) => false,
47334736
};
47344737
state.performance.measure(mark);
@@ -4738,16 +4741,7 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
47384741
#[op2]
47394742
#[serde]
47404743
fn op_libs() -> Vec<String> {
4741-
let mut out =
4742-
Vec::with_capacity(crate::tsc::LAZILY_LOADED_STATIC_ASSETS.len());
4743-
for key in crate::tsc::LAZILY_LOADED_STATIC_ASSETS.keys() {
4744-
let lib = key
4745-
.replace("lib.", "")
4746-
.replace(".d.ts", "")
4747-
.replace("deno_", "deno.");
4748-
out.push(lib);
4749-
}
4750-
out
4744+
crate::tsc::lib_names()
47514745
}
47524746

47534747
#[derive(Debug, thiserror::Error, deno_error::JsError)]
@@ -5101,11 +5095,6 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
51015095
by_notebook_uri: Default::default(),
51025096
};
51035097

5104-
let scopes_with_node_specifier = state
5105-
.state_snapshot
5106-
.document_modules
5107-
.scopes_with_node_specifier();
5108-
51095098
// Insert global scripts.
51105099
for (compiler_options_key, compiler_options_data) in
51115100
state.state_snapshot.compiler_options_resolver.entries()
@@ -5119,9 +5108,6 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
51195108
.as_ref()
51205109
.and_then(|s| state.state_snapshot.config.tree.scope_for_specifier(s))
51215110
.cloned();
5122-
if scopes_with_node_specifier.contains(&scope) {
5123-
script_names.insert("asset:///node_types.d.ts".to_string());
5124-
}
51255111
let scoped_resolver = state
51265112
.state_snapshot
51275113
.resolver

0 commit comments

Comments
 (0)