forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
no-duplicate-head.js
60 lines (56 loc) · 1.71 KB
/
no-duplicate-head.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
const url = 'https://nextjs.org/docs/messages/no-duplicate-head'
module.exports = {
meta: {
docs: {
description:
'Prevent duplicate usage of `<Head>` in `pages/_document.js`.',
recommended: true,
url,
},
type: 'problem',
schema: [],
},
create: function (context) {
let documentImportName
return {
ImportDeclaration(node) {
if (node.source.value === 'next/document') {
const documentImport = node.specifiers.find(
({ type }) => type === 'ImportDefaultSpecifier'
)
if (documentImport && documentImport.local) {
documentImportName = documentImport.local.name
}
}
},
ReturnStatement(node) {
const ancestors = context.getAncestors()
const documentClass = ancestors.find(
(ancestorNode) =>
ancestorNode.type === 'ClassDeclaration' &&
ancestorNode.superClass &&
ancestorNode.superClass.name === documentImportName
)
if (!documentClass) {
return
}
if (node.argument && node.argument.children) {
const headComponents = node.argument.children.filter(
(childrenNode) =>
childrenNode.openingElement &&
childrenNode.openingElement.name &&
childrenNode.openingElement.name.name === 'Head'
)
if (headComponents.length > 1) {
for (let i = 1; i < headComponents.length; i++) {
context.report({
node: headComponents[i],
message: `Do not include multiple instances of \`<Head/>\`. See: ${url}`,
})
}
}
}
},
}
},
}