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

Ara-Framework で Micro Frontends with SSR

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

Micro Frontends を学んだすべて

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

ジブンノート

今、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

※ 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

最後に

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

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

Ara-Framework の紹介でした!

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

-

読者になる

|

シェアする

|

silverbirders

silverbirder

Webソフトウェアエンジニア
個人ブログキュレーション こぶりー 運営

ブログを応援する

この記事がよかったら、お布施という形で応援してもらえるとうれしいです。

おふせぼたん

※ ログイン不要で投稿できます。

※ 同じブラウザから投稿を削除できます。

0

読み込み中...

次の記事へ前の記事へ

関連する記事

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

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
バックエンド
成果物

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

モジュールアップデートでやっていること

ITヲタクな AI くんにピッタリな仕事の一つは、モジュールアップデート。 特に、メジャーアップデートが超助かる。 昔だったら 数ヶ月掛かった移行も、数日たらずに対応できるようになったので、 さすが ITヲタクくん。 対応してよかったフロー

2026年07月24日

AI
フロントエンド
写経テストコードを全部消した

以下で書いた通り、プロダクトコードを写経したテストコードを削除しました。 "こぶりー" ( https://kobliy.vercel.app/ ) という個人ブログを読むアプリのコードです。 https://silverbirder.gi

2026年06月08日

AI
フロントエンド
テスト
念の為に、手動確認をしよう

最近のお悩みは、Webのソフトウェア開発におけるテストコードが爆増したことにより、 テスト成功による過度な安心感 によって手動確認するのが減っているのかもと思ったりしています。 例えば、Webのフォーム画面に小さな改修があったとして、その修

2026年06月03日

AI
フロントエンド

タグ「成果物」の記事

GitHub Busy をアラームの様に登録したい

仕事柄、GitHub Busy を設定しています。 この Busy には有効期限を GUI 上で登録することができます。 GitHub Busy 編集画面 困っていること 毎週水曜日に Busy を設定していて、木曜日に解除しています。 こ

2026年06月19日

成果物
個人ブログを読むアプリ、こぶりーをリリースしました!

個人ブログ好きの皆さんに朗報です! "個人ブログを、見つけて、読んで、シェアする" アプリ、こぶりーをリリースしました!🎉 こぶりー アプリのURLは、以下の通りです。 こぶりー - kobliy.vercel.app こちらから、個人ブ

2026年05月23日

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

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

2026年02月20日

成果物
← ブログ一覧へ