ホーム自己紹介ブログ
NO.50
DATE2020. 08. 23

Ara-Framework で Micro Frontends with SSR

みなさん、こんにちは。silverbirder です。 私の最近の興味として、Micro Frontends があります。

Micro Frontends を学んだすべて
Micro FrontendsというWebフロントエンドアーキテクチャがあります。このアーキテクチャを知るために、書籍を読み、簡単なサンプルWebアプリを開発しました。そこから学んだことをすべて議事録として残したいと思います。
silverbirder.github.io

今、Ara-Framework というフレームワークを使った Micro Frontends のアプローチ方法を学んでいます。

Ara-Framework とは

Build Micro-frontends easily using Airbnb Hypernova

※ https://ara-framework.github.io/website/

Ara-Framework は、Airbnb が開発した Hypernova というフレームワークを使って、Micro Frontends を構築します。

Airbnb Hypernova とは

A service for server-side rendering your JavaScript views

※ https://github.com/airbnb/hypernova

簡単に説明すると、Hypernova はデータを渡せばレンダリング結果(HTML)を返却してくれるライブラリです。 これにより、データ構築とレンダリングを明確に分離することができるメリットがあります。

Ara-Framework アーキテクチャ

Ara-Framework のアーキテクチャ図は、次のようなものです。

ara framework overview
ara framework overview

※ https://ara-framework.github.io/website/docs/nova-architecture

構成要素は、次のとおりです。(↑ の公式ページにも説明があります)

  • Nova Proxy
    • ブラウザのアクセスを Layout へプロキシします。
    • Layout から返却された HTML をパースし、Hypernova のプレースホルダーがあれば、Nova Cluster へ問い合わせします。
    • Nova Cluster から返却された HTML を、Hypernova のプレースホルダーに埋め込み、ブラウザへ HTML を返却します。
  • Nova Directive (Layout)
    • 全体の HTML を構築します。Hypernova のプレースホルダーを埋め込みます。
    • Node.js, Laravel, Jinja2 が対応しています。
  • Nova Cluster
    • Nova Binding を管理するクラスタです。
    • Nova Proxy と Nova Bindings の間に位置します。
  • Nova Bindings (Hypernova)
    • データを渡されて、HTML をレンダリングした結果を返します。 (Hypernova をここで使います)
    • React, Vue.js, Angular, Svelte, Preact が対応しています。

このように、Layout と Rendering (Nova Bindings) を明確に分けることで、独立性、スケーラビリティ性が良いのかなと感じます。 各レイアの間にキャッシュレイヤを設けることでパフォーマンス向上も期待できます。

詳しくは、公式ページをご確認下さい。

Ara-Framework サンプルコード

Ara-Framework を実際に使ってみました。サンプルコードは下記にあげています。 https://github.com/silverbirder/micro-frontends-sample-code-2

package.json はこんな感じです。

package.json

  "scripts": {
    "cluster": "cd cluster && PORT=5000 ara run:cluster --config ./views.json",
    "layout": "cd layout && PORT=8080 node ./bin/www",
    "proxy": "cd proxy && HYPERNOVA_BATCH=http://localhost:5000/batch PORT=8000 ara run:proxy --config ./nova-proxy.json",
    "search:dev": "cd search && PORT=3000 ./node_modules/webpack/bin/webpack.js --watch --mode development",
    "product:dev": "cd product && PORT=3001 ./node_modules/webpack/bin/webpack.js --watch --mode development",
    "dev": "concurrently -n cluster,layout,proxy,search,product \"npm run cluster\" \"npm run layout\" \"npm run proxy\" \"npm run search:dev\" \"npm run product:dev\"",
  }

作っていく手順は、次の流れです。

  1. Nova Proxy を作成
  2. Nova Directive (Layout) を作成
  3. Nova Cluster を作成
  4. Nova Bindings (Hypernova) を作成

Ara-Framework を使うためには、次の準備をしておく必要があります。

npm i -g ara-cli

Nova Proxy

Nova Proxy は、Nova Directive へ Proxy しますので、その host を書きます。

nova-proxy.json

{
  "locations": [
    {
      "path": "/",
      "host": "http://localhost:8080",
      "modifyResponse": true
    }
  ]
}

また、Nova Proxy は、Nova Cluster へ問い合わせするため、HYPERNOVA_BATCH という変数に URL を指定する必要があります。 Nova Proxy を動かすときは、次のコマンドを実行します。

HYPERNOVA_BATCH=http://localhost:5000/batch PORT=8000 ara run:proxy --config ./nova-proxy.json

Nova Directive (Layout)

Nova Directvie は、hypernova-handlebars-directive を使います。 これは、Node.js の handlebars テンプレートエンジン(hbs)で使えます。

Express の雛形を生成します。

npx express-generator -v hbs layout

詳細は割愛しますが、次の HTML ファイル(hbs)を作成します。

※ 詳しくはこちら https://ara-framework.github.io/website/docs/render-on-page

layout/index.hbs

<h1>{{title}}</h1>
<p>Welcome to {{title}}</p>
 
{{>nova name="Search" data-title=title }}
 
<script src="http://localhost:3000/public/client.js"></script>
<script src="http://localhost:3001/public/client.js"></script>

{{>nova}} が Hypernova のプレースホルダーである hypernova-handlebars-directive です。 name は、Nova Bindings の名前 (後ほど説明します)、data-*は、Nova Bindings に渡すデータです。 また、script で client.js を load しているのは、CSR を実現するためです。

動かすのは、Express を動かすときと同じで、次になります。

PORT=8080 node ./bin/www

Nova Cluster

Nova Cluster は、Nova Bindings を管理します。

views.json

{
  "Search": {
    "server": "http://localhost:3000/batch"
  },
  "Product": {
    "server": "http://localhost:3001/batch"
  }
}

Search や Product は、後ほど作成する Nova Bindings の名前です。server は、Nova Bindings が動いている URL です。

Nova Cluster を動かすときは、次のコマンドを実行します。

PORT=5000 ara run:cluster --config ./views.json

Nova Bindings

Nova Bindings を作るために、次のコマンドを実行します。

ara new:nova search -t react
ara new:nova product -t vue

そこから、自動生成されたディレクトリから、少し修正したものが次のとおりです。

search/Search.jsx

import React, { Component } from 'react'
import { Nova } from 'nova-react-bridge'
 
class Search extends Component {
  render() {
      <div>
        <div>Search Components!</div>
        <table>
          <tr>
            {['🐙', '🐳', '🐊', '🐍', '🐷', '🐶', '🐯'].map((emoji, key) => {
              return <td key={key}>
                <Nova
                  name="Product"
                  data={{title: emoji}}/>
              </td>
            })}
          </tr>
        </table>
      </div>
  }
}

今までの説明ではなかったですが、Nova Bridge である nova-react-bridge を使っています。 これは、Nova Directive に似ているのですが、使えるファイルが React や Vue.js などの JS フレームワークに対応しています。 そのため、Nuxt.js や Next.js,Gatsby.js にも使えるようになります。

※ わかりにくいですが、このサンプルの Nova Bridge は、CSR で動作します。SSR で動作させるためには、Nova Proxy を挟む必要が (たぶん) あります。

product/Product.vue

<template>
  <div>{{title}}</div>
</template>
 
<script>
export default {
  props: ['title']
}
</script>

Nova Bindings のこれらを動作させるためには、次のコマンドを実行します。

## search
PORT=3000 ./node_modules/webpack/bin/webpack.js --watch --mode development
## product
PORT=3001 ./node_modules/webpack/bin/webpack.js --watch --mode development

動作確認

今まで紹介したものを同時に実行する必要があります。 そこで、concurrently を使います。

concurrently -n cluster,layout,proxy,search,product "npm run cluster" "npm run layout" "npm run proxy" "npm run search:dev" "npm run product:dev"

動作として、次のような画像になります。

nova results
nova results

最後に

繰り返しますが、Ara-Framework を使うとデータ構築(Nova Directive)とレンダリング(Nova Bindings)を明確に分離できます。 また、レンダリング部分は、それぞれ独立できます。今回紹介していない API 部分は、誰がどのように管理するのか考える必要があります。

ただ、Nova Bindings で使用する CSR 用 javascript は、重複するコードが含まれてしまい、ブラウザロード時間が長くなってしまいます。 そこで、webpack 5 から使えるようになった Federation 機能を使って解決するとった手段があります。

Ara-Framework の紹介でした!

バックエンド
フロントエンド
成果物

-

シェアする

フォローする

購読する

次のページ

Zalando tailor で Micro Frontends with ( LitElement & etcetera)

前のページ

Apache Beam + Kotlin 開発 実践入門

関連する記事

タグ「バックエンド」の記事

Storybook上で tRPC通信をMSWでモックする方法

はじめに tRPCは、型安全なAPIを簡単に構築できるフレームワークです。開発中、バックエンドの実装を待たずに、Storybook上でフロントエンドの開発を進めたい場合、Mock Service Worker (MSW) を使用してAPIのモックを行うことができます。この記事では、maloguertin/msw-trpc を用いて、tRPC通信をMSWでモックする方法について解説します。実用例として、サンプルコードをGitHubリポジトリ silverbirder/trpc-msw-storybook-nextjs で共有しています。

2024年03月07日

テスト
バックエンド
GraphQL Guildのエコシステムって便利だね

GraphQL Guild ってご存知ですか?GraphQL 界隈だと、Code Generator が有名と思いますが

2022年10月15日

バックエンド
Stable Diffusion API 開発

Stable Diffusion は、文章を渡すと画像を生成してくれる AI で OSS です。これを自前で動かそうとすると、GPU が必要になります。

2022年09月03日

AI
バックエンド
成果物

タグ「フロントエンド」の記事

iframeの難しさ

最近、iframeを使っています。 クライアントサイドで埋め込む想定で、iframeを使おうとしています。 色々と苦労したことがあったので、書いて残しておこうと思います。 レスポンスヘッダー 前提として、ウェブアプリケーションをプロダクショ

2026年02月18日

フロントエンド
ブラウザ
SVGを書くと数学の知識が必要だった

紙を積んだイラストをSVGで書こうとしていました。 (当たり前ですが)図形を表現するためには数学の知識が必要で、学生の頃の記憶を思い出したので疲れました。 所感について、諸々書こうと思います。 成果物 実際に完成したのは、以下の画像ができま

2026年02月17日

フロントエンド
CSSを、Vitestでテストしてみる

以下の記事で書いた CSSをテストする方法について、試してみました。 https://zenn.dev/silverbirder/articles/df6752b230f04c ソースコードは、以下に置いています。 https://gith

2026年02月10日

フロントエンド
テスト

タグ「成果物」の記事

記事投稿 連続100回以上している 私専用執筆環境Webアプリ

個人サイトリニューアルを機に、記事を書く執筆環境Webアプリを用意しました。 https://silverbirder.github.io/blog/contents/20260128/ どのようなものか簡単に紹介します。 入力とプレビュー

2026年02月20日

成果物
個人サイトリニューアルの振り返り

個人サイト(ジブンノート)をリニューアルしました。本記事では、個人サイトをリニューアルした際にあった出来事などを振り返りたいと思います。ちなみに、個人サイトは以下のページです。ノート風デザインで、ブログ記事が読めるようになりました!🎉

2026年01月29日

成果物
振り返り
個人サイトをリニューアルしました!

個人サイトをリニューアルしました!🎉 https://silverbirder.github.io リニューアルは、今回で6回目です。制作期間は、去年の12月27日から今年の1月28日までの約1ヶ月間です。個人的には最速の開発期間でした。AIの力は偉大ですね。本記事では、個人サイトのリニューアルでこだわったポイントについて紹介します。

2026年01月28日

成果物
← ブログ一覧へ