Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/eslint-plugin-import
Path: blob/main/src/rules/dynamic-import-chunkname.js
829 views
1
import vm from 'vm';
2
import docsUrl from '../docsUrl';
3
4
module.exports = {
5
meta: {
6
type: 'suggestion',
7
docs: {
8
url: docsUrl('dynamic-import-chunkname'),
9
},
10
schema: [{
11
type: 'object',
12
properties: {
13
importFunctions: {
14
type: 'array',
15
uniqueItems: true,
16
items: {
17
type: 'string',
18
},
19
},
20
webpackChunknameFormat: {
21
type: 'string',
22
},
23
},
24
}],
25
},
26
27
create(context) {
28
const config = context.options[0];
29
const { importFunctions = [] } = config || {};
30
const { webpackChunknameFormat = '[0-9a-zA-Z-_/.]+' } = config || {};
31
32
const paddedCommentRegex = /^ (\S[\s\S]+\S) $/;
33
const commentStyleRegex = /^( \w+: (["'][^"']*["']|\d+|false|true),?)+ $/;
34
const chunkSubstrFormat = ` webpackChunkName: ["']${webpackChunknameFormat}["'],? `;
35
const chunkSubstrRegex = new RegExp(chunkSubstrFormat);
36
37
function run(node, arg) {
38
const sourceCode = context.getSourceCode();
39
const leadingComments = sourceCode.getCommentsBefore
40
? sourceCode.getCommentsBefore(arg) // This method is available in ESLint >= 4.
41
: sourceCode.getComments(arg).leading; // This method is deprecated in ESLint 7.
42
43
if (!leadingComments || leadingComments.length === 0) {
44
context.report({
45
node,
46
message: 'dynamic imports require a leading comment with the webpack chunkname',
47
});
48
return;
49
}
50
51
let isChunknamePresent = false;
52
53
for (const comment of leadingComments) {
54
if (comment.type !== 'Block') {
55
context.report({
56
node,
57
message: 'dynamic imports require a /* foo */ style comment, not a // foo comment',
58
});
59
return;
60
}
61
62
if (!paddedCommentRegex.test(comment.value)) {
63
context.report({
64
node,
65
message: `dynamic imports require a block comment padded with spaces - /* foo */`,
66
});
67
return;
68
}
69
70
try {
71
// just like webpack itself does
72
vm.runInNewContext(`(function() {return {${comment.value}}})()`);
73
}
74
catch (error) {
75
context.report({
76
node,
77
message: `dynamic imports require a "webpack" comment with valid syntax`,
78
});
79
return;
80
}
81
82
if (!commentStyleRegex.test(comment.value)) {
83
context.report({
84
node,
85
message:
86
`dynamic imports require a leading comment in the form /*${chunkSubstrFormat}*/`,
87
});
88
return;
89
}
90
91
if (chunkSubstrRegex.test(comment.value)) {
92
isChunknamePresent = true;
93
}
94
}
95
96
if (!isChunknamePresent) {
97
context.report({
98
node,
99
message:
100
`dynamic imports require a leading comment in the form /*${chunkSubstrFormat}*/`,
101
});
102
}
103
}
104
105
return {
106
ImportExpression(node) {
107
run(node, node.source);
108
},
109
110
CallExpression(node) {
111
if (node.callee.type !== 'Import' && importFunctions.indexOf(node.callee.name) < 0) {
112
return;
113
}
114
115
run(node, node.arguments[0]);
116
},
117
};
118
},
119
};
120
121