Help us understand the problem. What is going on with this article?

webpack 5 の webpack federation という概念について

注意: まだHEADにすらマージされていない機能です。

僕の現状の理解で書いてます。細かいニュアンスは見落としてるかも。

今の課題

  • 異なるチームで、異なるビルドプロセスのものを統合するような巨大なフロントエンド、いわゆるマイクロなフロントエンドやってると、同じようなライブラリが内部的に重複するよね
  • webpack build (chunk) 間で、そういう自明なもののを重複を省いたり、一方向ではなく、相互に読み出せるようにしたいよね

ScriptedAlchemy氏の提案

異なるWebpackビルド同士が連携する、Federation という概念を作る。

  • Host と Remote という概念を追加する。既存のものは Host となる(?)。 Remote は、それぞれに要求する chunk (react, vue など)と、他に外側に提供するインターフェースを明示する。
  • (optimazation をしないビルドの場合?) 読み込まれるライブラリの内部に、どの node_module から構成されたかの chunk.id を、ヒントとして残す。これらは tree shake できるように、ESM の方式でインターフェースを残す。
  • どのような経路から読み込まれたとしても、複数の webpack build から同一 chunk.id のものが読み込まれた時、インスタンスは共有される(注: ちょっと自信がない。ランタイムの話か、ビルドステップの話なのか)
  • それぞれのビルドチャンクごとに、異なる publicPath を持てる

個人的には、異なる publicPath というのが大きい気がする。様々なホストから提供されるアプリ同士を連携できるようになる)ので。

npm わかってる人向けの要約

つまりは webpack federation を使えば、 webpack build (chunk) の水準で、peerDependencies 的な振る舞いが設定できるという話だと自分は理解した。

実際に動いているところ

https://github.com/mizx/mfe-webpack-demo

これを clone して動かしてみるのが一番理解が早かった。

packages/app-01/webpack.config.js
// plugins
    new ModuleFederationPlugin({
      name: "app_01",
      library: { type: "var", name: "app_01" },
      filename: "remoteEntry.js",
      remotes: {
        app_02: "app_02",
        app_03: "app_03"
      },
      exposes: {
        SideNav: "./src/SideNav",
        Page: "./src/Page"
      },
      shared: ["react", "react-dom", "@material-ui/core", "react-router-dom"]
    }),
packages/app-02/webpack.config.js
// plugins
    new ModuleFederationPlugin({
      name: "app_02",
      library: { type: "var", name: "app_02" },
      filename: "remoteEntry.js",
      remotes: {
        app_01: "app_01",
        app_03: "app_03"
      },
      exposes: {
        Dialog: "./src/Dialog",
        Tabs: "./src/Tabs"
      },
      shared: ["react", "react-dom", "@material-ui/core", "react-router-dom"]
    }),
packages/app-03/webpack.config.js
    new ModuleFederationPlugin({
      name: "app_03",
      library: { type: "var", name: "app_03" },
      filename: "remoteEntry.js",
      remotes: {
        app_01: "app_01"
      },
      exposes: {
        Button: "./src/Button"
      },
      shared: ["react", "react-dom"]
    }),

これを動かす packages/app-01 の HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="http://localhost:3002/remoteEntry.js"></script>
    <script src="http://localhost:3003/remoteEntry.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
<!-- html-plugin によって、app-01 の remoteEntry も挿入される -->

これで、相互に読み出しながら、react 等のインスタンスを共有しながら実行される

まだちょっとよくわかってないところ

  • ビルド時の話なのか、ランタイムのときの話なのかが、自分はまだ混乱してるかも
  • だれが明示的にチャンクを持つのか、指定できる? 複数にまたがる vendor chunk 的なものを作れるのか?

利点

マイクロフロントエンドのパフォーマンス上のメリットは↑の通り。

それ以外に、もっとエコシステム的な観点がある気がしていて、現在のフロントエンドライブラリは、 npm パッケージとして読み込み、特定のローダーで展開することを期待するようなライブラリ(style-loader, worker-loaderを前提とするようなやつ。例えば monaco-editor)があることが多いが、それが既存の設定とバッティングしたり、期待するwebpackのバージョンと一致しなくなったりして、動かせないことがある。

webpack federation が普及すれば、一つの振る舞いをする webpackのビルドチャンクが一塊になることで、他のwebpack設定から読み込ませつつ、 他の loader と干渉しないようなものとして、ビルドを提供できる。

つまりは、一つの振る舞いを持つUIコンポーネントという単位で、ビルド済みのものを配布しやすくなる。作者はそういうエコシステムを思い描いている気がする。

参考

ここまで理解したが、ちょっとまだ自分もふわっとしてるので、コメントなどで教えてほしいです。

plaid
CXプラットフォーム「KARTE」の開発・運営、EC特化型メディア「Shopping Tribe」の企画・運営、CX特化型メディア「XD(クロスディー)」の企画・運営
https://plaid.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした