CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nx--eslint-plugin

ESLint plugin for Nx monorepos with boundary enforcement and dependency management rules.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

module-boundaries.mddocs/

Module Boundary Enforcement

The enforce-module-boundaries rule is the cornerstone of Nx workspace integrity, ensuring proper separation of concerns and preventing architectural violations through comprehensive dependency analysis.

Capabilities

Enforce Module Boundaries Rule

Validates import statements against configured dependency constraints, checking for proper module boundaries, circular dependencies, and tagging compliance.

/**
 * ESLint rule that enforces module boundaries within Nx workspaces
 * Rule name: "@nx/enforce-module-boundaries"
 */
interface EnforceModuleBoundariesRule {
  name: "enforce-module-boundaries";
  meta: {
    type: "suggestion";
    docs: {
      description: "Ensure that module boundaries are respected within the monorepo";
    };
    fixable: "code";
    schema: [EnforceModuleBoundariesOptions];
    messages: Record<MessageIds, string>;
  };
  defaultOptions: [EnforceModuleBoundariesOptions];
  create: (context: RuleContext) => RuleListener;
}

Configuration Options

Complete configuration interface for the enforce-module-boundaries rule.

interface EnforceModuleBoundariesOptions {
  /** Array of allowed import patterns that bypass all boundary checks */
  allow: string[];
  
  /** Build target names used to determine buildable libraries */
  buildTargets: string[];
  
  /** Dependency constraints that define allowed relationships between projects */
  depConstraints: DepConstraint[];
  
  /** Enforce that libraries can only depend on other buildable libraries */
  enforceBuildableLibDependency: boolean;
  
  /** Allow projects to import from themselves (circular self-dependency) */
  allowCircularSelfDependency: boolean;
  
  /** Array of [source, target] project pairs to ignore for circular dependency checks */
  ignoredCircularDependencies: Array<[string, string]>;
  
  /** Project names exempt from dynamic dependency checks */
  checkDynamicDependenciesExceptions: string[];
  
  /** Prevent imports of transitive dependencies not declared in package.json */
  banTransitiveDependencies: boolean;
  
  /** Check for nested external imports beyond top-level package imports */
  checkNestedExternalImports: boolean;
}

Dependency Constraints

Configuration for tag-based dependency rules and external import restrictions.

interface DepConstraint {
  /** Source tag that this constraint applies to */
  sourceTag: string;
  
  /** If specified, projects with sourceTag can only depend on libraries with these tags */
  onlyDependOnLibsWithTags?: string[];
  
  /** If specified, projects with sourceTag cannot depend on libraries with these tags */
  notDependOnLibsWithTags?: string[];
  
  /** External imports that are banned for projects with this sourceTag */
  bannedExternalImports?: string[];
  
  /** Wildcard patterns for banned external imports */
  bannedExternalImportsPatterns?: string[];
  
  /** Allow specific external imports despite being in bannedExternalImports */
  allowedExternalImports?: string[];
}

/** Union type for complex constraint combinations */
type ComboDepConstraint = {
  allOf: DepConstraint[];
} | {
  anyOf: DepConstraint[];
};

Default Configuration

The rule comes with sensible defaults for most Nx workspaces.

const DEFAULT_OPTIONS: EnforceModuleBoundariesOptions = {
  allow: [],
  buildTargets: ['build'],
  depConstraints: [],
  enforceBuildableLibDependency: false,
  allowCircularSelfDependency: false,
  checkDynamicDependenciesExceptions: [],
  ignoredCircularDependencies: [],
  banTransitiveDependencies: false,
  checkNestedExternalImports: false
};

Error Messages

All possible violation messages returned by the rule.

type MessageIds =
  | "noRelativeOrAbsoluteImportsAcrossLibraries"
  | "noRelativeOrAbsoluteExternals" 
  | "noSelfCircularDependencies"
  | "noCircularDependencies"
  | "noImportsOfApps"
  | "noImportsOfE2e"
  | "noImportOfNonBuildableLibraries"
  | "noImportsOfLazyLoadedLibraries"
  | "projectWithoutTagsCannotHaveDependencies"
  | "bannedExternalImportsViolation"
  | "nestedBannedExternalImportsViolation"
  | "noTransitiveDependencies"
  | "onlyTagsConstraintViolation"
  | "emptyOnlyTagsConstraintViolation"
  | "notTagsConstraintViolation";

Usage Examples:

// Basic usage in ESLint config
{
  rules: {
    "@nx/enforce-module-boundaries": [
      "error",
      {
        depConstraints: [
          {
            sourceTag: "scope:shared",
            onlyDependOnLibsWithTags: ["scope:shared"]
          },
          {
            sourceTag: "type:feature",
            onlyDependOnLibsWithTags: ["type:ui", "type:data-access", "type:util"]
          }
        ],
        enforceBuildableLibDependency: true,
        allow: ["^@myorg/shared-.*"]
      }
    ]
  }
}

// Complex constraints with banned imports
{
  rules: {
    "@nx/enforce-module-boundaries": [
      "error", 
      {
        depConstraints: [
          {
            sourceTag: "platform:web",
            bannedExternalImports: ["react-native", "@react-native/*"],
            onlyDependOnLibsWithTags: ["platform:web", "platform:shared"]
          },
          {
            sourceTag: "scope:admin",
            notDependOnLibsWithTags: ["scope:customer"],
            bannedExternalImports: ["lodash"]
          }
        ],
        banTransitiveDependencies: true,
        checkNestedExternalImports: true
      }
    ]
  }
}

// Ignoring specific circular dependencies
{
  rules: {
    "@nx/enforce-module-boundaries": [
      "error",
      {
        allowCircularSelfDependency: true,
        ignoredCircularDependencies: [
          ["project-a", "project-b"],
          ["legacy-lib", "legacy-utils"]
        ]
      }
    ]
  }
}

Validation Behaviors

The rule performs several types of validation:

  1. Import Path Validation: Ensures imports follow proper patterns (no relative imports across project boundaries)
  2. Tag Constraint Validation: Enforces tag-based dependency rules
  3. Circular Dependency Detection: Identifies and prevents circular dependencies
  4. Buildable Library Enforcement: Ensures non-buildable libraries don't import buildable ones
  5. External Import Control: Manages allowed/banned external package imports
  6. Transitive Dependency Checks: Validates against importing undeclared transitive dependencies
  7. App Import Prevention: Prevents libraries from importing application code
  8. Dynamic Import Validation: Checks dynamic imports for compliance

Integration with Nx Project Graph

The rule integrates deeply with Nx's project graph system:

  • Reads project configurations and dependency relationships
  • Analyzes build targets to determine buildable libraries
  • Uses project tags for constraint matching
  • Leverages workspace layout for path resolution
  • Caches project graph data for performance

Install with Tessl CLI

npx tessl i tessl/npm-nx--eslint-plugin

docs

configurations.md

dependency-checks.md

index.md

module-boundaries.md

plugin-validation.md

workspace-rules.md

tile.json