はじめに
ある時こんなファイルを見て「???」となったので調べてみた。
export * from '...略'
export * from '...略'
結論
様々なモジュールから様々なエクスポートを集約した1つのモジュールを作成しているということらしい。
つまり集約元として動作するのみのモジュールということ。
例えば以下のようなコンポーネントがあるとする
export const Header = () => {
return <header>ヘッダー</header>
}
export const Footer = () => {
return <footer>フッター</footer>
}
上記のコンポーネントを集約したモジュールを作成する
export * from './Header'
export * from './Footer'
コンポーネントを読み込むときは集約したモジュールから読み込むだけ
importの記述がスッキリする!
// スッキリ爽快
import { Header, Footer } from '@/components/Layout'
export const Top = () => {
return (
<>
<Header />
<h1>TOP</h1>
<Footer />
</>
)
}
以上!!
何がうれしいのか
モジュールを集約しなかった時の場合importの記述が煩雑になる
コンポーネントが増えてくるとより恩恵を受けられそう。
// モジュールを集約しなかったときの場合
import { Header } from '@/components/Layout/Header'
import { Footer } from '@/components/Layout/Footer'
export const Top = () => {
return (
<>
<Header />
<h1>TOP</h1>
<Footer />
</>
)
}
注意点
export * from ...
は名前付きエクスポートのみ有効になる
以下はバッドパターン
const Header = () => {
return <header>ヘッダー</header>
}
export default Header
export * from './Header' // エラー。再エクスポートできない。
Tree Shaking 的にどうなん?
Tree Shaking
とre-export
に関してこちらの記事を拝見しました。
結論、Reactを書く上ではあまり気にしなくてもいいかなぁといった印象を持ちました。
このあたりまだフワッっとしているのでアンチパターンなどあったら教えて頂きたいです。
import React from 'react'
import { Header } from '@/components/common'
import { Top } from './Top'
export const TopPage = () => {
return (
<>
<Header />
{toggle && <Top />}
{/* <Footer /> */}
</>
)
}
↑FooterをコメントアウトしてみたけどbuildしたJSには含まれてなかった👍
import React from 'react'
console.log('フッター') // <-buildに含まれる
export const Footer = () => {
return <footer>Footer</footer>
}
ただし、↑のようにグローバルに定義したものはbuildに含まれてしまうので注意。
グローバルに書かなければ問題なさそう。
2022/3/19 追記
import XXX from '何かしらのライブラリ'
export const Footer = () => {
return <footer>フッター</footer>
}
上記のような場合でこのFooterコンポーネントがどこでも使われておらず、集約モジュールに入っている場合は、このimportしたモジュールも読み込まれてファイルサイズが大きくなるでのは?とご指摘いただいた。
確かに!
試してみないと何とも言えないところですが、使われていない変数や関数はbuild時に削ぎ落とされるので、そこまで気にする必要はないのかなと思いました。
モジュールをimportするだけで関数が勝手に実行されるライブラリだと怖いですけどね(そんなのある?)
参考資料