1.0.3 • Published 6 months ago

eslint-plugin-feature-sliced-design-imports v1.0.3

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

eslint-plugin-feature-sliced-design-imports

Custom ESLint plugin designed to enforce strict import rules in projects following the Feature-Sliced Design architecture.

Installation

Install ESLint:

npm i eslint --save-dev

Next install eslint-plugin-feature-sliced-design-imports:

npm install eslint-plugin-feature-sliced-design-imports --save-dev

Usage

Add feature-sliced-design-imports to the plugins section of your eslint configuration file. You can omit the eslint-plugin- prefix:

{
    "plugins": [
        "feature-sliced-design-imports"
    ]
}

Settings

Add custom layers or alias if needed:

{
    "settings": [
        "feature-sliced-design-imports/layers": {
            "app": "app-layer",
            "pages": "pages-layer",
            "entities": "custom-entities-layer-name",
        },
        "feature-sliced-design-imports/alias": "@"
    ]
}

Rules

Then configure the rules you want to use under the rules section.

{
    "rules": {
        "feature-sliced-design-imports/layer-imports": "error",
        "feature-sliced-design-imports/public-api-imports": "error",
        "feature-sliced-design-imports/relative-imports": "error",
    }
}

1. layer-imports

Purpose

This rule enforces strict import order between defined architectural layers (e.g., app, shared, features, entities, etc.) in a feature-sliced design architecture. It ensures that higher-level layers only import from allowed lower-level layers to maintain a clear dependency hierarchy. The proccess layer isn't supported.

Key Features

  • Allowed Layers: Each layer has a defined set of layers it can import from, based on the plugin configuration.
  • Cross-Entity Imports: Imports between entities must use the @x folder convention to encapsulate shared logic or functionality.
  • Alias Support: Handles imports with aliases defined in the global configuration.
  • Ignored Patterns: Specific imports can be ignored based on patterns provided in the configuration.

Examples

  • Valid:
    // @/entities/user/ui/UserForm
    import { Button } from '@/shared/ui/Button'; // shared -> entities
    // @/entities/message/ui/MessageCard
    import { UserType } from '@/entities/user/@x/message'; // Cross-entity via @x folder
  • Invalid:
    // @/entities/user/ui/UserForm
    import { SomeType } from '@/features/auth-user'; // features -> entities
    //  @/entities/message/ui/MessageCard
    import { UserType } from '@/entities/user'; // Cross-entity without @x folder

Configuration example

{
    "feature-sliced-design-imports/layer-imports": ["error", {
        "ignoreImportsPattern": ["**/Store", "**/*.test.ts"]
    }],
}

2. relative-imports

Purpose

This rule enforces that imports within the same entity and layer use relative paths. This helps improve modularity and reduce coupling between slices of the same layer.

Key Features

  • Relative Path Check: Ensures that imports within the same layer and entity are always relative.
  • Layer Awareness: The rule understands custom layers defined in the configuration and applies relative path checks accordingly.
  • Cross-Slice Restriction: Prevents absolute imports within the same entity.

Examples

  • Valid:
    // @/entities/user/ui/UserCard
    import { UserType } from '../model/UserType'; // Relative import within the same entity
  • Invalid:
    // @/entities/user/ui/UserCard
    import { UserType } from '@/entities/user/model/UserType'; // Absolute import within the same entity
    import { UserType } from '@/entities/user'; // Absolute import from public api within the same entity

Configuration example

{
    "feature-sliced-design-imports/relative-imports": "error",
}

3. public-api-imports

Purpose

This rule enforces that imports from other layers or entities should only access the public API of those modules. For test files, it allows importing from a dedicated public testing API.

Key Features

  • Public API Enforcement: Ensures that imports from other entities or layers only access public APIs (index.ts or equivalent).
  • Testing API: Allows test files to access public testing APIs via testing.{ts,js} point, ensuring test isolation.
  • Pattern-Based Validation: Uses configurable patterns to identify test files and validate their imports.
  • Cross-Entity Encapsulation: Validates that cross-entity imports use the @x folder when necessary.

Examples

  • Valid:
    import { Button } from '@/entities/user'; // Importing from public API
    // myFile.test.ts or any file -> "should be allowed in configuration"
    import { mockUser } from '@/entities/user/testing'; // Importing from testing public API in an allowed test file
  • Invalid:
    import { UserType } from '@/entities/user/model/UserType'; // Importing from private module
    // @/pages/home/ui/Page
    import { mockUser } from '@/entities/user/testing'; // Testing API imported in a production file

Configuration example

{
    "feature-sliced-design-imports/public-api-imports": ["error", {
        "testFilePatterns": ["**/*.test.ts", "**/*-test.{ts,js}"]
    }],
}