Skip to content

Commit 3085a2f

Browse files
committed
Add 'no-relative-imports' rule
1 parent 9e3b256 commit 3085a2f

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
module.exports.rules = {
44
'no-cross-imports': require('./rules/no-cross-imports'),
5+
'no-relative-imports': require('./rules/no-relative-imports'),
56
};

lib/rules/no-relative-imports.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
3+
const getPackages = require('get-monorepo-packages');
4+
const { relative, resolve, sep, isAbsolute } = require('path');
5+
6+
module.exports.meta = {
7+
type: 'problem',
8+
docs: {
9+
url:
10+
'https://github.com/joshuajaco/eslint-plugin-workspaces/docs/rules/no-relative-imports.md',
11+
},
12+
};
13+
14+
module.exports.schema = [];
15+
16+
const isSubPath = (parent, path) => {
17+
const relativePath = relative(parent, path);
18+
return relativePath.split(sep)[0] !== '..' && !isAbsolute(relativePath);
19+
};
20+
21+
const isRelativeImport = (packages, context, node, value) => {
22+
packages.forEach(location => {
23+
if (
24+
!isSubPath(location, context.getFilename()) &&
25+
isSubPath(location, resolve(context.getFilename(), value))
26+
)
27+
context.report({
28+
node,
29+
message: 'Relative imports of other packages are not allowed',
30+
});
31+
});
32+
};
33+
34+
module.exports.create = context => {
35+
const packages = getPackages(process.cwd()).map(({ location }) => location);
36+
37+
return {
38+
ImportDeclaration: node => {
39+
if (node.source.type === 'Literal') {
40+
isRelativeImport(packages, context, node, node.source.value);
41+
}
42+
},
43+
ExpressionStatement: node => {
44+
if (
45+
node.expression.type === 'CallExpression' &&
46+
node.expression.arguments[0].type === 'Literal' &&
47+
(node.expression.callee.type === 'Import' ||
48+
(node.expression.callee.type === 'Identifier' &&
49+
node.expression.callee.name === 'require'))
50+
) {
51+
const { value } = node.expression.arguments[0];
52+
isRelativeImport(packages, context, node, value);
53+
}
54+
},
55+
};
56+
};

tests/rules/no-relative-imports.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'use strict';
2+
3+
const ruleTester = require('../ruleTester');
4+
const rule = require('../../lib/rules/no-relative-imports');
5+
6+
ruleTester.run('no-relative-imports', rule, {
7+
valid: [
8+
"import workspace from '@test/workspace';",
9+
"require('@test/workspace');",
10+
"import('@test/workspace');",
11+
"import '@test/workspace';",
12+
"import '../some/relative/path';",
13+
{
14+
filename: '/test/workspace',
15+
code: "import '../workspace';",
16+
},
17+
{
18+
filename: '/test/workspace',
19+
code: "import './some/path';",
20+
},
21+
{
22+
filename: '/test/workspace/some/path',
23+
code: "import '../another/path';",
24+
},
25+
],
26+
27+
invalid: [
28+
{
29+
code: "import workspace from '../../test/workspace';",
30+
filename: '/some/path',
31+
errors: [
32+
{
33+
message: 'Relative imports of other packages are not allowed',
34+
},
35+
],
36+
},
37+
{
38+
code: "require('../../test/workspace');",
39+
filename: '/some/path',
40+
errors: [
41+
{
42+
message: 'Relative imports of other packages are not allowed',
43+
},
44+
],
45+
},
46+
{
47+
code: "import('../../test/workspace');",
48+
filename: '/some/path',
49+
errors: [
50+
{
51+
message: 'Relative imports of other packages are not allowed',
52+
},
53+
],
54+
},
55+
{
56+
code: "import '../../test/workspace';",
57+
filename: '/some/path',
58+
errors: [
59+
{
60+
message: 'Relative imports of other packages are not allowed',
61+
},
62+
],
63+
},
64+
{
65+
code: "import workspace from '../another-workspace';",
66+
filename: '/test/workspace',
67+
errors: [
68+
{
69+
message: 'Relative imports of other packages are not allowed',
70+
},
71+
],
72+
},
73+
{
74+
code: "import workspace from '../another-workspace/testing';",
75+
filename: '/test/workspace',
76+
errors: [
77+
{
78+
message: 'Relative imports of other packages are not allowed',
79+
},
80+
],
81+
},
82+
],
83+
});

0 commit comments

Comments
 (0)