eslint-plugin-strict-dependencies 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -2
- package/package.json +6 -6
- package/strict-dependencies/index.js +32 -9
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# eslint-plugin-strict-dependencies
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ESLint plugin to define custom module dependency rules.
|
|
4
4
|
|
|
5
5
|
NOTE: `eslint-plugin-strict-dependencies` uses tsconfig, tsconfig.json must be present.
|
|
6
6
|
|
|
@@ -14,7 +14,10 @@ npm install eslint-plugin-strict-dependencies --save-dev
|
|
|
14
14
|
|
|
15
15
|
- strict-dependencies
|
|
16
16
|
- module: `string` (Glob or Forward matching string)
|
|
17
|
-
-
|
|
17
|
+
- Target module path
|
|
18
|
+
- targetMembers: `string[]`
|
|
19
|
+
- Target member name
|
|
20
|
+
- e.x. `["Suspense"]` in `import { Suspense } from 'react'`
|
|
18
21
|
- allowReferenceFrom: `string[]` (Glob or Forward matching string)
|
|
19
22
|
- Paths of files where target module imports are allowed.
|
|
20
23
|
- allowSameModule: `boolean`
|
|
@@ -84,6 +87,17 @@ npm install eslint-plugin-strict-dependencies --save-dev
|
|
|
84
87
|
"allowReferenceFrom": ["src/libs/router.ts"],
|
|
85
88
|
"allowSameModule": false
|
|
86
89
|
},
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* example:
|
|
93
|
+
* Disallow to import Suspense from react. it should always be imported using `libs/react.ts`.
|
|
94
|
+
*/
|
|
95
|
+
{
|
|
96
|
+
"module": "react",
|
|
97
|
+
"targetMembers": ["Suspense"],
|
|
98
|
+
"allowReferenceFrom": ["src/libs/react.ts"],
|
|
99
|
+
"allowSameModule": false
|
|
100
|
+
},
|
|
87
101
|
],
|
|
88
102
|
// options
|
|
89
103
|
// {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-strict-dependencies",
|
|
3
3
|
"description": "ESlint plugin to define custom module dependency rules.",
|
|
4
|
-
"version": "1.1
|
|
4
|
+
"version": "1.2.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/knowledge-work/eslint-plugin-strict-dependencies.git"
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"index.js"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"is-glob": "
|
|
29
|
-
"micromatch": "
|
|
30
|
-
"normalize-path": "
|
|
31
|
-
"require-strip-json-comments": "
|
|
28
|
+
"is-glob": "4.0.3",
|
|
29
|
+
"micromatch": "4.0.5",
|
|
30
|
+
"normalize-path": "3.0.0",
|
|
31
|
+
"require-strip-json-comments": "2.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"jest": "
|
|
34
|
+
"jest": "29.6.2"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"test": "jest --coverage",
|
|
@@ -68,19 +68,42 @@ module.exports = {
|
|
|
68
68
|
const relativeFilePath = normalize(path.relative(process.cwd(), fileFullPath))
|
|
69
69
|
const importPath = resolveImportPath(node.source.value, resolveRelativeImport ? relativeFilePath : null, pathIndexMap)
|
|
70
70
|
|
|
71
|
+
// specにはImportDefaultSpecifier/ImportNamespaceSpecifier/ImportSpecifierがあり、ImportSpecifierの場合はimportedが存在する
|
|
72
|
+
const importedModules = node.specifiers.filter(spec => 'imported' in spec).map(spec => spec.imported.name)
|
|
73
|
+
|
|
71
74
|
dependencies
|
|
72
|
-
.filter((dependency) => isMatch(importPath, dependency.module))
|
|
73
75
|
.forEach((dependency) => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
// そもそもmoduleがimportPathと一致していない場合は必ず報告しない
|
|
77
|
+
if (!isMatch(importPath, dependency.module)) return;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 1. 参照元チェックをしてAllowであればそこで処理を終了する
|
|
81
|
+
* 2. targetMembersが指定されていれば、targetMembersと実際にimportしているモジュールを比較して含まれていればエラーレポートして処理を終了する
|
|
82
|
+
* 3. targetMembersが指定されていない場合は、エラー扱いなのでエラーレポートして処理を終了する
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
const isAllowedByPath =
|
|
86
|
+
// 参照元が許可されている
|
|
87
|
+
dependency.allowReferenceFrom.some((allowPath) =>
|
|
88
|
+
isMatch(relativeFilePath, allowPath),
|
|
89
|
+
) || // または同一モジュール間の参照が許可されている場合
|
|
90
|
+
(dependency.allowSameModule && isMatch(relativeFilePath, dependency.module))
|
|
80
91
|
|
|
81
|
-
if (
|
|
82
|
-
|
|
92
|
+
if (isAllowedByPath) return
|
|
93
|
+
|
|
94
|
+
// importedされた値・型名もLintのターゲットに入っている場合の検出処理
|
|
95
|
+
function getCommonElements(arrA, arrB) {
|
|
96
|
+
return arrA.filter(element => arrB.includes(element));
|
|
97
|
+
}
|
|
98
|
+
if (dependency.targetMembers && Array.isArray(dependency.targetMembers)) {
|
|
99
|
+
const commonImportedList = getCommonElements(dependency.targetMembers, importedModules)
|
|
100
|
+
if (commonImportedList.length > 0) {
|
|
101
|
+
context.report(node, `import specifier '${commonImportedList.join(', ')}' is not allowed from ${relativeFilePath}.`)
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
83
104
|
}
|
|
105
|
+
|
|
106
|
+
context.report(node, `import '${importPath}' is not allowed from ${relativeFilePath}.`)
|
|
84
107
|
})
|
|
85
108
|
}
|
|
86
109
|
|