eslint-plugin-strict-dependencies 0.0.1 → 1.0.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 CHANGED
@@ -1,6 +1,8 @@
1
1
  # eslint-plugin-strict-dependencies
2
2
 
3
- NOTE: eslint-plugin-strict-dependencies uses tsconfig, tsconfig.json must be present.
3
+ ESlint plugin to define custom module dependency rules.
4
+
5
+ NOTE: `eslint-plugin-strict-dependencies` uses tsconfig, tsconfig.json must be present.
4
6
 
5
7
  ## Installation
6
8
 
@@ -16,7 +18,18 @@ npm install eslint-plugin-strict-dependencies --save-dev
16
18
  - allowReferenceFrom: `string[]` (Glob or Forward matching string)
17
19
  - Paths of files where target module imports are allowed.
18
20
  - allowSameModule: `boolean`
19
- - Whether or not the target module itself can import on the target module
21
+ - Whether it can be imported by other files in the same directory
22
+
23
+ ### Options
24
+
25
+ - resolveRelativeImport: `boolean[default = false]`
26
+ - Whether to resolve relative import as in the following example
27
+ - `src/components/aaa.ts`
28
+ ```typescript
29
+ import bbb from './bbb';
30
+ ```
31
+ - `resolveRelativeImport = false`: Resolve as `./bbb` (excluded from lint target)
32
+ - `resolveRelativeImport = true`: Resolve as `src/components/bbb`: (included from lint target)
20
33
 
21
34
  ## Usage
22
35
 
@@ -31,8 +44,8 @@ npm install eslint-plugin-strict-dependencies --save-dev
31
44
  "error",
32
45
  [
33
46
  /**
34
- * example:
35
- * Components only allow dependencies in the following directions
47
+ * Example:
48
+ * Limit the dependencies in the following directions
36
49
  * pages -> components/page -> components/ui
37
50
  */
38
51
  {
@@ -50,7 +63,7 @@ npm install eslint-plugin-strict-dependencies --save-dev
50
63
 
51
64
  /**
52
65
  * example:
53
- * Don't import next/router directly, always import it through libs/router.
66
+ * Disallow to import `next/router` directly. it should always be imported using `libs/router.ts`.
54
67
  */
55
68
  {
56
69
  "module": "next/router",
@@ -58,7 +71,11 @@ npm install eslint-plugin-strict-dependencies --save-dev
58
71
  "allowSameModule": false
59
72
  },
60
73
  ],
61
- ],
74
+ // options
75
+ // {
76
+ // "resolveRelativeImport": true
77
+ // }
78
+ ]
62
79
  }
63
80
 
64
81
  ```
@@ -66,4 +83,4 @@ npm install eslint-plugin-strict-dependencies --save-dev
66
83
 
67
84
  ## License
68
85
 
69
- MIT
86
+ MIT
package/package.json CHANGED
@@ -1,15 +1,38 @@
1
1
  {
2
2
  "name": "eslint-plugin-strict-dependencies",
3
- "description": "Restrict imports between files according to the configured dependency rules.",
4
- "version": "0.0.1",
3
+ "description": "ESlint plugin to define custom module dependency rules.",
4
+ "version": "1.0.1",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/knowledge-work/eslint-plugin-strict-dependencies.git"
8
8
  },
9
+ "keywords": [
10
+ "eslint",
11
+ "eslintplugin",
12
+ "lint",
13
+ "rule",
14
+ "check",
15
+ "import",
16
+ "module",
17
+ "directory",
18
+ "strict",
19
+ "dependencies"
20
+ ],
9
21
  "license": "MIT",
10
22
  "main": "index.js",
11
23
  "files": [
12
24
  "strict-dependencies",
13
25
  "index.js"
14
- ]
26
+ ],
27
+ "dependencies": {
28
+ "is-glob": "^4.0.3",
29
+ "micromatch": "^4.0.4",
30
+ "require-strip-json-comments": "^2.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "jest": "^27.2.4"
34
+ },
35
+ "scripts": {
36
+ "test": "jest --coverage"
37
+ }
15
38
  }
@@ -43,15 +43,25 @@ module.exports = {
43
43
  },
44
44
  ],
45
45
  },
46
+ {
47
+ type: 'object',
48
+ properties: {
49
+ resolveRelativeImport: {
50
+ type: 'boolean',
51
+ }
52
+ },
53
+ },
46
54
  ],
47
55
  },
48
56
  create: (context) => {
49
57
  const dependencies = context.options[0]
58
+ const options = context.options.length > 1 ? context.options[1] : {}
59
+ const resolveRelativeImport = options.resolveRelativeImport
50
60
 
51
61
  function checkImport(node) {
52
62
  const fileFullPath = context.getFilename()
53
63
  const relativeFilePath = path.relative(process.cwd(), fileFullPath)
54
- const importPath = resolveImportPath(node.source.value)
64
+ const importPath = resolveImportPath(node.source.value, resolveRelativeImport ? relativeFilePath : null)
55
65
 
56
66
  dependencies
57
67
  .filter((dependency) => isMatch(importPath, dependency.module))
@@ -64,7 +74,7 @@ module.exports = {
64
74
  (dependency.allowSameModule && isMatch(relativeFilePath, dependency.module))
65
75
 
66
76
  if (!isAllowed) {
67
- context.report(node, `import '${importPath}' is not allowed from ${dependency.module}.`)
77
+ context.report(node, `import '${importPath}' is not allowed from ${relativeFilePath}.`)
68
78
  }
69
79
  })
70
80
  }
@@ -1,31 +1,35 @@
1
1
  /* eslint-disable */
2
2
 
3
- const fs = require('fs')
4
3
  const path = require('path')
4
+ const parseJSON = require('require-strip-json-comments')
5
5
 
6
6
  /**
7
7
  * import文のrootからのパスを求める
8
8
  */
9
- module.exports = (importPath) => {
9
+ module.exports = (importPath, relativeFilePath) => {
10
10
  // { [importAlias: string]: OriginalPath }
11
11
  const importAliasMap = {}
12
12
 
13
13
  // Load tsconfig option
14
14
  // MEMO: tscとか使って簡単に読める方法がありそう
15
15
  try {
16
- const tsConfigFile = fs.readFileSync(path.join(process.cwd(), '/tsconfig.json'), 'utf-8')
16
+ const tsConfigFilePath = path.join(process.cwd(), '/tsconfig.json')
17
17
  // Exists ts config
18
- const tsConfig = JSON.parse(tsConfigFile)
18
+ const tsConfig = parseJSON(tsConfigFilePath)
19
19
  if (tsConfig.compilerOptions && tsConfig.compilerOptions.paths) {
20
20
  Object.keys(tsConfig.compilerOptions.paths).forEach((key) => {
21
21
  // FIXME: このlint ruleではimport先が存在するかチェックしておらず、複数のパスから正しい方を選択できないため[0]固定
22
- importAliasMap[key] = tsConfig.compilerOptions.paths[key][0]
22
+ importAliasMap[key] = tsConfig.compilerOptions.baseUrl ? path.join(tsConfig.compilerOptions.baseUrl, tsConfig.compilerOptions.paths[key][0]) : tsConfig.compilerOptions.paths[key][0]
23
23
  })
24
24
  }
25
25
  } catch (e) {
26
26
  // DO NOTHING
27
27
  }
28
28
 
29
+ if (relativeFilePath && (importPath.startsWith('./') || importPath.startsWith('../'))) {
30
+ importPath = path.join(path.dirname(relativeFilePath), importPath)
31
+ }
32
+
29
33
  return Object.keys(importAliasMap).reduce((resolvedImportPath, key) => {
30
34
  // FIXME: use glob module instead of replace('*')
31
35
  return resolvedImportPath.replace(key.replace('*', ''), importAliasMap[key].replace('*', ''))