forked from import-js/eslint-plugin-import
/
dynamic-import-chunkname.js
119 lines (104 loc) · 3.17 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: function (context) {
const config = context.options[0]
const { importFunctions = [] } = config || {}
const { webpackChunknameFormat = '[0-9a-zA-Z-_/.]+' } = config || {}
const paddedCommentRegex = /^ (\S[\s\S]+\S) $/
const commentStyleRegex = /^( \w+: (["'][^"']*["']|\d+|false|true),?)+ $/
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 leading comment in the form /*${chunkSubstrFormat}*/`,
})
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])
},
}
},
}