rsnext/packages/next/build/babel/plugins/no-anonymous-default-export.ts
Luis Alvarez D 735aab6f03
Update Fast Refresh warning (#16496)
Fixes https://github.com/vercel/next.js/issues/16495

Terminal:

![image](https://user-images.githubusercontent.com/4278345/90984442-96421b00-e53a-11ea-9939-44b00cba87cf.png)

Browser: 

![image](https://user-images.githubusercontent.com/4278345/90984456-a9ed8180-e53a-11ea-86da-d9f28e9c2fdd.png)

The link https://nextjs.link/codemod-ndc used for the warning links to a currently 404 docs page, that will be available in the next stable release.

Tests not added as the warning has tests already.
2020-08-24 03:04:25 +00:00

91 lines
2.8 KiB
TypeScript

import { PluginObj, types as BabelTypes } from '@babel/core'
import chalk from 'next/dist/compiled/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
}
}
},
},
}
}