forked from import-js/eslint-plugin-import
/
prefer-default-export.js
95 lines (81 loc) · 2.4 KB
/
prefer-default-export.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
'use strict'
import docsUrl from '../docsUrl'
module.exports = {
meta: {
type: 'suggestion',
docs: {
url: docsUrl('prefer-default-export'),
},
},
create: function(context) {
let specifierExportCount = 0
let hasDefaultExport = false
let hasStarExport = false
let hasTypeExport = false
let namedExportNode = null
function captureDeclaration(identifierOrPattern) {
if (identifierOrPattern.type === 'ObjectPattern') {
// recursively capture
identifierOrPattern.properties
.forEach(function(property) {
captureDeclaration(property.value)
})
} else if (identifierOrPattern.type === 'ArrayPattern') {
identifierOrPattern.elements
.forEach(captureDeclaration)
} else {
// assume it's a single standard identifier
specifierExportCount++
}
}
return {
'ExportDefaultSpecifier': function() {
hasDefaultExport = true
},
'ExportSpecifier': function(node) {
if (node.exported.name === 'default') {
hasDefaultExport = true
} else {
specifierExportCount++
namedExportNode = node
}
},
'ExportNamedDeclaration': function(node) {
// if there are specifiers, node.declaration should be null
if (!node.declaration) return
const { type } = node.declaration
if (
type === 'TSTypeAliasDeclaration' ||
type === 'TypeAlias' ||
type === 'TSInterfaceDeclaration' ||
type === 'InterfaceDeclaration'
) {
specifierExportCount++
hasTypeExport = true
return
}
if (node.declaration.declarations) {
node.declaration.declarations.forEach(function(declaration) {
captureDeclaration(declaration.id)
})
}
else {
// captures 'export function foo() {}' syntax
specifierExportCount++
}
namedExportNode = node
},
'ExportDefaultDeclaration': function() {
hasDefaultExport = true
},
'ExportAllDeclaration': function() {
hasStarExport = true
},
'Program:exit': function() {
if (specifierExportCount === 1 && !hasDefaultExport && !hasStarExport && !hasTypeExport) {
context.report(namedExportNode, 'Prefer default export.')
}
},
}
},
}