Skip to content

Commit 38f3935

Browse files
committed
order: enforce imports being before require
1 parent 039a77b commit 38f3935

File tree

3 files changed

+61
-19
lines changed

3 files changed

+61
-19
lines changed

docs/rules/order.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import baz from './bar/baz';
2222
import main from './';
2323
```
2424

25-
Unassigned imports are not accounted for, as the order they are imported in may be important.
25+
Unassigned imports are ignored, as the order they are imported in may be important.
26+
27+
Statements using the ES6 `import` syntax must appear before any `require()` statements.
2628

2729

2830
## Fail
@@ -35,6 +37,11 @@ import path from 'path'; // `path` import should occur before import of `lodash`
3537

3638
var _ = require('lodash');
3739
var path = require('path'); // `path` import should occur before import of `lodash`
40+
41+
// -----
42+
43+
var path = require('path');
44+
import foo from './foo'; // `import` statements must be before `require` statement
3845
```
3946

4047

@@ -54,6 +61,12 @@ var _ = require('lodash');
5461
// Allowed as ̀`babel-register` is not assigned.
5562
require('babel-register');
5663
var path = require('path');
64+
65+
// -----
66+
67+
// Allowed as `import` must be before `require`
68+
import foo from './foo';
69+
var path = require('path');
5770
```
5871

5972
## Options

src/rules/order.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ function makeReport(context, imported) {
5959

6060
// DETECTING
6161

62-
function computeRank(context, ranks, name) {
63-
return ranks[importType(name, context)]
62+
function computeRank(context, ranks, name, type) {
63+
return ranks[importType(name, context)] +
64+
(type === 'import' ? 0 : 100)
6465
}
6566

66-
function registerNode(context, node, name, ranks, imported) {
67-
const rank = computeRank(context, ranks, name)
67+
function registerNode(context, node, name, type, ranks, imported) {
68+
const rank = computeRank(context, ranks, name, type)
6869
if (rank !== -1) {
69-
imported.push({name: name, rank: rank, node: node})
70+
imported.push({name, rank, node})
7071
}
7172
}
7273

@@ -136,15 +137,15 @@ module.exports = function importOrderRule (context) {
136137
ImportDeclaration: function handleImports(node) {
137138
if (node.specifiers.length) { // Ignoring unassigned imports
138139
const name = node.source.value
139-
registerNode(context, node, name, ranks, imported)
140+
registerNode(context, node, name, 'import', ranks, imported)
140141
}
141142
},
142143
CallExpression: function handleRequires(node) {
143144
if (level !== 0 || !isStaticRequire(node) || !isInVariableDeclarator(node.parent)) {
144145
return
145146
}
146147
const name = node.arguments[0].value
147-
registerNode(context, node, name, ranks, imported)
148+
registerNode(context, node, name, 'require', ranks, imported)
148149
},
149150
'Program:exit': function reportAndReset() {
150151
makeReport(context, imported)

tests/src/rules/order.js

+39-11
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,6 @@ ruleTester.run('order', rule, {
2929
import sibling, {foo3} from './foo';
3030
import index from './';`,
3131
}),
32-
// Default order using both require and import
33-
test({
34-
code: `
35-
var fs = require('fs');
36-
import async, {foo1} from 'async';
37-
var relParent1 = require('../foo');
38-
import relParent2, {foo2} from '../foo/bar';
39-
var relParent3 = require('../');
40-
import sibling, {foo3} from './foo';
41-
var index = require('./');`,
42-
}),
4332
// Multiple module of the same rank next to each other
4433
test({
4534
code: `
@@ -159,6 +148,18 @@ ruleTester.run('order', rule, {
159148
// missing 'builtin'
160149
]}],
161150
}),
151+
// Mixing require and import should have import up top
152+
test({
153+
code: `
154+
import async, {foo1} from 'async';
155+
import relParent2, {foo2} from '../foo/bar';
156+
import sibling, {foo3} from './foo';
157+
var fs = require('fs');
158+
var relParent1 = require('../foo');
159+
var relParent3 = require('../');
160+
var index = require('./');
161+
`,
162+
}),
162163
],
163164
invalid: [
164165
// builtin before external module (require)
@@ -385,5 +386,32 @@ ruleTester.run('order', rule, {
385386
message: 'Incorrect configuration of the rule: `parent` is duplicated',
386387
}],
387388
}),
389+
// Mixing require and import should have import up top
390+
test({
391+
code: `
392+
import async, {foo1} from 'async';
393+
import relParent2, {foo2} from '../foo/bar';
394+
var fs = require('fs');
395+
var relParent1 = require('../foo');
396+
var relParent3 = require('../');
397+
import sibling, {foo3} from './foo';
398+
var index = require('./');
399+
`,
400+
errors: [{
401+
ruleId: 'order',
402+
message: '`./foo` import should occur before import of `fs`',
403+
}],
404+
}),
405+
test({
406+
code: `
407+
var fs = require('fs');
408+
import async, {foo1} from 'async';
409+
import relParent2, {foo2} from '../foo/bar';
410+
`,
411+
errors: [{
412+
ruleId: 'order',
413+
message: '`fs` import should occur after import of `../foo/bar`',
414+
}],
415+
}),
388416
],
389417
})

0 commit comments

Comments
 (0)