Eslint no-restricted-imports only restrict importing from a package root?

2 min read 06-10-2024
Eslint no-restricted-imports only restrict importing from a package root?


Mastering Imports: Why ESLint's no-restricted-imports Might Not Be Enough

Problem: You're using ESLint's no-restricted-imports rule to prevent developers from importing directly from a package's root directory. However, you've noticed that it only restricts imports from the top-level directory and doesn't stop imports from subdirectories within the same package.

Solution: ESLint's no-restricted-imports rule, while powerful, has a limitation: it primarily focuses on the package root. To effectively control imports within a package, you'll need to leverage a more comprehensive approach.

Example: Imagine you have a package my-utils structured as follows:

my-utils
├── index.js
└── utils
    └── stringUtils.js

You want to enforce that developers import specific utilities like stringUtils from my-utils/utils/stringUtils.js rather than directly from my-utils/index.js.

Current Limitation:

// This import is allowed by 'no-restricted-imports'
import { stringUtils } from 'my-utils/utils/stringUtils'; 

// This import is also allowed by 'no-restricted-imports'
import { stringUtils } from 'my-utils'; 

// This import will be flagged by 'no-restricted-imports'
import { stringUtils } from 'my-utils/index.js'; 

Solution: To restrict imports from specific subdirectories within a package, you can use the pattern property within the no-restricted-imports rule.

module.exports = {
  "rules": {
    "no-restricted-imports": [
      "error",
      {
        "paths": [
          {
            "name": "my-utils",
            "message": "Please import from 'my-utils/utils' instead.",
            "importNames": ["*"], // This restricts all imports
            "pattern": "my-utils(/.*)?", // Matches the entire package and subdirectories
            "allow": ["my-utils/utils/*"] 
          }
        ]
      }
    ]
  }
};

This configuration will:

  • Restrict: Imports from any path starting with "my-utils", including subdirectories like "utils".
  • Allow: Imports from "my-utils/utils/*", providing the flexibility to access individual utility files.
  • Message: Display a custom message explaining the preferred import path.

Key Takeaways:

  • no-restricted-imports is a powerful rule for controlling package imports, but it's not always enough.
  • Use the pattern property to restrict imports from specific subdirectories within a package.
  • Be specific with the allow property to provide exceptions and control which imports are allowed.

Additional Tips:

  • Code Clarity: Enforcing structured imports improves code readability and maintainability.
  • Consistency: Encourage a consistent import style across your codebase.
  • Documentation: Document your import restrictions for clear guidance to other developers.

By understanding the limitations of no-restricted-imports and using the pattern property effectively, you can enforce a more robust and consistent import structure within your projects. This promotes cleaner code, enhances maintainability, and ensures everyone adheres to the desired import paths.