React开发规范:默认导出 VS 具名导出

87 阅读3分钟

React中组件的神奇之处在于它们的可重用性:你可以创建一个由其他组件构成的组件。但当你嵌套了越来越多的组件时,则需要将它们拆分成不同的文件。这样可以使得查找文件更加容易,并且能在更多地方复用这些组件。

导出组件

这是 JavaScript 里两个主要用来导出值的方式:默认导出和具名导出。到目前为止,我们的示例中只用到了默认导出。但你可以在一个文件中,选择使用其中一种,或者两种都使用。一个文件里有且仅有一个 默认 导出,但是可以有任意多个 具名 导出。

组件的导出方式决定了其导入方式。当你用默认导入的方式,导入具名导出的组件时,就会报错。如下表格可以帮你更好地理解它们:

语法导出语句导入语句
默认export default function Button() {}import Button from './Button.js';
具名export function Button() {}import { Button } from './Button.js';
// 默认导出 (Default Export)
export default function MyComponent() { }

// 具名导出 (Named Export)
export function MyComponent() { }

核心区别

当使用默认导入时,你可以在 import 语句后面进行任意命名。比如 import Banana from './Button.js',如此你能获得与默认导出一致的内容。相反,对于具名导入,导入和导出的名字必须一致。这也是称其为 具名 导入的原因!

特性默认导出具名导出
导入名称可任意命名必须对应导出名称
IDE自动导入较差,可能重名优秀,精准匹配
重构支持弱,无法全局重命名强,支持全局重命名
Tree Shaking可能失效始终有效
代码提示有限完整
可读性追踪来源困难来源清晰明确

默认导出的问题 ⚠️

1. 命名混乱

// Button.js
export default function Button() {}

// 在其他文件中
import Btn from './Button';      // 合法但语义不清
import ButtonComponent from './Button'; // 另一个名字

2. 重构困难

当修改文件名或组件名时,IDE无法自动更新所有导入点。

3. Tree Shaking风险

// 默认导出对象时
export default { Button, Input, Select };
import { Button } from './components'; // 可能打包整个对象

4. 难以聚合导出

// 需要额外步骤
export { default as Button } from './Button';

具名导出的优势 ✅

1. 强类型支持

// 组件定义
export function UserCard(props: UserCardProps) {}

// 使用时自动提示所有导出
import { UserCard } from './components'; // IDE精确提示

2. 可靠的重构

// 重命名组件时,IDE可全局更新所有导入点

3. 清晰的依赖关系

import { UserCard, UserAvatar, UserMenu } from './user';
// 一目了然使用了哪些组件

4. 便于 Barrel exports

// components/index.js
export { UserCard } from './UserCard';
export { UserAvatar } from './UserAvatar';

// 使用
import { UserCard, UserAvatar } from './components';

社区推荐规范

Airbnb规范(ESLint规则)

// ❌ 不推荐
export default class MyComponent extends React.Component {}

// ✅ 推荐
export class MyComponent extends React.Component {}

ESLint配置:

{
  "rules": {
    "import/prefer-default-export": "off",
    "import/no-default-export": "error"
  }
}

React核心团队实践 React官方项目(如React DevTools)100%使用具名导出

例外情况

默认导出在极少数场景仍可接受:

  1. Next.js页面(框架强制要求)
  2. 单一入口的库(如 export default axios
  3. 遗留代码兼容性

但即使在这些场景,也建议在文件内部优先使用具名导出。

总结

场景推荐方式理由
React组件具名导出重构、可读性、Tree Shaking
工具函数具名导出按需引入、IDE支持
TypeScript类型具名导出必须具名
第三方库入口可默认导出简化使用
Next.js页面被迫默认框架限制

核心原则:具名导出是React现代开发的标配,默认导出应视为例外而非常规。它带来的可维护性收益远超微小的书写便捷性。

感谢大家收看!Forever React!