Check entry point used for each element type
It checks import
statements to the elements of the project and ensure that each element is imported only by its defined entry-point based on the provided options rules.
"boundaries/entry-point": [<enabled>, { "default": <string>, "message": <string>, "rules": <object> }]
enabled
: for enabling the rule. 0=off, 1=warn, 2=error.default
:allow
ordisallow
. If no onerule
matches, the dependency will be allowed or disallowed based on this value.message
: Custom message for the rule errors. Note that the rule default message provides a lot of information about why the error was produced, so you should define a custom message only if you are sure about what you are doing. Read "error messages" for further information.rules
: Rules to be processed in order to decide if theimport
statement has to be allowed or not.target
:<element matchers>
If the element being imported matches with this, then the rule will be executed to know if it allows/disallows theimport
. If not, the rule is skipped.disallow
:<string>
Amicromatch
pattern. If the element being imported matches with this, then the result of the rule will be "disallow", and the import will be notified as aneslint
error (this value can be overwritten by a next rule returning "allow")allow
:<string>
Amicromatch
pattern. If the element being imported matches with this, then the result of the rule will be "allow", and the import will not be notified as aneslint
error (this value can be overwritten by a next rule returning "disallow")importKind
:<string>
Optional. It is useful only when using TypeScript, as it allows to define if the rule applies when the dependency is being imported as a value or as a type. It can be also defined as an array of strings, or a micromatch pattern. Note that possible values to match with are"value"
,"type"
or"typeof"
.message
:<string>
Custom error message only for this rule. Read "error messages" for further info.
{
"rules": {
"boundaries/entry-point": [2, {
// disallow all entry-points by default
"default": "disallow",
"rules": [
{
// when importing helpers
"target": ["helpers"],
// allow file (helpers are single files)
"allow": "*"
},
{
// when importing components or modules
"target": ["components", "modules"],
// only allow index.js
"allow": "index.js",
// allow only importing values, not types. Useful only in TypeScript
"importKind": "value"
}
]
}
]
}
}
Examples in the next sections are based on the previous options example and these files and settings.
src/
├── components/
│ ├── atoms/
│ │ ├── atom-a/
│ │ │ ├── index.js
│ │ │ └── AtomA.js
│ │ └── atom-b/
│ │ ├── index.js
│ │ └── AtomB.js
│ └── molecules/
│ ├── molecule-a/
│ │ ├── index.js
│ │ └── MoleculeA.js
│ └── molecule-b/
│ ├── index.js
│ └── MoleculeB.js
├── helpers/
│ ├── data/
│ │ ├── sort.js
│ │ └── parse.js
│ └── permissions/
│ └── roles.js
└── modules/
├── module-a/
│ ├── index.js
│ └── ModuleA.js
└── module-b/
├── index.js
└── ModuleB.js
{
"settings": {
"boundaries/elements": [
{
"type": "helpers",
"pattern": "helpers/*/*.js",
"mode": "file",
"capture": ["category", "elementName"]
},
{
"type": "components",
"pattern": "components/*/*",
"mode": "folder",
"capture": ["family", "elementName"]
},
{
"type": "modules",
"pattern": "modules/*",
"mode": "folder",
"capture": ["elementName"]
}
],
"import/resolver": {
"babel-module": {}
}
}
}
Next examples are written as is the project has configured babel aliases for folders
src/helpers
,src/components
andsrc/modules
. This is made for better readability of the examples, but it would work also with relative paths. You can configure the plugin to recognize babel aliases usingeslint-import-resolver-babel-module
as a resolver, as you can see in the settings example.
Any other file than index.js can't be imported from components
// modules/module-a/ModuleA.js
import AtomA from 'components/atoms/atom-a/AtomA'
Any other file than index.js can't be imported from modules
// modules/module-a/ModuleA.js
import ModuleB from 'modules/module-b/ModuleB'
type from index.js from modules can't be imported:
// src/modules/module-a/ModuleA.js
import type ModuleB from 'modules/module-b'
Helper file can be imported:
// src/components/atoms/atom-a/AtomA.js
import { someParser } from 'helpers/data/parse'
index.js from components can be imported:
// src/components/atoms/atom-a/AtomA.js
import ComponentB from 'components/atoms/atom-b'
index.js from components can be imported:
// src/components/atoms/atom-a/AtomA.js
import ComponentB from 'components/atoms/atom-b/index.js'
index.js from modules can be imported:
// src/modules/module-a/ModuleA.js
import ModuleB from 'modules/module-b'
This rule provides a lot of information about the specific option producing an error, so the user can have enough context to solve it.
- If the error is produced because all entry points are disallowed by default, and no rule is specificly allowing it, then the message provides information about the dependency type and captured values:
No rule allows the entry point 'fooFile.js' in dependencies of type 'components' with category 'molecules' and elementName 'molecule-c'
. - If the error is produced by a specific option, then the message includes information about the option producing it:
The entry point 'fooFile.js' is not allowed in elements of type 'helpers' with elementName 'helper-c'. Disallowed in rule 2
- If the rule contains an
importKind
property, then the message also includes information about the import kind:The entry point 'fooFile.js' is not allowed in elements of type 'helpers' with elementName 'helper-c' when importing type. Disallowed in rule 2
You can also configure a custom error message for changing this default behaviour, or even custom error messages only for a specific rule option. Read "error messages" in the main docs for further info about how to configure messages.
Read how to configure the boundaries/elements
setting to assign an element type to each project's file.