eslint-plugin-strict-dependencies
Advanced tools
Comparing version 1.1.0 to 1.2.0
{ | ||
"name": "eslint-plugin-strict-dependencies", | ||
"description": "ESlint plugin to define custom module dependency rules.", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"repository": { | ||
@@ -6,0 +6,0 @@ "type": "git", |
# eslint-plugin-strict-dependencies | ||
ESlint plugin to define custom module dependency rules. | ||
ESLint plugin to define custom module dependency rules. | ||
@@ -17,3 +17,6 @@ NOTE: `eslint-plugin-strict-dependencies` uses tsconfig, tsconfig.json must be present. | ||
- module: `string` (Glob or Forward matching string) | ||
- target module path | ||
- Target module path | ||
- targetMembers: `string[]` | ||
- Target member name | ||
- e.x. `["Suspense"]` in `import { Suspense } from 'react'` | ||
- allowReferenceFrom: `string[]` (Glob or Forward matching string) | ||
@@ -88,2 +91,13 @@ - Paths of files where target module imports are allowed. | ||
}, | ||
/** | ||
* example: | ||
* Disallow to import Suspense from react. it should always be imported using `libs/react.ts`. | ||
*/ | ||
{ | ||
"module": "react", | ||
"targetMembers": ["Suspense"], | ||
"allowReferenceFrom": ["src/libs/react.ts"], | ||
"allowSameModule": false | ||
}, | ||
], | ||
@@ -90,0 +104,0 @@ // options |
@@ -71,15 +71,38 @@ /* eslint-disable */ | ||
// specにはImportDefaultSpecifier/ImportNamespaceSpecifier/ImportSpecifierがあり、ImportSpecifierの場合はimportedが存在する | ||
const importedModules = node.specifiers.filter(spec => 'imported' in spec).map(spec => spec.imported.name) | ||
dependencies | ||
.filter((dependency) => isMatch(importPath, dependency.module)) | ||
.forEach((dependency) => { | ||
const isAllowed = | ||
// 参照元が許可されている | ||
dependency.allowReferenceFrom.some((allowPath) => | ||
isMatch(relativeFilePath, allowPath), | ||
) || // または同一モジュール間の参照が許可されている場合 | ||
(dependency.allowSameModule && isMatch(relativeFilePath, dependency.module)) | ||
// そもそもmoduleがimportPathと一致していない場合は必ず報告しない | ||
if (!isMatch(importPath, dependency.module)) return; | ||
if (!isAllowed) { | ||
context.report(node, `import '${importPath}' is not allowed from ${relativeFilePath}.`) | ||
/** | ||
* 1. 参照元チェックをしてAllowであればそこで処理を終了する | ||
* 2. targetMembersが指定されていれば、targetMembersと実際にimportしているモジュールを比較して含まれていればエラーレポートして処理を終了する | ||
* 3. targetMembersが指定されていない場合は、エラー扱いなのでエラーレポートして処理を終了する | ||
*/ | ||
const isAllowedByPath = | ||
// 参照元が許可されている | ||
dependency.allowReferenceFrom.some((allowPath) => | ||
isMatch(relativeFilePath, allowPath), | ||
) || // または同一モジュール間の参照が許可されている場合 | ||
(dependency.allowSameModule && isMatch(relativeFilePath, dependency.module)) | ||
if (isAllowedByPath) return | ||
// importedされた値・型名もLintのターゲットに入っている場合の検出処理 | ||
function getCommonElements(arrA, arrB) { | ||
return arrA.filter(element => arrB.includes(element)); | ||
} | ||
if (dependency.targetMembers && Array.isArray(dependency.targetMembers)) { | ||
const commonImportedList = getCommonElements(dependency.targetMembers, importedModules) | ||
if (commonImportedList.length > 0) { | ||
context.report(node, `import specifier '${commonImportedList.join(', ')}' is not allowed from ${relativeFilePath}.`) | ||
} | ||
return; | ||
} | ||
context.report(node, `import '${importPath}' is not allowed from ${relativeFilePath}.`) | ||
}) | ||
@@ -86,0 +109,0 @@ } |
11247
145
116