-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathbabel-plugin-forbidden-imports.js
More file actions
68 lines (60 loc) · 2.19 KB
/
babel-plugin-forbidden-imports.js
File metadata and controls
68 lines (60 loc) · 2.19 KB
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
const forbiddenRule = require('./forbidden-rule');
const path = require('path');
module.exports = function ({ types: t }) {
return {
visitor: {
ImportDeclaration(pathNode, state) {
const filename = state.file.opts.filename || '';
const importSource = pathNode.node.source.value;
// 跳过 node_modules
if (
filename.includes(`${path.sep}node_modules${path.sep}`) ||
filename.includes('/node_modules/') ||
filename.includes('\\node_modules\\')
) {
return;
}
// 检查 ESLint 注释是否禁用本规则
const leadingComments = pathNode.node.leadingComments || [];
const hasESLintDisable = leadingComments.some(comment =>
/eslint-disable(-next-line)?\s+no-restricted-imports/.test(comment.value),
);
if (hasESLintDisable) return; // 放行
for (const rule of forbiddenRule) {
// 模块名不匹配,跳过
if (importSource !== rule.source) continue;
// 白名单路径匹配,跳过
if (
rule.allowIn?.some(allowPath => {
const fileAbs = path.resolve(filename);
const allowAbs = path.resolve(allowPath);
const relative = path.relative(allowAbs, fileAbs);
// 文件名完全匹配,或在允许目录内
return (
fileAbs === allowAbs || (relative !== '' && !relative.startsWith('..') && !path.isAbsolute(relative))
);
})
) {
continue;
}
// 检查是否导入了禁止的名称
const banned = pathNode.node.specifiers.some(spec => {
if (t.isImportSpecifier(spec)) {
return rule.names.includes(spec.imported.name);
}
if (t.isImportDefaultSpecifier(spec)) {
return rule.names.includes('default');
}
if (t.isImportNamespaceSpecifier(spec)) {
return rule.names.includes('*');
}
return false;
});
if (banned) {
throw pathNode.buildCodeFrameError(rule.message);
}
}
},
},
};
};