/
merge-duplicate-imports.js
100 lines (78 loc) 路 1.93 KB
/
merge-duplicate-imports.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
96
97
98
99
'use strict';
const {types} = require('putout');
const {isImportDefaultSpecifier} = types;
const {entries} = Object;
module.exports.report = () => `Duplicate imports should be avoided`;
module.exports.fix = ({path, imports}) => {
const all = path.node.specifiers;
for (const path of imports) {
const {specifiers} = path.node;
all.push(...specifiers);
path.remove();
}
};
module.exports.traverse = ({push}) => {
const {
add,
get,
clear,
} = importsStore();
return {
ImportDeclaration(path) {
add(path);
},
Program: {
exit: () => {
processImports(push, get());
clear();
},
},
};
};
function processImports(push, imports) {
const {get, add} = duplicatesStore();
let importDefaultCount = 0;
for (const path of imports) {
const {
source,
specifiers,
} = path.node;
const {value} = source;
add(value, path);
importDefaultCount += specifiers.filter(isImportDefaultSpecifier).length;
}
if (importDefaultCount > 1)
return;
for (const [name, list] of get()) {
if (list.length === 1)
continue;
const [path, ...imports] = list;
push({
path,
imports,
});
}
}
function importsStore() {
let imports = [];
const add = (a) => imports.push(a);
const get = () => imports;
const clear = () => imports = [];
return {
add,
get,
clear,
};
}
function duplicatesStore() {
const duplicates = [];
const get = () => entries(duplicates);
const add = (value, path) => {
duplicates[value] = duplicates[value] || [];
duplicates[value].push(path);
};
return {
get,
add,
};
}