mirror of
https://github.com/denoland/deno.git
synced 2025-08-03 18:38:33 +00:00
feat(npm): support bare specifiers from package.json in more subcommands and language server (#17891)
This commit is contained in:
parent
214bdbbc2b
commit
344317ec50
41 changed files with 472 additions and 95 deletions
|
@ -9,12 +9,14 @@ use deno_core::serde_json;
|
|||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_runtime::deno_node::PackageJson;
|
||||
use deno_runtime::deno_web::BlobStore;
|
||||
use import_map::ImportMap;
|
||||
use log::error;
|
||||
use log::warn;
|
||||
use serde_json::from_value;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::PathBuf;
|
||||
|
@ -58,6 +60,7 @@ use super::tsc::AssetsSnapshot;
|
|||
use super::tsc::TsServer;
|
||||
use super::urls;
|
||||
use crate::args::get_root_cert_store;
|
||||
use crate::args::package_json;
|
||||
use crate::args::resolve_import_map_from_specifier;
|
||||
use crate::args::CaData;
|
||||
use crate::args::CacheSetting;
|
||||
|
@ -130,6 +133,8 @@ pub struct Inner {
|
|||
maybe_import_map: Option<Arc<ImportMap>>,
|
||||
/// The URL for the import map which is used to determine relative imports.
|
||||
maybe_import_map_uri: Option<Url>,
|
||||
/// An optional package.json configuration file.
|
||||
maybe_package_json: Option<PackageJson>,
|
||||
/// Configuration for formatter which has been taken from specified config file.
|
||||
fmt_options: FmtOptions,
|
||||
/// An optional configuration for linter which has been taken from specified config file.
|
||||
|
@ -376,6 +381,7 @@ impl Inner {
|
|||
maybe_config_file: None,
|
||||
maybe_import_map: None,
|
||||
maybe_import_map_uri: None,
|
||||
maybe_package_json: None,
|
||||
fmt_options: Default::default(),
|
||||
lint_options: Default::default(),
|
||||
maybe_testing_server: None,
|
||||
|
@ -456,8 +462,6 @@ impl Inner {
|
|||
Ok(navigation_tree)
|
||||
}
|
||||
|
||||
/// Returns a tuple with parsed `ConfigFile` and `Url` pointing to that file.
|
||||
/// If there's no config file specified in settings returns `None`.
|
||||
fn get_config_file(&self) -> Result<Option<ConfigFile>, AnyError> {
|
||||
let workspace_settings = self.config.get_workspace_settings();
|
||||
let maybe_config = workspace_settings.config;
|
||||
|
@ -501,6 +505,28 @@ impl Inner {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_package_json(
|
||||
&self,
|
||||
maybe_config_file: Option<&ConfigFile>,
|
||||
) -> Result<Option<PackageJson>, AnyError> {
|
||||
// It is possible that root_uri is not set, for example when having a single
|
||||
// file open and not a workspace. In those situations we can't
|
||||
// automatically discover the configuration
|
||||
if let Some(root_uri) = &self.config.root_uri {
|
||||
let root_path = specifier_to_file_path(root_uri)?;
|
||||
let maybe_package_json = package_json::discover_from(
|
||||
&root_path,
|
||||
maybe_config_file.and_then(|f| f.specifier.to_file_path().ok()),
|
||||
)?;
|
||||
Ok(maybe_package_json.map(|c| {
|
||||
lsp_log!(" Auto-resolved package.json: \"{}\"", c.specifier());
|
||||
c
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_diagnosable(&self, specifier: &ModuleSpecifier) -> bool {
|
||||
if specifier.scheme() == "asset" {
|
||||
matches!(
|
||||
|
@ -785,6 +811,7 @@ impl Inner {
|
|||
|
||||
fn update_config_file(&mut self) -> Result<(), AnyError> {
|
||||
self.maybe_config_file = None;
|
||||
self.maybe_package_json = None;
|
||||
self.fmt_options = Default::default();
|
||||
self.lint_options = Default::default();
|
||||
|
||||
|
@ -814,6 +841,15 @@ impl Inner {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Updates the package.json. Always ensure this is done after updating
|
||||
/// the configuration file as the resolution of this depends on that.
|
||||
fn update_package_json(&mut self) -> Result<(), AnyError> {
|
||||
self.maybe_package_json = None;
|
||||
self.maybe_package_json =
|
||||
self.get_package_json(self.maybe_config_file.as_ref())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_tsconfig(&mut self) -> Result<(), AnyError> {
|
||||
let mark = self.performance.mark("update_tsconfig", None::<()>);
|
||||
let mut tsconfig = TsConfig::new(json!({
|
||||
|
@ -923,6 +959,9 @@ impl Inner {
|
|||
if let Err(err) = self.update_config_file() {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
if let Err(err) = self.update_package_json() {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
if let Err(err) = self.update_tsconfig().await {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
|
@ -950,6 +989,7 @@ impl Inner {
|
|||
self.documents.update_config(
|
||||
self.maybe_import_map.clone(),
|
||||
self.maybe_config_file.as_ref(),
|
||||
self.maybe_package_json.as_ref(),
|
||||
self.npm_resolver.api().clone(),
|
||||
self.npm_resolver.resolution().clone(),
|
||||
);
|
||||
|
@ -1129,6 +1169,9 @@ impl Inner {
|
|||
if let Err(err) = self.update_config_file() {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
if let Err(err) = self.update_package_json() {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
if let Err(err) = self.update_import_map().await {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
|
@ -1139,6 +1182,7 @@ impl Inner {
|
|||
self.documents.update_config(
|
||||
self.maybe_import_map.clone(),
|
||||
self.maybe_config_file.as_ref(),
|
||||
self.maybe_package_json.as_ref(),
|
||||
self.npm_resolver.api().clone(),
|
||||
self.npm_resolver.resolution().clone(),
|
||||
);
|
||||
|
@ -1155,7 +1199,7 @@ impl Inner {
|
|||
.performance
|
||||
.mark("did_change_watched_files", Some(¶ms));
|
||||
let mut touched = false;
|
||||
let changes: Vec<Url> = params
|
||||
let changes: HashSet<Url> = params
|
||||
.changes
|
||||
.iter()
|
||||
.map(|f| self.url_map.normalize_url(&f.uri))
|
||||
|
@ -1163,7 +1207,7 @@ impl Inner {
|
|||
|
||||
// if the current tsconfig has changed, we need to reload it
|
||||
if let Some(config_file) = &self.maybe_config_file {
|
||||
if changes.iter().any(|uri| config_file.specifier == *uri) {
|
||||
if changes.contains(&config_file.specifier) {
|
||||
if let Err(err) = self.update_config_file() {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
|
@ -1173,10 +1217,18 @@ impl Inner {
|
|||
touched = true;
|
||||
}
|
||||
}
|
||||
if let Some(package_json) = &self.maybe_package_json {
|
||||
if changes.contains(&package_json.specifier()) {
|
||||
if let Err(err) = self.update_package_json() {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
touched = true;
|
||||
}
|
||||
}
|
||||
// if the current import map, or config file has changed, we need to reload
|
||||
// reload the import map
|
||||
if let Some(import_map_uri) = &self.maybe_import_map_uri {
|
||||
if changes.iter().any(|uri| import_map_uri == uri) || touched {
|
||||
if changes.contains(import_map_uri) || touched {
|
||||
if let Err(err) = self.update_import_map().await {
|
||||
self.client.show_message(MessageType::WARNING, err).await;
|
||||
}
|
||||
|
@ -1187,6 +1239,7 @@ impl Inner {
|
|||
self.documents.update_config(
|
||||
self.maybe_import_map.clone(),
|
||||
self.maybe_config_file.as_ref(),
|
||||
self.maybe_package_json.as_ref(),
|
||||
self.npm_resolver.api().clone(),
|
||||
self.npm_resolver.resolution().clone(),
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue