/
no-anonymous-default-export.ts
91 lines (86 loc) · 2.79 KB
/
no-anonymous-default-export.ts
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
import { PluginObj, types as BabelTypes } from 'next/dist/compiled/babel/core'
import chalk from 'chalk'
export default function NoAnonymousDefaultExport({
types: t,
...babel
}: {
types: typeof BabelTypes
caller: (callerCallback: (caller: any) => any) => any
}): PluginObj<any> {
let onWarning: ((reason: string | Error) => void) | null = null
babel.caller((caller) => {
onWarning = caller.onWarning
return '' // Intentionally empty to not invalidate cache
})
if (typeof onWarning !== 'function') {
return { visitor: {} }
}
const warn = onWarning!
return {
visitor: {
ExportDefaultDeclaration(path) {
const def = path.node.declaration
if (
!(
def.type === 'ArrowFunctionExpression' ||
def.type === 'FunctionDeclaration'
)
) {
return
}
switch (def.type) {
case 'ArrowFunctionExpression': {
warn(
[
chalk.yellow.bold(
'Anonymous arrow functions cause Fast Refresh to not preserve local component state.'
),
'Please add a name to your function, for example:',
'',
chalk.bold('Before'),
chalk.cyan('export default () => <div />;'),
'',
chalk.bold('After'),
chalk.cyan('const Named = () => <div />;'),
chalk.cyan('export default Named;'),
'',
`A codemod is available to fix the most common cases: ${chalk.cyan(
'https://nextjs.link/codemod-ndc'
)}`,
].join('\n')
)
break
}
case 'FunctionDeclaration': {
const isAnonymous = !Boolean(def.id)
if (isAnonymous) {
warn(
[
chalk.yellow.bold(
'Anonymous function declarations cause Fast Refresh to not preserve local component state.'
),
'Please add a name to your function, for example:',
'',
chalk.bold('Before'),
chalk.cyan('export default function () { /* ... */ }'),
'',
chalk.bold('After'),
chalk.cyan('export default function Named() { /* ... */ }'),
'',
`A codemod is available to fix the most common cases: ${chalk.cyan(
'https://nextjs.link/codemod-ndc'
)}`,
].join('\n')
)
}
break
}
default: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _: never = def
}
}
},
},
}
}