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.