-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
dynamic-import-chunkname.js
119 lines (104 loc) · 3.42 KB
/
dynamic-import-chunkname.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import vm from 'vm';
import docsUrl from '../docsUrl';
module.exports = {
meta: {
type: 'suggestion',
docs: {
url: docsUrl('dynamic-import-chunkname'),
},
schema: [{
type: 'object',
properties: {
importFunctions: {
type: 'array',
uniqueItems: true,
items: {
type: 'string',
},
},
webpackChunknameFormat: {
type: 'string',
},
},
}],
},
create(context) {
const config = context.options[0];
const { importFunctions = [] } = config || {};
const { webpackChunknameFormat = '([0-9a-zA-Z-_/.]|\\[(request|index)\\])+' } = config || {};
const paddedCommentRegex = /^ (\S[\s\S]+\S) $/;
const commentStyleRegex = /^( ((webpackChunkName: .+)|((webpackPrefetch|webpackPreload): (true|false|-?[0-9]+))|(webpackIgnore: (true|false))|((webpackInclude|webpackExclude): \/.*\/)|(webpackMode: ["'](lazy|lazy-once|eager|weak)["'])|(webpackExports: (['"]\w+['"]|\[(['"]\w+['"], *)+(['"]\w+['"]*)\]))),?)+ $/;
const chunkSubstrFormat = ` webpackChunkName: ["']${webpackChunknameFormat}["'],? `;
const chunkSubstrRegex = new RegExp(chunkSubstrFormat);
function run(node, arg) {
const sourceCode = context.getSourceCode();
const leadingComments = sourceCode.getCommentsBefore
? sourceCode.getCommentsBefore(arg) // This method is available in ESLint >= 4.
: sourceCode.getComments(arg).leading; // This method is deprecated in ESLint 7.
if (!leadingComments || leadingComments.length === 0) {
context.report({
node,
message: 'dynamic imports require a leading comment with the webpack chunkname',
});
return;
}
let isChunknamePresent = false;
for (const comment of leadingComments) {
if (comment.type !== 'Block') {
context.report({
node,
message: 'dynamic imports require a /* foo */ style comment, not a // foo comment',
});
return;
}
if (!paddedCommentRegex.test(comment.value)) {
context.report({
node,
message: `dynamic imports require a block comment padded with spaces - /* foo */`,
});
return;
}
try {
// just like webpack itself does
vm.runInNewContext(`(function() {return {${comment.value}}})()`);
}
catch (error) {
context.report({
node,
message: `dynamic imports require a "webpack" comment with valid syntax`,
});
return;
}
if (!commentStyleRegex.test(comment.value)) {
context.report({
node,
message:
`dynamic imports require a "webpack" comment with valid syntax`,
});
return;
}
if (chunkSubstrRegex.test(comment.value)) {
isChunknamePresent = true;
}
}
if (!isChunknamePresent) {
context.report({
node,
message:
`dynamic imports require a leading comment in the form /*${chunkSubstrFormat}*/`,
});
}
}
return {
ImportExpression(node) {
run(node, node.source);
},
CallExpression(node) {
if (node.callee.type !== 'Import' && importFunctions.indexOf(node.callee.name) < 0) {
return;
}
run(node, node.arguments[0]);
},
};
},
};