import-js / eslint-plugin-import

ESLint plugin with rules that help validate proper imports.
MIT License
5.55k stars 1.57k forks source link

Enhancement: [import/no-restricted-paths] accept target exceptions #3050

Open velvolue opened 1 month ago

velvolue commented 1 month ago

In order to support more complex use-cases, it would be really nice to be able to exclude parts of the target path.

Suggested config:

zones: [
  {
    target: './common',
    exceptTarget: './common/tests',
    from: './features',
    message: 'Avoid importing from features.'
  }
]

It could be implemented pretty simple by extending the matchingZones filter:

diff --git a/src/rules/no-restricted-paths.js b/src/rules/no-restricted-paths.js
index 75952dd0..22e06a52 100644
--- a/src/rules/no-restricted-paths.js
+++ b/src/rules/no-restricted-paths.js
@@ -53,0 +54,11 @@ module.exports = {
+                exceptTarget: {
+                  anyOf: [
+                    { type: 'string' },
+                    {
+                      type: 'array',
+                      items: { type: 'string' },
+                      uniqueItems: true,
+                      minLength: 1,
+                    },
+                  ],
+                },
@@ -92 +103,4 @@ module.exports = {
-        .some((targetPath) => isMatchingTargetPath(currentFilename, targetPath)),
+        .some((targetPath) => isMatchingTargetPath(currentFilename, targetPath))
+        && ![].concat(zone.exceptTarget || [])
+        .map((except) => path.resolve(basePath, except))
+        .some((exceptPath) => isMatchingTargetPath(currentFilename, exceptPath)),

This would also resolve #2800

ljharb commented 1 month ago

Can't you already handle this by using eslint overrides?

velvolue commented 1 month ago

Can't you already handle this by using eslint overrides?

Some use-cases can be solved with overrides, but sadly not all. If you have multiple zones for the same target with different exceptions, you can't represent that with overrides as they would cancel each other out.

velvolue commented 1 month ago

For our use-case specifically, we managed to find a way using overrides in the end (though not as clean as I hoped), so this issue is not a blocker for us. I still think this would be a nice feature though 🙂

ljharb commented 1 month ago

also can't target be combined with except already?

velvolue commented 1 month ago

also can't target be combined with except already?

No, except applies only to from as the documentation states:

except may be defined for a zone, allowing exception paths that would otherwise violate the related from. Note that it does not alter the behaviour of target in any way.

It would be nice if target and from had similar configuration. Either through execpt/exceptTarget as suggested here, or by allowing negated paths.