248
148

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Qiita開発チームがReactの開発で default export を使わなくなった理由

Last updated at Posted at 2020-10-20

はじめに

こんにちは、Qiita開発チームの@ohakutsuです。

現在、QiitaのフロントエンドはReact + Atomic Designで実装されています。
Atomic Designの特徴として、再利用可能な単位で分割されたコンポーネントをつくる必要があります。
しかし、分割されたコンポーネントの数は日々大きくなっていってしまい、コンポーネントの管理が難しくなってしまいます。
そこで、Qiita開発チームでは、default exportを使い実装をしていたのをやめ、named exportを使い実装を行うようになりました。
今回は、Qiita開発チームがなぜdefault exportを使わなくなったのかについてお話します。

なぜ default export を使わなくなったのか

Qiita開発チームがdefault exportを使わなくなった理由は、default exportだとimportする側で自由に名前を決められてしまうためです。

default exportを使った場合

.jsx
export default () => {
  ...
}
index.jsx
import Button from './Button'
// ↑↓自由に名前をつけることができてしまう
import SubmitButton from './SubmitButton'

...

このように、default exportにしてしまうと、import側で自由に名前をつけることができてしまい、コンポーネント名が統一されなくなってしまいます。

また、例に出したSubmitButtonを抽象化し、Buttonにした場合、ファイルパスはVSCodeなどで自動的に修正をしてくれますが、SubmitButtonButtonにはなりません。ここで、実際の実装と定義名が異なってしまいます。また、それだけではなく、異なっていたとしても動いてしまうため、発見が難しくなるといったこともあります。

named exportを使った場合

SubmitButton.jsx
export const SubmitButton = () => {
  ...
}
index.jsx
import { SubmitButton } from './SubmitButton'

...

named exportの場合、importする側ではexport側で定義された名前をそのまま使うことになります。
また、以下のようにコンポーネント名を変更した場合、

Button.jsx
export const Button = () => {
  ...
}

Submitbuttonをインポートしている側でエラーが起きます。

index.jsx
import { SubmitButton } from './Button' // ←エラーになる

...

エラーが起きるため、インポート側でのコンポーネント名の変更忘れに気づくことができます。

冒頭でもお話しましたが、Atomic Designでは、部品ごとにパーツを作り、さらに組み立てたコンポーネントをつくっていくため、どうしてもコンポーネントの数が多くなってしまいます。そこでdefault exportを使うと、コードを書く人によってコンポーネント名が変わる可能性があり、コンポーネントの管理が難しくなるといった問題が考えられます。
そのため、named exportでインポートするコンポーネント名に制限をし、コンポーネントの管理をしやすくしたというのも1つの理由です。

named exportにしたときの問題点

React.lazyはdefault exportでないと使えない

Code-Splitting – React によると、React.lazyはnamed exportには対応しておらず、

ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;
MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";
MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));

のように、named export -> default exportにするための中間コンポーネントが必要になります。
React.lazyを使う必要のあるコンポーネントの場合は、例外としてディレクトリを分けるなどして、default exportで実装するのもアリだと思います。

さいごに

Qiita開発チームでAtomic Designを行う際に、default exportを使わなくなった理由について書いてきました。
僕はまだQiita開発チームに来て4ヶ月程度しかたっておらず、まだまだ力不足ですが、これからもQiitaをよりよいものにしていくために、開発・改善を行っていきます。

また、Qiitaの質問にdefault export / named exportについての意見交換を投稿しているので、ぜひ、ご意見をお聞かせください。

248
148
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
248
148

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?