eslint-plugin-smarthr 0.1.0 → 0.1.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/CHANGELOG.md CHANGED
@@ -2,28 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ## [0.1.0](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.0.1...v0.1.0) (2022-02-09)
6
-
7
-
8
- ### ⚠ BREAKING CHANGES
9
-
10
- * update prohibit-imoprt option
5
+ ### [0.1.1](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.1.0...v0.1.1) (2022-03-08)
11
6
 
12
- * chore: require-importの対象ファイル指定方法をoptionの第一階層のkeyにする
13
7
 
14
- * chore: update README.md
15
-
16
- * chore: require-importのdefaultReportMessageを修正
17
-
18
- * chore: update yarn.lock
8
+ ### Features
19
9
 
20
- * chore: fix test
10
+ * add require-barrel-import rule ([#13](https://github.com/kufu/eslint-plugin-smarthr/issues/13)) ([79ee88d](https://github.com/kufu/eslint-plugin-smarthr/commit/79ee88d355e01bb8344dc95bd65157e2fbcf916e))
21
11
 
22
- * chore: add test
12
+ ## [0.1.0](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.0.1...v0.1.0) (2022-02-09)
23
13
 
24
- * chore: refactoring prohibit-import
25
14
 
26
- * chore: add test
15
+ ### BREAKING CHANGES
27
16
 
28
17
  * BREAKING CHANGE: add require-import & update prohibit-import (#12) ([e6c5c44](https://github.com/kufu/eslint-plugin-smarthr/commit/e6c5c445a21620d4b796ded00a685e5da367c7bb)), closes [#12](https://github.com/kufu/eslint-plugin-smarthr/issues/12)
29
18
 
package/README.md CHANGED
@@ -359,6 +359,46 @@ import { SecondaryButton } from 'smarthr-ui'
359
359
  import useTitle from '.hooks/useTitle'
360
360
  ```
361
361
 
362
+ ## smarthr/require-barrel-import
363
+
364
+ - tsconfig.json の compilerOptions.pathsに '@/*' としてroot path を指定する必要があります
365
+ - importした対象が本来exportされているべきであるbarrel(index.tsなど)が有る場合、import pathの変更を促します
366
+ - 例: Page/parts/Menu/Item の import は Page/parts/Menu から行わせたい
367
+ - ディレクトリ内のindexファイルを捜査し、対象を決定します
368
+
369
+ ### rules
370
+
371
+ ```js
372
+ {
373
+ rules: {
374
+ 'smarthr/require-barrel-import': 'error',
375
+ },
376
+ }
377
+ ```
378
+
379
+ ### ❌ Incorrect
380
+
381
+ ```js
382
+ // client/src/views/Page/parts/Menu/index.ts
383
+ export { Menu } from './Menu'
384
+ export { Item } from './Item'
385
+
386
+ // client/src/App.tsx
387
+ import { Item } from './Page/parts/Menu/Item'
388
+ ```
389
+
390
+ ### ✅ Correct
391
+
392
+
393
+ ```js
394
+ // client/src/views/Page/parts/Menu/index.ts
395
+ export { Menu } from './Menu'
396
+ export { Item } from './Item'
397
+
398
+ // client/src/App.tsx
399
+ import { Item } from './Page/parts/Menu'
400
+ ```
401
+
362
402
 
363
403
  ## smarthr/redundant-name
364
404
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-smarthr",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "author": "SmartHR",
5
5
  "license": "MIT",
6
6
  "description": "A sharable ESLint plugin for SmartHR",
@@ -0,0 +1,125 @@
1
+ const path = require('path')
2
+ const fs = require('fs')
3
+ const { replacePaths, rootPath } = require('../libs/common')
4
+ const calculateAbsoluteImportPath = (source) => {
5
+ if (source[0] === '/') {
6
+ return source
7
+ }
8
+
9
+ return Object.entries(replacePaths).reduce((prev, [key, values]) => {
10
+ if (source === prev) {
11
+ return values.reduce((p, v) => {
12
+ if (prev === p) {
13
+ const regexp = new RegExp(`^${key}(.+)$`)
14
+
15
+ if (prev.match(regexp)) {
16
+ return p.replace(regexp, `${path.resolve(`${process.cwd()}/${v}`)}/$1`)
17
+ }
18
+ }
19
+
20
+ return p
21
+ }, prev)
22
+ }
23
+
24
+ return prev
25
+ }, source)
26
+ }
27
+ const calculateReplacedImportPath = (source) => {
28
+ return Object.entries(replacePaths).reduce((prev, [key, values]) => {
29
+ if (source === prev) {
30
+ return values.reduce((p, v) => {
31
+ if (prev === p) {
32
+ const regexp = new RegExp(`^${path.resolve(`${process.cwd()}/${v}`)}(.+)$`)
33
+
34
+ if (prev.match(regexp)) {
35
+ return p.replace(regexp, `${key}/$1`).replace(/(\/)+/g, '/')
36
+ }
37
+ }
38
+
39
+ return p
40
+ }, prev)
41
+ }
42
+
43
+ return prev
44
+ }, source)
45
+ }
46
+
47
+ module.exports = {
48
+ meta: {
49
+ type: 'suggestion',
50
+ messages: {
51
+ 'require-barrel-import': '{{ message }}',
52
+ },
53
+ schema: [],
54
+ },
55
+ create(context) {
56
+ const filename = context.getFilename()
57
+
58
+ // HINT: indexファイルがある == barrelであるとする
59
+ if (filename.match(/\/index\.(js|ts)x?$/)) {
60
+ return {}
61
+ }
62
+
63
+ const dir = (() => {
64
+ const d = filename.split('/')
65
+ d.pop()
66
+
67
+ return d.join('/')
68
+ })()
69
+
70
+ return {
71
+ ImportDeclaration: (node) => {
72
+ let sourceValue = node.source.value
73
+
74
+ if (sourceValue[0] === '.') {
75
+ sourceValue = path.resolve(`${dir}/${sourceValue}`)
76
+ }
77
+
78
+ sourceValue = calculateAbsoluteImportPath(sourceValue)
79
+
80
+ if (sourceValue[0] !== '/') {
81
+ return
82
+ }
83
+
84
+ const sources = sourceValue.split('/')
85
+ let joinedSources = sourceValue
86
+ let ext = undefined
87
+
88
+ while (sources.length > 0) {
89
+ // HINT: 以下の場合は即終了
90
+ // - import元以下のimportだった場合
91
+ // - rootまで捜索した場合
92
+ if (dir === joinedSources || dir === rootPath) {
93
+ return
94
+ }
95
+
96
+ ext = ['ts', 'tsx', 'js', 'jsx'].find((e) => fs.existsSync(`${sources.join('/')}/index.${e}`))
97
+
98
+ if (ext) {
99
+ break
100
+ }
101
+
102
+ sources.pop()
103
+ joinedSources = sources.join('/')
104
+ }
105
+
106
+ if (
107
+ joinedSources &&
108
+ sourceValue !== joinedSources &&
109
+ !dir.match(new RegExp(`^${joinedSources}/`))
110
+ ) {
111
+ const replacedSources = calculateReplacedImportPath(joinedSources)
112
+
113
+ context.report({
114
+ node,
115
+ messageId: 'require-barrel-import',
116
+ data: {
117
+ message: `${replacedSources}からimportするか、${replacedSources}/index.${ext}を削除してください`,
118
+ },
119
+ });
120
+ }
121
+ },
122
+ }
123
+ },
124
+ }
125
+ module.exports.schema = []