-
-
Notifications
You must be signed in to change notification settings - Fork 442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
💅 noUndeclaredDependencies
: not resolving tsconfig paths nor package subpaths
#2012
Comments
It would be great to understand what you would expect from the rule. |
Same. Biome doesn't understand path aliases(?) Would be great if it could read {
"imports": {
"#*": "./app/*",
"##*": "./*"
},
} All my imports use And then you need to redefine them in {
"compilerOptions": {
"paths": {
"#*": ["./app/*"],
"##*": ["./*"]
}
}
} ESLint import package has this kind of syntax to define the path: {
settings: {
'import/internal-regex': '^#'
}
} |
Well what I would expect is not an error, since the path:
|
@ematipico I think this could be implemented using the |
Fixed in #2035 |
@kevinwolfcr Hello I don't think this should be closed because import aliases in |
Sorry @Sec-ant, I just re-opened it, I thought that since you were using |
No need, that's on me. I mentioned it in the PR but I didn't use that. It's just a simple fix for subpath exports only. I plan to take a further look into using |
Here is a POC to use fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let node = ctx.query();
let token_text = node.inner_string_text()?;
let specifier = token_text.text();
// Fast path: read package.json
// Ignore relative path imports
// Ignore imports using a protocol such as `node:`, `bun:`, `jsr:`, `https:`, and so on.
if specifier.starts_with('.') || specifier.contains(':') {
return None;
}
let mut parts = specifier.split('/');
let mut pointer = 0;
if let Some(maybe_scope) = parts.next() {
pointer += maybe_scope.len();
if maybe_scope.starts_with('@') {
// scoped package: @mui/material/Button
// the package name is @mui/material, not @mui
pointer += parts.next().map_or(0, |s| s.len() + 1)
}
}
let package_name = &specifier[..pointer];
if ctx.is_dependency(package_name) || ctx.is_dev_dependency(package_name) {
return None;
}
// Slow path: resolve using oxc_resolver.
let path = ctx.file_path();
let common_resolve_options = ResolveOptions {
tsconfig: Some(TsconfigOptions {
// TODO: The absolute path is a demonstration.
// We should use a "tsconfck" alternative in Rust
// to automatically find the correct configuration file.
config_file: PathBuf::from("/home/secant/biome/crates/biome_js_analyze/tests/specs/nursery/noUndeclaredDependencies/tsconfig.json"),
references: TsconfigReferences::Auto,
}),
extensions: vec![
".ts".into(),
".js".into(),
".tsx".into(),
".jsx".into(),
".json".into(),
],
// TODO: I think it only supports `imports` field in a `package.json` file
// adding other file names to `description_files` doesn't work,
// so we have to modify our test cases.
// description_files: vec!["valid.package.json".into(), "package.json".into()]
..ResolveOptions::default()
};
// TODO: Maybe use the "type" field in package.json
// to decide which resolver we should choose,
// and only use both of them when we can't decide
let esm_resolver = Resolver::new(
common_resolve_options
.clone()
.with_condition_names(&["node", "import"]),
);
// use clone_with_options so that we can share cache between two resolvers.
let cjs_resolver = esm_resolver.clone_with_options(
common_resolve_options
.clone()
.with_condition_names(&["node", "require"]),
);
esm_resolver.resolve(path, specifier).map_or_else(
|_| {
cjs_resolver
.resolve(path, specifier)
.map_or(Some(()), |_| None)
},
|_| None,
)
} I don't know if we have something similar to |
@Sec-ant how about just assuming there will always be a |
We can't do that. Biome doesn't assume the presence of a configuration file; in fact, it has worked out of the box since day one. Hence, we shouldn't assume the presence of |
Resolving tsconfig paths also impacts useImportExtensions from working properly. Oxc requires passing tsconfig path explicitely, that could be option in short term, but breaks once you deal with monorepos and so on. Looking into If implemented in biome where would that be? In |
@minht11 Yeah I believe so. I am going to close this bug for now because we don't yet have the infrastructure to enhance the rule, so it can't be fixed easily. As explained, we don't read If anyone wants to help with this, feel free to open a task and assign it to yourself. Of course, we are here to answer any question. If not, please bear with us while we draft a plan for it. Cheers |
@ematipico can you reopen this? The problem was fixed on an earlier biome version, but after upgrading to |
Environment information
Rule name
noUndeclaredDependencies
Playground link
N/A
Expected result
I couldn't replicate the issue on the playground because I couldn't find a way to add a
tsconfig.json
nor external dependencies, so I'll just put the relevant files and reports below:Files
tsconfig.json
tailwind.config.ts
app/layout.tsx
Reports
Code of Conduct
The text was updated successfully, but these errors were encountered: