The @nx/enforce-module-boundaries lint rule enables you to define strict rules for accessing resources between different projects in the repository. Enforcing strict boundaries helps to prevent unplanned cross-dependencies.
Add the rule to your linter configuration:
import nxPlugin from '@nx/eslint-plugin';
export default [ ...nxPlugin.configs['flat/base'], ...nxPlugin.configs['flat/typescript'], ...nxPlugin.configs['flat/javascript'], { files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], rules: { '@nx/enforce-module-boundaries': [ 'error', { // ...rule specific configuration }, ], }, },];{ // ... more ESLint config here "overrides": [ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "rules": { "@nx/enforce-module-boundaries": [ "error", { // ...rule specific configuration }, ], }, }, // ... more ESLint overrides here ],}{ "jsPlugins": ["@nx/oxlint/boundaries-plugin"], "rules": { "@nx/enforce-module-boundaries": [ "error", { // ...rule specific configuration } ] }}Options
Section titled “Options”| Property | Type | Default | Description |
|---|---|---|---|
| allow | Array<string> | [] | List of imports that should be allowed without any checks |
| allowCircularSelfDependency | boolean | false | Disable check for self circular dependency when project imports from itself via alias path |
| banTransitiveDependencies | boolean | false | Ban import of dependencies that were not specified in the root or project's package.json |
| ignoredCircularDependencies | Array<[string, string]> | [] | List of project pairs that should be skipped from Circular dependencies checks, including the self-circular dependency check. E.g. ['feature-project-a', 'myapp']. Project name can be replaced by catch all * for more generic matches. |
| checkDynamicDependenciesExceptions | Array<string> | [] | List of imports that should be skipped for Imports of lazy-loaded libraries forbidden checks. E.g. ['@myorg/lazy-project/component/*', '@myorg/other-project'] |
| checkNestedExternalImports | boolean | false | Enable to also apply the bannedExternalImports and allowedExternalImports constraints to the external packages that imported projects depend on, transitively. The nested check compares whole package names. In bannedExternalImports, a subpath entry such as lodash/fp only applies to direct imports. In allowedExternalImports, a subpath entry does not allow the package for the nested check, so the rule reports the nested dependency. Check Dependency constraints for more information |
| enforceBuildableLibDependency | boolean | false | Enable to restrict the buildable libs from importing non-buildable libraries |
| depConstraints | Array<object> | [] | List of dependency constraints between projects |
Dependency constraints
Section titled “Dependency constraints”The depConstraints is an array of objects representing the constraints defined between source and target projects. A constraint must include sourceTag or allSourceTags. The constraints are applied with AND logical operation - for a given source project the resulting constraints would be all that match its tags.
| Property | Type | Description |
|---|---|---|
| sourceTag | string | Tag that source project must contain to match the constraint |
| allSourceTags | Array<string> | List of tags the source project must contain to match the constraint |
| onlyDependOnLibsWithTags | Array<string> | The source can depend only on projects that contain at least one of these tags |
| notDependOnLibsWithTags | Array<string> | The source can not depend on projects that contain at least one of these tags |
| allowedExternalImports | Array<string> | Exclusive list of external (npm) packages that are allowed to be imported |
| bannedExternalImports | Array<string> | List of external (npm) packages that are banned from importing |
E2E tests that hash from their imports
Section titled “E2E tests that hash from their imports”An atomized e2e test file with // @nx-ignore-server-inputs imports app code so its task hashes from that code. For its bare imports of other projects, such as import '../../shop/src/app/checkout/checkout-page', the rule skips these checks:
- Relative and absolute imports.
- Imports of apps.
- Static imports of lazy-loaded libraries.
depConstraints.
It still checks imports of e2e projects, circular dependencies, and direct imports of external packages. Imports that name values or types get the usual checks. A test file with only an @nx-depends-on directive gets every check. A file counts as atomized when its project has a target named <target>--<file path>, with the file path relative to the project root, such as e2e-ci--src/checkout.spec.ts.
Read more about the proper usage of this rule: