From 071f27a995e06e818c8674aa8f3ee54c66414593 Mon Sep 17 00:00:00 2001 From: Naoki Ikeguchi Date: Wed, 13 Aug 2025 16:56:44 +0900 Subject: [PATCH] Revert "feat(resolver): resolve extension alias (#7158)" This reverts commit 58f810236508660e2d31380d770c50f2f36e9d87. --- .changeset/petite-waves-love.md | 19 ------ .../src/js_module_info/visitor.rs | 11 +--- crates/biome_resolver/src/lib.rs | 60 +----------------- .../fixtures/resolver_cases_7/dir/index.js | 0 .../fixtures/resolver_cases_7/dir/index.ts | 0 .../fixtures/resolver_cases_7/dir2/index.js | 0 .../fixtures/resolver_cases_7/dir2/index.mts | 0 .../tests/fixtures/resolver_cases_7/index.js | 0 .../tests/fixtures/resolver_cases_7/index.mjs | 0 .../fixtures/resolver_cases_7/index.mts.js | 0 .../tests/fixtures/resolver_cases_7/index.ts | 0 crates/biome_resolver/tests/spec_tests.rs | 62 ------------------- 12 files changed, 4 insertions(+), 148 deletions(-) delete mode 100644 .changeset/petite-waves-love.md delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/dir/index.js delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/dir/index.ts delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/dir2/index.js delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/dir2/index.mts delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/index.js delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/index.mjs delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/index.mts.js delete mode 100644 crates/biome_resolver/tests/fixtures/resolver_cases_7/index.ts diff --git a/.changeset/petite-waves-love.md b/.changeset/petite-waves-love.md deleted file mode 100644 index 79a93bd0d664..000000000000 --- a/.changeset/petite-waves-love.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"@biomejs/biome": patch ---- - -The resolver can now correctly resolve `.ts`, `.tsx`, `.d.ts`, `.js` files by `.js` extension if exists, based on [the file extension substitution in TypeScript](https://www.typescriptlang.org/docs/handbook/modules/reference.html#file-extension-substitution). - -For example, the linter can now detect the floating promise in the following situation, if you have enabled the `noFloatingPromises` rule. - -**`foo.ts`** -```ts -export async function doSomething(): Promise {} -``` - -**`bar.ts`** -```ts -import { doSomething } from "./foo.js"; // doesn't exist actually, but it is resolved to `foo.ts` - -doSomething(); // floating promise! -``` diff --git a/crates/biome_module_graph/src/js_module_info/visitor.rs b/crates/biome_module_graph/src/js_module_info/visitor.rs index bf96668e4247..3b79a70e9083 100644 --- a/crates/biome_module_graph/src/js_module_info/visitor.rs +++ b/crates/biome_module_graph/src/js_module_info/visitor.rs @@ -18,14 +18,6 @@ use crate::{ use super::{ResolvedPath, collector::JsModuleInfoCollector}; -/// Extensions to try to resolve based on the extension in the import specifier. -/// ref: https://www.typescriptlang.org/docs/handbook/modules/reference.html#the-moduleresolution-compiler-option -const EXTENSION_ALIAS: &[(&str, &[&str])] = &[ - ("js", &["ts", "tsx", "d.ts", "js", "jsx"]), - ("mjs", &["mts", "d.mts", "mjs"]), - ("cjs", &["cts", "d.cts", "cjs"]), -]; - pub(crate) struct JsModuleVisitor<'a> { root: AnyJsRoot, directory: &'a Utf8Path, @@ -401,7 +393,7 @@ impl<'a> JsModuleVisitor<'a> { if let Ok(binding) = node.pattern() { self.visit_binding_pattern( binding, - collector, + collector, ); } } @@ -450,7 +442,6 @@ impl<'a> JsModuleVisitor<'a> { condition_names: &["types", "import", "default"], default_files: &["index"], extensions: SUPPORTED_EXTENSIONS, - extension_alias: EXTENSION_ALIAS, resolve_node_builtins: true, resolve_types: true, ..Default::default() diff --git a/crates/biome_resolver/src/lib.rs b/crates/biome_resolver/src/lib.rs index 1e5693a3f88c..33a94b04f24e 100644 --- a/crates/biome_resolver/src/lib.rs +++ b/crates/biome_resolver/src/lib.rs @@ -41,11 +41,7 @@ pub fn resolve( } if specifier.starts_with('/') { - return resolve_absolute_path_with_extension_alias( - Utf8PathBuf::from(specifier), - fs, - options, - ); + return resolve_absolute_path(Utf8PathBuf::from(specifier), fs, options); } if is_relative_specifier(specifier) { @@ -62,37 +58,6 @@ pub fn resolve( resolve_module(specifier, base_dir, fs, options) } -fn resolve_absolute_path_with_extension_alias( - path: Utf8PathBuf, - fs: &dyn ResolverFsProxy, - options: &ResolveOptions, -) -> Result { - // Skip if no extension is in the path. - let Some(extension) = path.extension() else { - return resolve_absolute_path(path, fs, options); - }; - - // Skip if no extension alias is configured. - let Some(&(_, aliases)) = options - .extension_alias - .iter() - .find(|(ext, _)| *ext == extension) - else { - return resolve_absolute_path(path, fs, options); - }; - - // Try to resolve the path for each extension alias. - for alias in aliases { - match resolve_absolute_path(path.with_extension(alias), fs, options) { - Ok(path) => return Ok(path), - Err(ResolveError::NotFound) => { /* continue */ } - Err(error) => return Err(error), - } - } - - Err(ResolveError::NotFound) -} - /// Resolves the given absolute `path`. /// /// Absolute paths are those starting with `/` or a Windows prefix/root. @@ -146,7 +111,7 @@ fn resolve_relative_path( fs: &dyn ResolverFsProxy, options: &ResolveOptions, ) -> Result { - resolve_absolute_path_with_extension_alias(base_dir.join(path), fs, options) + resolve_absolute_path(base_dir.join(path), fs, options) } /// Resolve the directory `dir_path`. @@ -755,16 +720,9 @@ pub struct ResolveOptions<'a> { /// Extensions are checked in the order given, meaning the first extension /// in the list has the highest priority. /// - /// Extensions should be provided without a leading dot. + /// Extensions should be provided without leading dot. pub extensions: &'a [&'a str], - /// List of extension aliases to search for in absolute or relative paths. - /// Typically used to resolve `.ts` files by `.js` extension. - /// Same behavior as the `extensionAlias` option in [enhanced-resolve](https://github.com/webpack/enhanced-resolve?tab=readme-ov-file#resolver-options). - /// - /// Extensions should be provided without a leading dot. - pub extension_alias: &'a [(&'a str, &'a [&'a str])], - /// Defines which `package.json` file should be used. /// /// See [`DiscoverableManifest`] for more details. @@ -834,7 +792,6 @@ impl<'a> ResolveOptions<'a> { condition_names: &[], default_files: &[], extensions: &[], - extension_alias: &[], package_json: DiscoverableManifest::Auto, resolve_node_builtins: false, resolve_types: false, @@ -873,15 +830,6 @@ impl<'a> ResolveOptions<'a> { self } - /// Sets [`Self::extension_alias`] and returns this instance. - pub const fn with_extension_alias( - mut self, - extension_alias: &'a [(&'a str, &'a [&'a str])], - ) -> Self { - self.extension_alias = extension_alias; - self - } - /// Sets [`Self::package_json`] and returns this instance. pub fn with_package_json( mut self, @@ -921,7 +869,6 @@ impl<'a> ResolveOptions<'a> { condition_names: self.condition_names, default_files: self.default_files, extensions: self.extensions, - extension_alias: self.extension_alias, package_json: DiscoverableManifest::Off, resolve_node_builtins: self.resolve_node_builtins, resolve_types: self.resolve_types, @@ -936,7 +883,6 @@ impl<'a> ResolveOptions<'a> { condition_names: self.condition_names, default_files: self.default_files, extensions: &[], - extension_alias: &[], package_json: DiscoverableManifest::Off, resolve_node_builtins: self.resolve_node_builtins, resolve_types: self.resolve_types, diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir/index.js b/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir/index.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir/index.ts b/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir/index.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir2/index.js b/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir2/index.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir2/index.mts b/crates/biome_resolver/tests/fixtures/resolver_cases_7/dir2/index.mts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.js b/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.mjs b/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.mjs deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.mts.js b/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.mts.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.ts b/crates/biome_resolver/tests/fixtures/resolver_cases_7/index.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/crates/biome_resolver/tests/spec_tests.rs b/crates/biome_resolver/tests/spec_tests.rs index a90ed463613a..e9b6b61ba5f5 100644 --- a/crates/biome_resolver/tests/spec_tests.rs +++ b/crates/biome_resolver/tests/spec_tests.rs @@ -533,65 +533,3 @@ fn test_resolve_type_definitions_without_type_specification() { ))) ); } - -#[test] -fn test_resolve_extension_alias() { - let base_dir = get_fixtures_path("resolver_cases_7"); - let fs = OsFileSystem::new(base_dir.clone()); - - let options = ResolveOptions { - default_files: &["index"], - extensions: &["js"], - extension_alias: &[("js", &["ts", "js"]), ("mjs", &["mts"])], - ..Default::default() - }; - - assert_eq!( - resolve("./index.js", &base_dir, &fs, &options), - Ok(Utf8PathBuf::from(format!("{base_dir}/index.ts"))), - "should alias fully specified file", - ); - - assert_eq!( - resolve("./dir/index.js", &base_dir, &fs, &options), - Ok(Utf8PathBuf::from(format!("{base_dir}/dir/index.ts"))), - "should alias fully specified file when there are two alternatives", - ); - - assert_eq!( - resolve("./dir2/index.js", &base_dir, &fs, &options), - Ok(Utf8PathBuf::from(format!("{base_dir}/dir2/index.js"))), - "should also allow the second alternative", - ); - - assert_eq!( - resolve("./dir2/index.mjs", &base_dir, &fs, &options), - Ok(Utf8PathBuf::from(format!("{base_dir}/dir2/index.mts"))), - "should support alias option without an array", - ); -} - -#[test] -fn test_resolve_extension_alias_not_apply_to_extension_nor_main_files() { - let base_dir = get_fixtures_path("resolver_cases_7"); - let fs = OsFileSystem::new(base_dir.clone()); - - let options = ResolveOptions { - default_files: &["index"], - extensions: &["js"], - extension_alias: &[("js", &[])], - ..Default::default() - }; - - assert_eq!( - resolve("./dir2", &base_dir, &fs, &options), - Ok(Utf8PathBuf::from(format!("{base_dir}/dir2/index.js"))), - "directory", - ); - - assert_eq!( - resolve("./dir2/index", &base_dir, &fs, &options), - Ok(Utf8PathBuf::from(format!("{base_dir}/dir2/index.js"))), - "file", - ); -}