Skip to content

Commit b96b499

Browse files
adipasculjharb
authored andcommittedDec 13, 2022
[New] no-absolute-path: add fixer
1 parent 5a37196 commit b96b499

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1818
- [`consistent-type-specifier-style`]: add rule ([#2473], thanks [@bradzacher])
1919
- Add [`no-empty-named-blocks`] rule ([#2568], thanks [@guilhermelimak])
2020
- [`prefer-default-export`]: add "target" option ([#2602], thanks [@azyzz228])
21+
- [`no-absolute-path`]: add fixer ([#2613], thanks [@adipascu])
2122

2223
### Fixed
2324
- [`order`]: move nested imports closer to main import entry ([#2396], thanks [@pri1311])
@@ -1026,6 +1027,7 @@ for info on changes for earlier releases.
10261027

10271028
[`memo-parser`]: ./memo-parser/README.md
10281029

1030+
[#2613]: https://github.com/import-js/eslint-plugin-import/pull/2613
10291031
[#2608]: https://github.com/import-js/eslint-plugin-import/pull/2608
10301032
[#2605]: https://github.com/import-js/eslint-plugin-import/pull/2605
10311033
[#2602]: https://github.com/import-js/eslint-plugin-import/pull/2602

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
5656
| [default](docs/rules/default.md) | Ensure a default export is present, given a default import. | ❗ ☑️ | | | | | |
5757
| [named](docs/rules/named.md) | Ensure named imports correspond to a named export in the remote file. | ❗ ☑️ | | ⌨️ | | | |
5858
| [namespace](docs/rules/namespace.md) | Ensure imported namespaces contain dereferenced properties as they are dereferenced. | ❗ ☑️ | | | | | |
59-
| [no-absolute-path](docs/rules/no-absolute-path.md) | Forbid import of modules using absolute paths. | | | | | | |
59+
| [no-absolute-path](docs/rules/no-absolute-path.md) | Forbid import of modules using absolute paths. | | | | 🔧 | | |
6060
| [no-cycle](docs/rules/no-cycle.md) | Forbid a module from importing a module with a dependency path back to itself. | | | | | | |
6161
| [no-dynamic-require](docs/rules/no-dynamic-require.md) | Forbid `require()` calls with expressions. | | | | | | |
6262
| [no-internal-modules](docs/rules/no-internal-modules.md) | Forbid importing the submodules of other modules. | | | | | | |

‎docs/rules/no-absolute-path.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# import/no-absolute-path
22

3+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
4+
35
<!-- end auto-generated rule header -->
46

57
Node.js allows the import of modules using an absolute path such as `/home/xyz/file.js`. That is a bad practice as it ties the code using it to your computer, and therefore makes it unusable in packages distributed on `npm` for instance.

‎src/rules/no-absolute-path.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import path from 'path';
12
import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor';
23
import { isAbsolute } from '../core/importType';
34
import docsUrl from '../docsUrl';
@@ -10,13 +11,26 @@ module.exports = {
1011
description: 'Forbid import of modules using absolute paths.',
1112
url: docsUrl('no-absolute-path'),
1213
},
14+
fixable: 'code',
1315
schema: [ makeOptionsSchema() ],
1416
},
1517

1618
create(context) {
1719
function reportIfAbsolute(source) {
1820
if (isAbsolute(source.value)) {
19-
context.report(source, 'Do not import modules using an absolute path');
21+
context.report({
22+
node: source,
23+
message: 'Do not import modules using an absolute path',
24+
fix: fixer => {
25+
const resolvedContext = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename();
26+
// node.js and web imports work with posix style paths ("/")
27+
let relativePath = path.posix.relative(path.dirname(resolvedContext), source.value);
28+
if (!relativePath.startsWith('.')) {
29+
relativePath = './' + relativePath;
30+
}
31+
return fixer.replaceText(source, JSON.stringify(relativePath));
32+
},
33+
});
2034
}
2135
}
2236

‎tests/src/rules/no-absolute-path.js

+26
Original file line numberDiff line numberDiff line change
@@ -53,48 +53,74 @@ ruleTester.run('no-absolute-path', rule, {
5353
invalid: [
5454
test({
5555
code: 'import f from "/foo"',
56+
filename: '/foo/bar/index.js',
5657
errors: [error],
58+
output: 'import f from ".."',
59+
}),
60+
test({
61+
code: 'import f from "/foo/bar/baz.js"',
62+
filename: '/foo/bar/index.js',
63+
errors: [error],
64+
output: 'import f from "./baz.js"',
5765
}),
5866
test({
5967
code: 'import f from "/foo/path"',
68+
filename: '/foo/bar/index.js',
6069
errors: [error],
70+
output: 'import f from "../path"',
6171
}),
6272
test({
6373
code: 'import f from "/some/path"',
74+
filename: '/foo/bar/index.js',
6475
errors: [error],
76+
output: 'import f from "../../some/path"',
6577
}),
6678
test({
6779
code: 'import f from "/some/path"',
80+
filename: '/foo/bar/index.js',
6881
options: [{ amd: true }],
6982
errors: [error],
83+
output: 'import f from "../../some/path"',
7084
}),
7185
test({
7286
code: 'var f = require("/foo")',
87+
filename: '/foo/bar/index.js',
7388
errors: [error],
89+
output: 'var f = require("..")',
7490
}),
7591
test({
7692
code: 'var f = require("/foo/path")',
93+
filename: '/foo/bar/index.js',
7794
errors: [error],
95+
output: 'var f = require("../path")',
7896
}),
7997
test({
8098
code: 'var f = require("/some/path")',
99+
filename: '/foo/bar/index.js',
81100
errors: [error],
101+
output: 'var f = require("../../some/path")',
82102
}),
83103
test({
84104
code: 'var f = require("/some/path")',
105+
filename: '/foo/bar/index.js',
85106
options: [{ amd: true }],
86107
errors: [error],
108+
output: 'var f = require("../../some/path")',
87109
}),
88110
// validate amd
89111
test({
90112
code: 'require(["/some/path"], function (f) { /* ... */ })',
113+
filename: '/foo/bar/index.js',
91114
options: [{ amd: true }],
92115
errors: [error],
116+
output: 'require(["../../some/path"], function (f) { /* ... */ })',
93117
}),
94118
test({
95119
code: 'define(["/some/path"], function (f) { /* ... */ })',
120+
filename: '/foo/bar/index.js',
96121
options: [{ amd: true }],
97122
errors: [error],
123+
output: 'define(["../../some/path"], function (f) { /* ... */ })',
98124
}),
99125
],
100126
});

0 commit comments

Comments
 (0)
Please sign in to comment.