11
3

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.

export * fromとは何なのか

Last updated at Posted at 2022-02-28

はじめに

ある時こんなファイルを見て「???」となったので調べてみた。

index.ts
export * from '...略'
export * from '...略'

結論

様々なモジュールから様々なエクスポートを集約した1つのモジュールを作成しているということらしい。
つまり集約元として動作するのみのモジュールということ。

例えば以下のようなコンポーネントがあるとする

src/components/Layout/Header.tsx
export const Header = () => {
 return <header>ヘッダー</header>
}
src/components/Layout/Footer.tsx
export const Footer = () => {
 return <footer>フッター</footer>
}

上記のコンポーネントを集約したモジュールを作成する

src/components/Layout/index.ts
export * from './Header'
export * from './Footer'

コンポーネントを読み込むときは集約したモジュールから読み込むだけ
importの記述がスッキリする!

src/pages/index.tsx
// スッキリ爽快
import { Header, Footer } from '@/components/Layout'

export const Top = () => {
  return (
    <>
      <Header />
      <h1>TOP</h1>
      <Footer />
    </>
  )
}

以上!!

何がうれしいのか

モジュールを集約しなかった時の場合importの記述が煩雑になる
コンポーネントが増えてくるとより恩恵を受けられそう。

src/pages/index.tsx
// モジュールを集約しなかったときの場合
import { Header } from '@/components/Layout/Header'
import { Footer } from '@/components/Layout/Footer'

export const Top = () => {
  return (
    <>
      <Header />
      <h1>TOP</h1>
      <Footer />
    </>
  )
}

注意点

export * from ...は名前付きエクスポートのみ有効になる

以下はバッドパターン

src/components/Layout/Header.tsx
const Header = () => {
 return <header>ヘッダー</header>
}

export default Header
index.ts
export * from './Header' // エラー。再エクスポートできない。

Tree Shaking 的にどうなん?

Tree Shakingre-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するだけで関数が勝手に実行されるライブラリだと怖いですけどね(そんなのある?)

参考資料

11
3
1

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
11
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?