Skip to content

Commit 75c637f

Browse files
committed
Merge branch 'master' into renovate/lock-file-maintenance
2 parents 75c388c + 95a2fc7 commit 75c637f

File tree

8 files changed

+405
-87
lines changed

8 files changed

+405
-87
lines changed

CHANGELOG.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
## [1.4.1](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.4.0...v1.4.1) (2020-06-18)
2+
3+
4+
### Bug Fixes
5+
6+
* optimization ([afc79e6](https://github.com/dword-design/eslint-plugin-import-alias/commit/afc79e60d092d0522abc45efdfdc65ddefdc0b15))
7+
8+
# [1.4.0](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.3.0...v1.4.0) (2020-06-18)
9+
10+
11+
### Features
12+
13+
* add resolvePath support ([28eeb0c](https://github.com/dword-design/eslint-plugin-import-alias/commit/28eeb0ccc5517f3ee915bc814e454570eb6dfc64))
14+
15+
# [1.3.0](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.2.0...v1.3.0) (2020-06-18)
16+
17+
18+
### Features
19+
20+
* use babel plugin to resolve options ([4d7c247](https://github.com/dword-design/eslint-plugin-import-alias/commit/4d7c24728a96da68045096a3109c00737d62b11a))
21+
22+
# [1.2.0](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.1.3...v1.2.0) (2020-06-16)
23+
24+
25+
### Features
26+
27+
* add packagejson and babelrc support ([dab35ad](https://github.com/dword-design/eslint-plugin-import-alias/commit/dab35ad9a555f69a77ebf329e0ffd3ea64eac5a9))
28+
29+
## [1.1.3](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.1.2...v1.1.3) (2020-06-15)
30+
31+
32+
### Bug Fixes
33+
34+
* subfolder fix ([fa390ef](https://github.com/dword-design/eslint-plugin-import-alias/commit/fa390ef8bd234806b4deeac210dde3e2760f6f50))
35+
36+
## [1.1.2](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.1.1...v1.1.2) (2020-06-15)
37+
38+
39+
### Bug Fixes
40+
41+
* scoped import support ([d6db8fc](https://github.com/dword-design/eslint-plugin-import-alias/commit/d6db8fc8042e891c22b41fde5599ce47bca664b2))
42+
43+
## [1.1.1](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.1.0...v1.1.1) (2020-06-15)
44+
45+
46+
### Bug Fixes
47+
48+
* fix name ([cd41c66](https://github.com/dword-design/eslint-plugin-import-alias/commit/cd41c66b05e01c638c79912bfed5e14d25375c8f))
49+
50+
# [1.1.0](https://github.com/dword-design/eslint-plugin-import-alias/compare/v1.0.0...v1.1.0) (2020-06-15)
51+
52+
53+
### Bug Fixes
54+
55+
* fi ([f13e15f](https://github.com/dword-design/eslint-plugin-import-alias/commit/f13e15fc489e7aaba12909245b884d997670d96d))
56+
* fix for windows ([4458135](https://github.com/dword-design/eslint-plugin-import-alias/commit/44581350b85c8eed49903122564e3ede992a8c17))
57+
58+
59+
### Features
60+
61+
* init ([5c756ac](https://github.com/dword-design/eslint-plugin-import-alias/commit/5c756acacbb534fc95d861069033268c1fae55e7))
62+
63+
# 1.0.0 (2020-06-15)
64+
65+
66+
### Bug Fixes
67+
68+
* **config:** Update changed files ([3a4efb6](https://github.com/dword-design/eslint-plugin-import-alias/commit/3a4efb6167ab523aeee58dff5a9ecafdec642e13))
69+
70+
71+
### Features
72+
73+
* init ([e45df74](https://github.com/dword-design/eslint-plugin-import-alias/commit/e45df74c5eea6a8af3c69181d4f9d7789d1d7f09))

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<!-- TITLE/ -->
2-
# eslint-plugin-import-alias
2+
# @dword-design/eslint-plugin-import-alias
33
<!-- /TITLE -->
44

55
<!-- BADGES/ -->
6-
[![NPM version](https://img.shields.io/npm/v/eslint-plugin-import-alias.svg)](https://npmjs.org/package/eslint-plugin-import-alias)
6+
[![NPM version](https://img.shields.io/npm/v/@dword-design/eslint-plugin-import-alias.svg)](https://npmjs.org/package/@dword-design/eslint-plugin-import-alias)
77
![Linux macOS Windows compatible](https://img.shields.io/badge/os-linux%20%7C%C2%A0macos%20%7C%C2%A0windows-blue)
88
[![Build status](https://img.shields.io/github/workflow/status/dword-design/eslint-plugin-import-alias/build)](https://github.com/dword-design/eslint-plugin-import-alias/actions)
99
[![Coverage status](https://img.shields.io/coveralls/dword-design/eslint-plugin-import-alias)](https://coveralls.io/github/dword-design/eslint-plugin-import-alias)
@@ -22,10 +22,10 @@
2222

2323
```bash
2424
# NPM
25-
$ npm install eslint-plugin-import-alias
25+
$ npm install @dword-design/eslint-plugin-import-alias
2626

2727
# Yarn
28-
$ yarn add eslint-plugin-import-alias
28+
$ yarn add @dword-design/eslint-plugin-import-alias
2929
```
3030
<!-- /INSTALL -->
3131

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@dword-design/eslint-plugin-import-alias",
3-
"version": "1.0.0",
3+
"version": "1.4.1",
44
"description": "",
55
"repository": "dword-design/eslint-plugin-import-alias",
66
"license": "MIT",
@@ -18,12 +18,14 @@
1818
"test": "base test"
1919
},
2020
"dependencies": {
21+
"@babel/core": "^7.10.2",
2122
"@dword-design/functions": "^1.1.2",
2223
"babel-plugin-module-resolver": "^4.0.0"
2324
},
2425
"devDependencies": {
2526
"@dword-design/base": "^6.15.6",
2627
"eslint": "^7.2.0",
28+
"get-package-name": "^1.1.0",
2729
"output-files": "^1.1.16",
2830
"with-local-tmp-dir": "^2.2.10"
2931
},

src/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import preferAlias from './rules/prefer-alias'
22

33
export default {
4+
configs: {
5+
recommended: {
6+
plugins: ['@dword-design/import-alias'],
7+
rules: {
8+
'@dword-design/import-alias/prefer-alias': 'error',
9+
},
10+
},
11+
},
412
rules: {
513
'prefer-alias': preferAlias,
614
},

src/index.spec.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import {
2+
endent,
3+
flatten,
4+
join,
5+
map,
6+
mapValues,
7+
pick,
8+
replace,
9+
} from '@dword-design/functions'
10+
import { ESLint } from 'eslint'
11+
import getPackageName from 'get-package-name'
12+
import outputFiles from 'output-files'
13+
import P from 'path'
14+
import withLocalTmpDir from 'with-local-tmp-dir'
15+
16+
const runTest = config => () => {
17+
const filename = config.filename || 'index.js'
18+
const output = config.output || config.code
19+
const messages = config.messages || []
20+
return withLocalTmpDir(async () => {
21+
await outputFiles({
22+
'node_modules/@dword-design/eslint-plugin-import-alias': `module.exports = require('${
23+
require.resolve('.') |> replace(/\\/g, '/')
24+
}')`,
25+
...config.files,
26+
})
27+
const lintingConfig = {
28+
useEslintrc: false,
29+
overrideConfig: {
30+
parserOptions: {
31+
sourceType: 'module',
32+
ecmaVersion: 2015,
33+
},
34+
extends: ['plugin:@dword-design/import-alias/recommended'],
35+
},
36+
}
37+
const eslintToLint = new ESLint(lintingConfig)
38+
const eslintToFix = new ESLint({ ...lintingConfig, fix: true })
39+
const lintedMessages =
40+
eslintToLint.lintText(config.code, {
41+
filePath: filename,
42+
})
43+
|> await
44+
|> map('messages')
45+
|> flatten
46+
|> map(pick(['ruleId', 'message']))
47+
expect(lintedMessages).toEqual(messages)
48+
const lintedOutput =
49+
eslintToFix.lintText(config.code, { filePath: filename })
50+
|> await
51+
|> map('output')
52+
|> join('\n')
53+
expect(lintedOutput).toEqual(output)
54+
})
55+
}
56+
57+
export default {
58+
'prefer-alias': {
59+
files: {
60+
'.babelrc.json': JSON.stringify({
61+
plugins: [
62+
[
63+
getPackageName(require.resolve('babel-plugin-module-resolver')),
64+
{ alias: { '@': '.' } },
65+
],
66+
],
67+
}),
68+
},
69+
code: endent`
70+
import foo from '../foo/bar'
71+
`,
72+
filename: P.join('sub', 'index.js'),
73+
messages: [
74+
{
75+
message:
76+
"Unexpected parent import '../foo/bar'. Use '@/foo/bar' instead",
77+
ruleId: '@dword-design/import-alias/prefer-alias',
78+
},
79+
],
80+
output: "import foo from '@/foo/bar'",
81+
},
82+
} |> mapValues(runTest)

src/rules/prefer-alias.js

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,87 @@
1-
import {
2-
findKey,
3-
keys,
4-
replace,
5-
some,
6-
startsWith,
7-
} from '@dword-design/functions'
8-
import { resolvePath } from 'babel-plugin-module-resolver'
1+
import { OptionManager } from '@babel/core'
2+
import { find, keys, replace, some, startsWith } from '@dword-design/functions'
3+
import { resolvePath as defaultResolvePath } from 'babel-plugin-module-resolver'
94
import P from 'path'
105

116
const isParentImport = path => /^(\.\/)?\.\.\//.test(path)
7+
const findMatchingAlias = (sourcePath, currentFile, options) => {
8+
const resolvePath = options.resolvePath || defaultResolvePath
9+
const absoluteSourcePath = P.resolve(P.dirname(currentFile), sourcePath)
10+
for (const aliasName of options.alias |> keys) {
11+
const path = P.resolve(
12+
P.dirname(currentFile),
13+
resolvePath(`${aliasName}/`, currentFile, options)
14+
)
15+
if (absoluteSourcePath |> startsWith(path)) {
16+
return { name: aliasName, path }
17+
}
18+
}
19+
return undefined
20+
}
1221

1322
export default {
1423
meta: {
1524
type: 'suggestion',
1625
fixable: true,
17-
schema: [
18-
{
19-
type: 'object',
20-
properties: {
21-
aliases: { type: 'object', default: { '@': '.' } },
22-
},
23-
required: ['aliases'],
24-
},
25-
],
2626
},
2727
create: context => {
28-
const aliases = context.options[0]?.aliases || { '@': '.' }
29-
const path = context.getFilename()
28+
const currentFile = context.getFilename()
29+
const folder = P.dirname(currentFile)
3030
// can't check a non-file
31-
if (path === '<text>') return {}
31+
if (currentFile === '<text>') return {}
32+
const manager = new OptionManager()
33+
const babelConfig = manager.init({
34+
babelrc: true,
35+
root: folder,
36+
filename: currentFile,
37+
})
38+
const plugin = babelConfig.plugins |> find({ key: 'module-resolver' })
39+
const options = plugin.options
40+
const resolvePath = options.resolvePath || defaultResolvePath
3241
return {
3342
ImportDeclaration: node => {
34-
const importPath = node.source.value
43+
const sourcePath = node.source.value
3544
const hasAlias =
36-
aliases |> keys |> some(alias => importPath |> startsWith(alias))
37-
const resolvedImport = resolvePath(importPath, path, {
38-
alias: aliases,
39-
})
45+
options.alias
46+
|> keys
47+
|> some(alias => sourcePath |> startsWith(`${alias}/`))
4048
// relative parent
41-
if (importPath |> isParentImport) {
42-
const folder = P.basename(path)
43-
const resolvedImportPath = P.resolve(folder, importPath)
44-
const matchingAlias =
45-
aliases
46-
|> findKey(
47-
aliasPath =>
48-
resolvedImportPath |> startsWith(P.resolve(aliasPath))
49-
)
49+
if (sourcePath |> isParentImport) {
50+
const matchingAlias = findMatchingAlias(
51+
sourcePath,
52+
currentFile,
53+
options
54+
)
5055
if (!matchingAlias) {
5156
return context.report({
5257
node,
53-
message: `Unexpected parent import '${importPath}'. No matching alias found to fix the issue`,
58+
message: `Unexpected parent import '${sourcePath}'. No matching alias found to fix the issue`,
5459
})
5560
}
56-
const rewrittenImport = `${matchingAlias}/${
57-
P.relative(P.resolve(aliases[matchingAlias]), resolvedImportPath)
61+
const absoluteImportPath = P.resolve(folder, sourcePath)
62+
const rewrittenImport = `${matchingAlias.name}/${
63+
P.relative(matchingAlias.path, absoluteImportPath)
5864
|> replace(/\\/g, '/')
5965
}`
6066
return context.report({
6167
node,
62-
message: `Unexpected parent import '${importPath}'. Use '${rewrittenImport}' instead`,
68+
message: `Unexpected parent import '${sourcePath}'. Use '${rewrittenImport}' instead`,
6369
fix: fixer =>
6470
fixer.replaceTextRange(
6571
[node.source.range[0] + 1, node.source.range[1] - 1],
6672
rewrittenImport
6773
),
6874
})
6975
}
70-
if (!(resolvedImport |> isParentImport) && hasAlias) {
76+
const importWithoutAlias = resolvePath(sourcePath, currentFile, options)
77+
if (!(importWithoutAlias |> isParentImport) && hasAlias) {
7178
return context.report({
7279
node,
73-
message: `Unexpected subpath import via alias '${importPath}'. Use '${resolvedImport}' instead`,
80+
message: `Unexpected subpath import via alias '${sourcePath}'. Use '${importWithoutAlias}' instead`,
7481
fix: fixer =>
7582
fixer.replaceTextRange(
7683
[node.source.range[0] + 1, node.source.range[1] - 1],
77-
resolvedImport
84+
importWithoutAlias
7885
),
7986
})
8087
}

0 commit comments

Comments
 (0)