From 933b0a57f411b49e3f8774b86e73bb75e20b70a2 Mon Sep 17 00:00:00 2001 From: Mohit Karekar Date: Mon, 22 Dec 2025 13:19:54 +0100 Subject: [PATCH] feat(linter): Update is_relative_path to include other relative patterns --- crates/oxc_linter/src/rules/import/first.rs | 26 ++++++++++++++++++- .../src/snapshots/import_first.snap | 16 ++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/import/first.rs b/crates/oxc_linter/src/rules/import/first.rs index cfe9620980744..287ec375c5281 100644 --- a/crates/oxc_linter/src/rules/import/first.rs +++ b/crates/oxc_linter/src/rules/import/first.rs @@ -83,7 +83,9 @@ declare_oxc_lint!( ); fn is_relative_path(path: &str) -> bool { - path.starts_with("./") + // A path is considered relative if it starts with "/", "./", or "../" + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#module_specifier_resolution + path.starts_with("./") || path.starts_with("../") || path.starts_with('/') } /// @@ -169,6 +171,17 @@ fn test() { export { x, y }", None, ), + // Relative imports with absolute-first + ( + r"import { y } from 'bar'; + import { x } from '../foo';", + Some(json!(["absolute-first"])), + ), + ( + r"import { y } from 'bar'; + import { x } from '/foo';", + Some(json!(["absolute-first"])), + ), ]; let fail = vec![ @@ -208,6 +221,17 @@ fn test() { import F3 = require('mod');", None, ), + // Relative imports with absolute-first + ( + r"import { x } from '../foo'; + import { y } from 'bar';", + Some(json!(["absolute-first"])), + ), + ( + r"import { x } from '/foo'; + import { y } from 'bar';", + Some(json!(["absolute-first"])), + ), ]; Tester::new(First::NAME, First::PLUGIN, pass, fail) diff --git a/crates/oxc_linter/src/snapshots/import_first.snap b/crates/oxc_linter/src/snapshots/import_first.snap index 3b0cc6fed1a6b..874561b1bd952 100644 --- a/crates/oxc_linter/src/snapshots/import_first.snap +++ b/crates/oxc_linter/src/snapshots/import_first.snap @@ -81,3 +81,19 @@ source: crates/oxc_linter/src/tester.rs · ─────────────────────────── ╰──── help: Move import statement to the top of the file + + ⚠ eslint-plugin-import(first): Relative imports before absolute imports are prohibited + ╭─[index.ts:2:33] + 1 │ import { x } from '../foo'; + 2 │ import { y } from 'bar'; + · ───── + ╰──── + help: Move absolute import above relative import + + ⚠ eslint-plugin-import(first): Relative imports before absolute imports are prohibited + ╭─[index.ts:2:33] + 1 │ import { x } from '/foo'; + 2 │ import { y } from 'bar'; + · ───── + ╰──── + help: Move absolute import above relative import