no-restricted-paths
Added in v0.8.0Configuration
Rule Details
Some projects contain files that are not meant to run in the same environment. A web application, for example, may hold server-only code next to browser code, and importing the server code from the client bundle would ship it to the browser.
This rule lets you declare restricted zones: a target set of files, and a from set of files those targets are not allowed to import.
The rule takes one option object with a list of zones and an optional basePath used to resolve the relative paths inside each zone. basePath defaults to the current working directory.
Each zone accepts:
target— which files belong to the zone. A directory path (matching everything inside it recursively), a glob pattern, or an array of either.from— which files the zone may not import. A directory path, a glob pattern, or an array of only directory paths or only glob patterns.except— optional. Imports that are allowed even thoughfromcovers them. Whenfromis a directory path, each entry is resolved relative tofromand must stay inside it. Whenfromis a glob pattern, each entry must be a glob pattern too.message— optional. Appended to the reported message.
from is matched against the resolved path of the imported file, not against the specifier text as written in the source.
Given this folder structure:
Examples of incorrect code for this rule:
Examples of correct code for this rule:
except
Given this folder structure:
Examples of incorrect code for this rule:
Examples of correct code for this rule:
basePath
Relative target and from paths are resolved against basePath, and a relative basePath is itself resolved against the current working directory. except entries stay relative to their zone's from.
message
reports Unexpected path "../server/bar" imported in restricted zone. Use the API client instead.
Differences from ESLint
- Glob patterns support
*,**,?,[abc]character classes and{a,b}alternatives. Extended glob syntax —!(a),@(a|b),+(a),?(a),*(a)— is matched as the literal text it is written as, so./src/?(server)/**/*covers a directory named?(server)rather than one namedserver. Write{server,shared}instead of@(server|shared), and name the directories you want to cover instead of excluding one with!(...). - A
*matches path segments that begin with a dot, so./src/*covers./src/.hidden.tsas well. - A package specifier resolves the way TypeScript resolves it, so it lands on the file a package's
typesentry names. ESLint's resolver followsmaininstead, so for a package published with"main": "index.js"and"types": "index.d.ts"the same import resolves toindex.d.tshere and toindex.jsunder ESLint. This only shows up in a zone that names a single file inside a package:from: "./node_modules/some-package/index.d.ts"restricts the import here and nothing under ESLint, andfrom: "./node_modules/some-package/index.js"the other way around. Name the package directory —./node_modules/some-package— and the zone applies under both, whichever file the specifier lands on. - A relative specifier resolves under the project's TypeScript compiler options, so
moduleSuffixesandrootDirssteer it to the file TypeScript itself would load. ESLint's resolver reads neither option, so a project that sets one can land the same specifier on a different file under each. Name the directory holding both candidates, and the zone applies under both.