diff --git a/configs/recommended.js b/configs/recommended.js
index a807c50b02..67f99a8472 100644
--- a/configs/recommended.js
+++ b/configs/recommended.js
@@ -14,6 +14,7 @@ module.exports = {
'unicorn/import-style': 'error',
'unicorn/new-for-builtins': 'error',
'unicorn/no-abusive-eslint-disable': 'error',
+ 'unicorn/no-anonymous-default-export': 'error',
'unicorn/no-array-callback-reference': 'error',
'unicorn/no-array-for-each': 'error',
'unicorn/no-array-method-this-argument': 'error',
diff --git a/docs/rules/no-anonymous-default-export.md b/docs/rules/no-anonymous-default-export.md
new file mode 100644
index 0000000000..8ac3c117fe
--- /dev/null
+++ b/docs/rules/no-anonymous-default-export.md
@@ -0,0 +1,64 @@
+# Disallow anonymous functions and classes as the default export
+
+πΌ This rule is enabled in the β
`recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs).
+
+π‘ This rule is manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
+
+
+
+
+Naming default exports improves codebase searchability by ensuring consistent identifier use for a module's default export, both where it's declared and where it's imported.
+
+## Fail
+
+```js
+export default class {}
+```
+
+```js
+export default function () {}
+```
+
+```js
+export default () => {};
+```
+
+```js
+module.exports = class {};
+```
+
+```js
+module.exports = function () {};
+```
+
+```js
+module.exports = () => {};
+```
+
+## Pass
+
+```js
+export default class Foo {}
+```
+
+```js
+export default function foo () {}
+```
+
+```js
+const foo = () => {};
+export default foo;
+```
+
+```js
+module.exports = class Foo {};
+```
+
+```js
+module.exports = function foo () {};
+```
+
+```js
+const foo = () => {};
+module.exports = foo;
+```
diff --git a/package.json b/package.json
index c2ebe2dec4..df437f7798 100644
--- a/package.json
+++ b/package.json
@@ -134,7 +134,8 @@
]
}
],
- "import/order": "off"
+ "import/order": "off",
+ "func-names": "off"
},
"overrides": [
{
diff --git a/readme.md b/readme.md
index 506f43f92f..47c31feef5 100644
--- a/readme.md
+++ b/readme.md
@@ -124,6 +124,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c
| [import-style](docs/rules/import-style.md) | Enforce specific import styles per module. | β
| | |
| [new-for-builtins](docs/rules/new-for-builtins.md) | Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. | β
| π§ | |
| [no-abusive-eslint-disable](docs/rules/no-abusive-eslint-disable.md) | Enforce specifying rules to disable in `eslint-disable` comments. | β
| | |
+| [no-anonymous-default-export](docs/rules/no-anonymous-default-export.md) | Disallow anonymous functions and classes as the default export. | β
| | π‘ |
| [no-array-callback-reference](docs/rules/no-array-callback-reference.md) | Prevent passing a function reference directly to iterator methods. | β
| | π‘ |
| [no-array-for-each](docs/rules/no-array-for-each.md) | Prefer `forβ¦of` over the `forEach` method. | β
| π§ | π‘ |
| [no-array-method-this-argument](docs/rules/no-array-method-this-argument.md) | Disallow using the `this` argument in array methods. | β
| π§ | π‘ |
diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js
new file mode 100644
index 0000000000..f520801af5
--- /dev/null
+++ b/rules/no-anonymous-default-export.js
@@ -0,0 +1,212 @@
+'use strict';
+
+const path = require('node:path');
+const {
+ getFunctionHeadLocation,
+ getFunctionNameWithKind,
+ isOpeningParenToken,
+} = require('@eslint-community/eslint-utils');
+const {
+ isIdentifierName,
+} = require('@babel/helper-validator-identifier');
+const getClassHeadLocation = require('./utils/get-class-head-location.js');
+const {upperFirst, camelCase} = require('./utils/lodash.js');
+const {getParenthesizedRange} = require('./utils/parentheses.js');
+const {
+ getScopes,
+ avoidCapture,
+} = require('./utils/index.js');
+const {isMemberExpression} = require('./ast/index.js');
+
+const MESSAGE_ID_ERROR = 'no-anonymous-default-export/error';
+const MESSAGE_ID_SUGGESTION = 'no-anonymous-default-export/suggestion';
+const messages = {
+ [MESSAGE_ID_ERROR]: 'The {{description}} should be named.',
+ [MESSAGE_ID_SUGGESTION]: 'Name it as `{{name}}`.',
+};
+
+const isClassKeywordToken = token => token.type === 'Keyword' && token.value === 'class';
+const isAnonymousClassOrFunction = node =>
+ (
+ (
+ node.type === 'FunctionDeclaration'
+ || node.type === 'FunctionExpression'
+ || node.type === 'ClassDeclaration'
+ || node.type === 'ClassExpression'
+ )
+ && !node.id
+ )
+ || node.type === 'ArrowFunctionExpression';
+
+function getSuggestionName(node, filename, sourceCode) {
+ if (filename === '' || filename === '') {
+ return;
+ }
+
+ let [name] = path.basename(filename).split('.');
+ name = camelCase(name);
+
+ if (!isIdentifierName(name)) {
+ return;
+ }
+
+ name = node.type === 'ClassDeclaration' ? upperFirst(name) : name;
+ name = avoidCapture(name, getScopes(sourceCode.getScope(node)));
+
+ return name;
+}
+
+function addName(fixer, node, name, sourceCode) {
+ switch (node.type) {
+ case 'ClassDeclaration':
+ case 'ClassExpression': {
+ const lastDecorator = node.decorators?.at(-1);
+ const classToken = lastDecorator
+ ? sourceCode.getTokenAfter(lastDecorator, isClassKeywordToken)
+ : sourceCode.getFirstToken(node, isClassKeywordToken);
+ return fixer.insertTextAfter(classToken, ` ${name}`);
+ }
+
+ case 'FunctionDeclaration':
+ case 'FunctionExpression': {
+ const openingParenthesisToken = sourceCode.getFirstToken(
+ node,
+ isOpeningParenToken,
+ );
+ return fixer.insertTextBefore(
+ openingParenthesisToken,
+ `${sourceCode.text.charAt(openingParenthesisToken.range[0] - 1) === ' ' ? '' : ' '}${name} `,
+ );
+ }
+
+ case 'ArrowFunctionExpression': {
+ const [exportDeclarationStart, exportDeclarationEnd]
+ = node.parent.type === 'ExportDefaultDeclaration'
+ ? node.parent.range
+ : node.parent.parent.range;
+ const [arrowFunctionStart, arrowFunctionEnd] = getParenthesizedRange(node, sourceCode);
+
+ let textBefore = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart);
+ let textAfter = sourceCode.text.slice(arrowFunctionEnd, exportDeclarationEnd);
+
+ textBefore = `\n${textBefore}`;
+ if (!/\s$/.test(textBefore)) {
+ textBefore = `${textBefore} `;
+ }
+
+ if (!textAfter.endsWith(';')) {
+ textAfter = `${textAfter};`;
+ }
+
+ return [
+ fixer.replaceTextRange(
+ [exportDeclarationStart, arrowFunctionStart],
+ `const ${name} = `,
+ ),
+ fixer.replaceTextRange(
+ [arrowFunctionEnd, exportDeclarationEnd],
+ ';',
+ ),
+ fixer.insertTextAfterRange(
+ [exportDeclarationEnd, exportDeclarationEnd],
+ `${textBefore}${name}${textAfter}`,
+ ),
+ ];
+ }
+
+ // No default
+ }
+}
+
+function getProblem(node, context) {
+ const {sourceCode, physicalFilename} = context;
+
+ const suggestionName = getSuggestionName(node, physicalFilename, sourceCode);
+
+ let loc;
+ let description;
+ if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {
+ loc = getClassHeadLocation(node, sourceCode);
+ description = 'class';
+ } else {
+ loc = getFunctionHeadLocation(node, sourceCode);
+ // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind`
+ const nameWithKind = getFunctionNameWithKind(node);
+ description = nameWithKind.replace(/ '.*?'$/, '');
+ }
+
+ const problem = {
+ node,
+ loc,
+ messageId: MESSAGE_ID_ERROR,
+ data: {
+ description,
+ },
+ };
+
+ if (!suggestionName) {
+ return problem;
+ }
+
+ problem.suggest = [
+ {
+ messageId: MESSAGE_ID_SUGGESTION,
+ data: {
+ name: suggestionName,
+ },
+ fix: fixer => addName(fixer, node, suggestionName, sourceCode),
+ },
+ ];
+
+ return problem;
+}
+
+/** @param {import('eslint').Rule.RuleContext} context */
+const create = context => {
+ context.on('ExportDefaultDeclaration', node => {
+ if (!isAnonymousClassOrFunction(node.declaration)) {
+ return;
+ }
+
+ return getProblem(node.declaration, context);
+ });
+
+ context.on('AssignmentExpression', node => {
+ if (
+ !isAnonymousClassOrFunction(node.right)
+ || !(
+ node.parent.type === 'ExpressionStatement'
+ && node.parent.expression === node
+ )
+ || !(
+ isMemberExpression(node.left, {
+ object: 'module',
+ property: 'exports',
+ computed: false,
+ optional: false,
+ })
+ || (
+ node.left.type === 'Identifier',
+ node.left.name === 'exports'
+ )
+ )
+ ) {
+ return;
+ }
+
+ return getProblem(node.right, context);
+ });
+};
+
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+ create,
+ meta: {
+ type: 'suggestion',
+ docs: {
+ description: 'Disallow anonymous functions and classes as the default export.',
+ },
+ hasSuggestions: true,
+ messages,
+ },
+};
diff --git a/rules/utils/avoid-capture.js b/rules/utils/avoid-capture.js
index 9a1f9faa42..1de17b16c1 100644
--- a/rules/utils/avoid-capture.js
+++ b/rules/utils/avoid-capture.js
@@ -129,7 +129,7 @@ Useful when you want to rename a variable (or create a new variable) while being
@param {isSafe} [isSafe] - Rule-specific name check function.
@returns {string} - Either `name` as is, or a string like `${name}_` suffixed with underscores to make the name unique.
*/
-module.exports = (name, scopes, isSafe = alwaysTrue) => {
+module.exports = function avoidCapture(name, scopes, isSafe = alwaysTrue) {
if (!isValidIdentifier(name)) {
name += '_';
@@ -144,3 +144,4 @@ module.exports = (name, scopes, isSafe = alwaysTrue) => {
return name;
};
+
diff --git a/rules/utils/cartesian-product-samples.js b/rules/utils/cartesian-product-samples.js
index 726b37ec87..e20926b265 100644
--- a/rules/utils/cartesian-product-samples.js
+++ b/rules/utils/cartesian-product-samples.js
@@ -1,6 +1,6 @@
'use strict';
-module.exports = (combinations, length = Number.POSITIVE_INFINITY) => {
+module.exports = function cartesianProductSamples(combinations, length = Number.POSITIVE_INFINITY) {
const total = combinations.reduce((total, {length}) => total * length, 1);
const samples = Array.from({length: Math.min(total, length)}, (_, sampleIndex) => {
diff --git a/rules/utils/escape-string.js b/rules/utils/escape-string.js
index be0ffc85ec..06c4ff04bb 100644
--- a/rules/utils/escape-string.js
+++ b/rules/utils/escape-string.js
@@ -9,7 +9,7 @@ Escape string and wrap the result in quotes.
@param {string} [quote] - The quote character.
@returns {string} - The quoted and escaped string.
*/
-module.exports = (string, quote = '\'') => {
+module.exports = function escapeString(string, quote = '\'') {
/* c8 ignore start */
if (typeof string !== 'string') {
throw new TypeError('Unexpected string.');
diff --git a/rules/utils/escape-template-element-raw.js b/rules/utils/escape-template-element-raw.js
index 1fdcbf7e27..14bc08c40a 100644
--- a/rules/utils/escape-template-element-raw.js
+++ b/rules/utils/escape-template-element-raw.js
@@ -1,6 +1,7 @@
'use strict';
-module.exports = string => string.replaceAll(
+const escapeTemplateElementRaw = string => string.replaceAll(
/(?<=(?:^|[^\\])(?:\\\\)*)(?(?:`|\$(?={)))/g,
'\\$',
);
+module.exports = escapeTemplateElementRaw;
diff --git a/rules/utils/get-documentation-url.js b/rules/utils/get-documentation-url.js
index 3128369df3..0b1c9738f7 100644
--- a/rules/utils/get-documentation-url.js
+++ b/rules/utils/get-documentation-url.js
@@ -4,7 +4,7 @@ const packageJson = require('../../package.json');
const repoUrl = 'https://github.com/sindresorhus/eslint-plugin-unicorn';
-module.exports = filename => {
+module.exports = function getDocumentationUrl(filename) {
const ruleName = path.basename(filename, '.js');
return `${repoUrl}/blob/v${packageJson.version}/docs/rules/${ruleName}.md`;
};
diff --git a/rules/utils/get-variable-identifiers.js b/rules/utils/get-variable-identifiers.js
index 5a2617655d..816d5e6b40 100644
--- a/rules/utils/get-variable-identifiers.js
+++ b/rules/utils/get-variable-identifiers.js
@@ -1,7 +1,8 @@
'use strict';
// Get identifiers of given variable
-module.exports = ({identifiers, references}) => [...new Set([
+const getVariableIdentifiers = ({identifiers, references}) => [...new Set([
...identifiers,
...references.map(({identifier}) => identifier),
])];
+module.exports = getVariableIdentifiers;
diff --git a/rules/utils/has-same-range.js b/rules/utils/has-same-range.js
index 07227b18e2..7018ffc159 100644
--- a/rules/utils/has-same-range.js
+++ b/rules/utils/has-same-range.js
@@ -1,7 +1,8 @@
'use strict';
-module.exports = (node1, node2) =>
+const hasSameRange = (node1, node2) =>
node1
&& node2
&& node1.range[0] === node2.range[0]
&& node1.range[1] === node2.range[1];
+module.exports = hasSameRange;
diff --git a/rules/utils/is-object-method.js b/rules/utils/is-object-method.js
index c82184f277..f4df81a2dc 100644
--- a/rules/utils/is-object-method.js
+++ b/rules/utils/is-object-method.js
@@ -1,5 +1,5 @@
'use strict';
-module.exports = (node, object, method) => {
+module.exports = function isObjectMethod(node, object, method) {
const {callee} = node;
return (
callee.type === 'MemberExpression'
diff --git a/rules/utils/is-value-not-usable.js b/rules/utils/is-value-not-usable.js
index a838ffd926..88c5df827f 100644
--- a/rules/utils/is-value-not-usable.js
+++ b/rules/utils/is-value-not-usable.js
@@ -2,4 +2,5 @@
const {isExpressionStatement} = require('../ast/index.js');
-module.exports = node => isExpressionStatement(node.parent);
+const isValueNotUsable = node => isExpressionStatement(node.parent);
+module.exports = isValueNotUsable;
diff --git a/rules/utils/resolve-variable-name.js b/rules/utils/resolve-variable-name.js
index 09784128ff..f5b50d126a 100644
--- a/rules/utils/resolve-variable-name.js
+++ b/rules/utils/resolve-variable-name.js
@@ -7,7 +7,7 @@ Finds a variable named `name` in the scope `scope` (or it's parents).
@param {Scope} scope - The scope to look for the variable in.
@returns {Variable?} - The found variable, if any.
*/
-module.exports = (name, scope) => {
+module.exports = function resolveVariableName(name, scope) {
while (scope) {
const variable = scope.set.get(name);
diff --git a/scripts/internal-rules/fix-snapshot-test.js b/scripts/internal-rules/fix-snapshot-test.js
index 1699b0719a..9e206494f0 100644
--- a/scripts/internal-rules/fix-snapshot-test.js
+++ b/scripts/internal-rules/fix-snapshot-test.js
@@ -101,7 +101,7 @@ function checkInvalidCases(node, context) {
}
for (const propertyNode of testCaseNode.properties) {
- if (propertyNode.computed || propertyNode.key.type !== 'Identifier') {
+ if (propertyNode.type !== 'Property' || propertyNode.computed || propertyNode.key.type !== 'Identifier') {
continue;
}
diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs
new file mode 100644
index 0000000000..c9be26d50d
--- /dev/null
+++ b/test/no-anonymous-default-export.mjs
@@ -0,0 +1,320 @@
+import outdent from 'outdent';
+import {getTester, parsers} from './utils/test.mjs';
+
+const {test} = getTester(import.meta);
+
+test.snapshot({
+ valid: [
+ 'export default function named() {}',
+ 'export default class named {}',
+ 'export default []',
+ 'export default {}',
+ 'export default 1',
+ 'export default false',
+ 'export default 0n',
+ 'notExports = class {}',
+ 'notModule.exports = class {}',
+ 'module.notExports = class {}',
+ 'module.exports.foo = class {}',
+ 'alert(exports = class {})',
+ 'foo = module.exports = class {}',
+ ],
+ invalid: [
+ 'export default function () {}',
+ 'export default class {}',
+ 'export default () => {}',
+ 'export default function * () {}',
+ 'export default async function () {}',
+ 'export default async function * () {}',
+ 'export default async () => {}',
+
+ // `ClassDeclaration`
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default class extends class {} {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default class{}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo-bar.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo_bar.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo+bar.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo+bar123.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo*.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/[foo].js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/class.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo.helper.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo.bar.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/foo.test.js',
+ },
+ {
+ code: 'export default class {}',
+ filename: '/path/to/.foo.js',
+ },
+ {
+ code: outdent`
+ let Foo, Foo_, foo, foo_
+ export default class {}
+ `,
+ filename: '/path/to/foo.js',
+ },
+
+ // `ClassExpression`
+ {
+ code: outdent`
+ let Foo, Foo_, foo, foo_
+ export default (class{})
+ `,
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default (class extends class {} {})',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: outdent`
+ let Exports, Exports_, exports, exports_
+ exports = class {}
+ `,
+ filename: '/path/to/exports.js',
+ },
+ {
+ code: 'module.exports = class {}',
+ filename: '/path/to/module.js',
+ },
+
+ // `FunctionDeclaration`
+ {
+ code: 'export default function () {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default function* () {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default async function* () {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default async function*() {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default async function *() {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default async function * () {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default async function * /* comment */ () {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: outdent`
+ export default async function * // comment
+ () {}
+ `,
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: outdent`
+ let Foo, Foo_, foo, foo_
+ export default async function * () {}
+ `,
+ filename: '/path/to/foo.js',
+ },
+
+ // `FunctionExpression`
+ {
+ code: outdent`
+ let Foo, Foo_, foo, foo_
+ export default (async function * () {})
+ `,
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: outdent`
+ let Exports, Exports_, exports, exports_
+ exports = function() {}
+ `,
+ filename: '/path/to/exports.js',
+ },
+ {
+ code: 'module.exports = function() {}',
+ filename: '/path/to/module.js',
+ },
+
+ // `ArrowFunctionExpression`
+ {
+ code: 'export default () => {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default async () => {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default () => {};',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default() => {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default foo => {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: 'export default (( () => {} ))',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: '/* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {}',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: outdent`
+ // comment 1
+ export
+ // comment 2
+ default
+ // comment 3
+ () => {}
+ `,
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: outdent`
+ let Foo, Foo_, foo, foo_
+ export default async () => {}
+ `,
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: outdent`
+ let Exports, Exports_, exports, exports_
+ exports = (( () => {} ))
+ `,
+ filename: '/path/to/exports.js',
+ },
+ {
+ code: outdent`
+ // comment 1
+ module
+ // comment 2
+ .exports
+ // comment 3
+ =
+ // comment 4
+ () => {};
+ `,
+ filename: '/path/to/module.js',
+ },
+ {
+ code: '(( exports = (( () => {} )) ))',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: '(( module.exports = (( () => {} )) ))',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: '(( exports = (( () => {} )) ));',
+ filename: '/path/to/foo.js',
+ },
+ {
+ code: '(( module.exports = (( () => {} )) ));',
+ filename: '/path/to/foo.js',
+ },
+ ],
+});
+
+// Decorators
+const decoratorsBeforeExportOptions = {
+ parser: parsers.babel,
+ parserOptions: {
+ babelOptions: {
+ parserOpts: {
+ plugins: [
+ ['decorators', {decoratorsBeforeExport: true}],
+ ],
+ },
+ },
+ },
+};
+const decoratorsAfterExportOptions = {
+ parser: parsers.babel,
+ parserOptions: {
+ babelOptions: {
+ parserOpts: {
+ plugins: [
+ ['decorators', {decoratorsBeforeExport: false}],
+ ],
+ },
+ },
+ },
+};
+test.snapshot({
+ valid: [],
+ invalid: [
+ {
+ code: '@decorator export default class {}',
+ filename: '/path/to/foo.js',
+ ...decoratorsBeforeExportOptions,
+ },
+ {
+ code: 'export default @decorator(class {}) class extends class {} {}',
+ filename: '/path/to/foo.js',
+ ...decoratorsAfterExportOptions,
+ },
+ {
+ code: 'module.exports = @decorator(class {}) class extends class {} {}',
+ filename: '/path/to/foo.js',
+ ...decoratorsAfterExportOptions,
+ },
+ {
+ code: '@decorator @decorator(class {}) export default class {}',
+ filename: '/path/to/foo.js',
+ ...decoratorsBeforeExportOptions,
+ },
+ ],
+});
+
diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md
new file mode 100644
index 0000000000..d016aec97d
--- /dev/null
+++ b/test/snapshots/no-anonymous-default-export.mjs.md
@@ -0,0 +1,1435 @@
+# Snapshot report for `test/no-anonymous-default-export.mjs`
+
+The actual snapshot is saved in `no-anonymous-default-export.mjs.snap`.
+
+Generated by [AVA](https://avajs.dev).
+
+## invalid(1): export default function () {}
+
+> Input
+
+ `β
+ 1 | export default function () {}β
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default function () {}β
+ | ^^^^^^^^^ The function should be named.β
+ `
+
+## invalid(2): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ `
+
+## invalid(3): export default () => {}
+
+> Input
+
+ `β
+ 1 | export default () => {}β
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default () => {}β
+ | ^^ The arrow function should be named.β
+ `
+
+## invalid(4): export default function * () {}
+
+> Input
+
+ `β
+ 1 | export default function * () {}β
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default function * () {}β
+ | ^^^^^^^^^^^ The generator function should be named.β
+ `
+
+## invalid(5): export default async function () {}
+
+> Input
+
+ `β
+ 1 | export default async function () {}β
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function () {}β
+ | ^^^^^^^^^^^^^^^ The async function should be named.β
+ `
+
+## invalid(6): export default async function * () {}
+
+> Input
+
+ `β
+ 1 | export default async function * () {}β
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function * () {}β
+ | ^^^^^^^^^^^^^^^^^ The async generator function should be named.β
+ `
+
+## invalid(7): export default async () => {}
+
+> Input
+
+ `β
+ 1 | export default async () => {}β
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async () => {}β
+ | ^^ The async arrow function should be named.β
+ `
+
+## invalid(8): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo {}β
+ `
+
+## invalid(9): export default class extends class {} {}
+
+> Input
+
+ `β
+ 1 | export default class extends class {} {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class extends class {} {}β
+ | ^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo extends class {} {}β
+ `
+
+## invalid(10): export default class{}
+
+> Input
+
+ `β
+ 1 | export default class{}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class{}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo{}β
+ `
+
+## invalid(11): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo-bar.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`FooBar\`.β
+ 1 | export default class FooBar {}β
+ `
+
+## invalid(12): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo_bar.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`FooBar\`.β
+ 1 | export default class FooBar {}β
+ `
+
+## invalid(13): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo+bar.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`FooBar\`.β
+ 1 | export default class FooBar {}β
+ `
+
+## invalid(14): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo+bar123.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`FooBar123\`.β
+ 1 | export default class FooBar123 {}β
+ `
+
+## invalid(15): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo*.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo {}β
+ `
+
+## invalid(16): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/[foo].jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo {}β
+ `
+
+## invalid(17): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/class.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Class\`.β
+ 1 | export default class Class {}β
+ `
+
+## invalid(18): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.helper.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo {}β
+ `
+
+## invalid(19): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.bar.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo {}β
+ `
+
+## invalid(20): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.test.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default class Foo {}β
+ `
+
+## invalid(21): export default class {}
+
+> Input
+
+ `β
+ 1 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/.foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default class {}β
+ | ^^^^^ The class should be named.β
+ `
+
+## invalid(22): let Foo, Foo_, foo, foo_ export default class {}
+
+> Input
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ > 2 | export default class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo__\`.β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default class Foo__ {}β
+ `
+
+## invalid(23): let Foo, Foo_, foo, foo_ export default (class{})
+
+> Input
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default (class{})β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ > 2 | export default (class{})β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo__\`.β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default (class foo__{})β
+ `
+
+## invalid(24): export default (class extends class {} {})
+
+> Input
+
+ `β
+ 1 | export default (class extends class {} {})β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default (class extends class {} {})β
+ | ^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default (class foo extends class {} {})β
+ `
+
+## invalid(25): let Exports, Exports_, exports, exports_ exports = class {}
+
+> Input
+
+ `β
+ 1 | let Exports, Exports_, exports, exports_β
+ 2 | exports = class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/exports.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Exports, Exports_, exports, exports_β
+ > 2 | exports = class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`exports__\`.β
+ 1 | let Exports, Exports_, exports, exports_β
+ 2 | exports = class exports__ {}β
+ `
+
+## invalid(26): module.exports = class {}
+
+> Input
+
+ `β
+ 1 | module.exports = class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/module.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | module.exports = class {}β
+ | ^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`module_\`.β
+ 1 | module.exports = class module_ {}β
+ `
+
+## invalid(27): export default function () {}
+
+> Input
+
+ `β
+ 1 | export default function () {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default function () {}β
+ | ^^^^^^^^^ The function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default function foo () {}β
+ `
+
+## invalid(28): export default function* () {}
+
+> Input
+
+ `β
+ 1 | export default function* () {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default function* () {}β
+ | ^^^^^^^^^^ The generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default function* foo () {}β
+ `
+
+## invalid(29): export default async function* () {}
+
+> Input
+
+ `β
+ 1 | export default async function* () {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function* () {}β
+ | ^^^^^^^^^^^^^^^^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default async function* foo () {}β
+ `
+
+## invalid(30): export default async function*() {}
+
+> Input
+
+ `β
+ 1 | export default async function*() {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function*() {}β
+ | ^^^^^^^^^^^^^^^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default async function* foo () {}β
+ `
+
+## invalid(31): export default async function *() {}
+
+> Input
+
+ `β
+ 1 | export default async function *() {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function *() {}β
+ | ^^^^^^^^^^^^^^^^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default async function * foo () {}β
+ `
+
+## invalid(32): export default async function * () {}
+
+> Input
+
+ `β
+ 1 | export default async function * () {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function * () {}β
+ | ^^^^^^^^^^^^^^^^^^^^^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default async function * foo () {}β
+ `
+
+## invalid(33): export default async function * /* comment */ () {}
+
+> Input
+
+ `β
+ 1 | export default async function * /* comment */ () {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function * /* comment */ () {}β
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default async function * /* comment */ foo () {}β
+ `
+
+## invalid(34): export default async function * // comment () {}
+
+> Input
+
+ `β
+ 1 | export default async function * // commentβ
+ 2 | () {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async function * // commentβ
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^β
+ > 2 | () {}β
+ | ^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | export default async function * // commentβ
+ 2 | foo () {}β
+ `
+
+## invalid(35): let Foo, Foo_, foo, foo_ export default async function * () {}
+
+> Input
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default async function * () {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ > 2 | export default async function * () {}β
+ | ^^^^^^^^^^^^^^^^^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo__\`.β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default async function * foo__ () {}β
+ `
+
+## invalid(36): let Foo, Foo_, foo, foo_ export default (async function * () {})
+
+> Input
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default (async function * () {})β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ > 2 | export default (async function * () {})β
+ | ^^^^^^^^^^^^^^^^^ The async generator function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo__\`.β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default (async function * foo__ () {})β
+ `
+
+## invalid(37): let Exports, Exports_, exports, exports_ exports = function() {}
+
+> Input
+
+ `β
+ 1 | let Exports, Exports_, exports, exports_β
+ 2 | exports = function() {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/exports.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Exports, Exports_, exports, exports_β
+ > 2 | exports = function() {}β
+ | ^^^^^^^^ The function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`exports__\`.β
+ 1 | let Exports, Exports_, exports, exports_β
+ 2 | exports = function exports__ () {}β
+ `
+
+## invalid(38): module.exports = function() {}
+
+> Input
+
+ `β
+ 1 | module.exports = function() {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/module.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | module.exports = function() {}β
+ | ^^^^^^^^ The function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`module_\`.β
+ 1 | module.exports = function module_ () {}β
+ `
+
+## invalid(39): export default () => {}
+
+> Input
+
+ `β
+ 1 | export default () => {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default () => {}β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = () => {};β
+ 2 | export default foo;β
+ `
+
+## invalid(40): export default async () => {}
+
+> Input
+
+ `β
+ 1 | export default async () => {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default async () => {}β
+ | ^^ The async arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = async () => {};β
+ 2 | export default foo;β
+ `
+
+## invalid(41): export default () => {};
+
+> Input
+
+ `β
+ 1 | export default () => {};β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default () => {};β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = () => {};β
+ 2 | export default foo;β
+ `
+
+## invalid(42): export default() => {}
+
+> Input
+
+ `β
+ 1 | export default() => {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default() => {}β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = () => {};β
+ 2 | export default foo;β
+ `
+
+## invalid(43): export default foo => {}
+
+> Input
+
+ `β
+ 1 | export default foo => {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default foo => {}β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo_\`.β
+ 1 | const foo_ = foo => {};β
+ 2 | export default foo_;β
+ `
+
+## invalid(44): export default (( () => {} ))
+
+> Input
+
+ `β
+ 1 | export default (( () => {} ))β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default (( () => {} ))β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = (( () => {} ));β
+ 2 | export default foo;β
+ `
+
+## invalid(45): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {}
+
+> Input
+
+ `β
+ 1 | /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {}β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | /* comment 1 */ const foo = () => {};β
+ 2 | export /* comment 2 */ default /* comment 3 */ foo;β
+ `
+
+## invalid(46): // comment 1 export // comment 2 default // comment 3 () => {}
+
+> Input
+
+ `β
+ 1 | // comment 1β
+ 2 | exportβ
+ 3 | // comment 2β
+ 4 | defaultβ
+ 5 | // comment 3β
+ 6 | () => {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | // comment 1β
+ 2 | exportβ
+ 3 | // comment 2β
+ 4 | defaultβ
+ 5 | // comment 3β
+ > 6 | () => {}β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | // comment 1β
+ 2 | const foo = () => {};β
+ 3 | exportβ
+ 4 | // comment 2β
+ 5 | defaultβ
+ 6 | // comment 3β
+ 7 | foo;β
+ `
+
+## invalid(47): let Foo, Foo_, foo, foo_ export default async () => {}
+
+> Input
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | export default async () => {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Foo, Foo_, foo, foo_β
+ > 2 | export default async () => {}β
+ | ^^ The async arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo__\`.β
+ 1 | let Foo, Foo_, foo, foo_β
+ 2 | const foo__ = async () => {};β
+ 3 | export default foo__;β
+ `
+
+## invalid(48): let Exports, Exports_, exports, exports_ exports = (( () => {} ))
+
+> Input
+
+ `β
+ 1 | let Exports, Exports_, exports, exports_β
+ 2 | exports = (( () => {} ))β
+ `
+
+> Filename
+
+ `β
+ /path/to/exports.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | let Exports, Exports_, exports, exports_β
+ > 2 | exports = (( () => {} ))β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`exports__\`.β
+ 1 | let Exports, Exports_, exports, exports_β
+ 2 | const exports__ = (( () => {} ));β
+ 3 | exports = exports__;β
+ `
+
+## invalid(49): // comment 1 module // comment 2 .exports // comment 3 = // comment 4 () => {};
+
+> Input
+
+ `β
+ 1 | // comment 1β
+ 2 | moduleβ
+ 3 | // comment 2β
+ 4 | .exportsβ
+ 5 | // comment 3β
+ 6 | =β
+ 7 | // comment 4β
+ 8 | () => {};β
+ `
+
+> Filename
+
+ `β
+ /path/to/module.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ 1 | // comment 1β
+ 2 | moduleβ
+ 3 | // comment 2β
+ 4 | .exportsβ
+ 5 | // comment 3β
+ 6 | =β
+ 7 | // comment 4β
+ > 8 | () => {};β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`module_\`.β
+ 1 | // comment 1β
+ 2 | const module_ = () => {};β
+ 3 | moduleβ
+ 4 | // comment 2β
+ 5 | .exportsβ
+ 6 | // comment 3β
+ 7 | =β
+ 8 | // comment 4β
+ 9 | module_;β
+ `
+
+## invalid(50): (( exports = (( () => {} )) ))
+
+> Input
+
+ `β
+ 1 | (( exports = (( () => {} )) ))β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | (( exports = (( () => {} )) ))β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = (( () => {} ));β
+ 2 | (( exports = foo ));β
+ `
+
+## invalid(51): (( module.exports = (( () => {} )) ))
+
+> Input
+
+ `β
+ 1 | (( module.exports = (( () => {} )) ))β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | (( module.exports = (( () => {} )) ))β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = (( () => {} ));β
+ 2 | (( module.exports = foo ));β
+ `
+
+## invalid(52): (( exports = (( () => {} )) ));
+
+> Input
+
+ `β
+ 1 | (( exports = (( () => {} )) ));β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | (( exports = (( () => {} )) ));β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = (( () => {} ));β
+ 2 | (( exports = foo ));β
+ `
+
+## invalid(53): (( module.exports = (( () => {} )) ));
+
+> Input
+
+ `β
+ 1 | (( module.exports = (( () => {} )) ));β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | (( module.exports = (( () => {} )) ));β
+ | ^^ The arrow function should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | const foo = (( () => {} ));β
+ 2 | (( module.exports = foo ));β
+ `
+
+## invalid(1): @decorator export default class {}
+
+> Input
+
+ `β
+ 1 | @decorator export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | @decorator export default class {}β
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | @decorator export default class Foo {}β
+ `
+
+## invalid(2): export default @decorator(class {}) class extends class {} {}
+
+> Input
+
+ `β
+ 1 | export default @decorator(class {}) class extends class {} {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | export default @decorator(class {}) class extends class {} {}β
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | export default @decorator(class {}) class Foo extends class {} {}β
+ `
+
+## invalid(3): module.exports = @decorator(class {}) class extends class {} {}
+
+> Input
+
+ `β
+ 1 | module.exports = @decorator(class {}) class extends class {} {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | module.exports = @decorator(class {}) class extends class {} {}β
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`foo\`.β
+ 1 | module.exports = @decorator(class {}) class foo extends class {} {}β
+ `
+
+## invalid(4): @decorator @decorator(class {}) export default class {}
+
+> Input
+
+ `β
+ 1 | @decorator @decorator(class {}) export default class {}β
+ `
+
+> Filename
+
+ `β
+ /path/to/foo.jsβ
+ `
+
+> Error 1/1
+
+ `β
+ > 1 | @decorator @decorator(class {}) export default class {}β
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β
+ β
+ --------------------------------------------------------------------------------β
+ Suggestion 1/1: Name it as \`Foo\`.β
+ 1 | @decorator @decorator(class {}) export default class Foo {}β
+ `
diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap
new file mode 100644
index 0000000000..5d4237c13a
Binary files /dev/null and b/test/snapshots/no-anonymous-default-export.mjs.snap differ