AWS AmplifyプルリクエストWebプレビューをLINEミニアプリでもやってみた

AWS AmplifyプルリクエストWebプレビューをLINEミニアプリでもやってみた

Clock Icon2025.06.24

はじめに

こんにちは!

アノテーション株式会社 LINE / アプリ DevOpsチーム の草竹です。

AWS Amplifyの プルリクエストの Web プレビューは便利ですよね!

https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/pr-previews.html

GitHub プルリクエストごとにWeb上にデプロイできるので、コードレビューの際にWeb上での動作確認がとってもお手軽になります。

今回はLINEミニアプリ開発の文脈で、このAmplifyのプレビュー機能を活用してみました!

リポジトリを公開しておりますので、あわせて参照ください。

https://github.com/D-ske104/devio-liffmock-amplify

関連用語

  • LINEミニアプリ
  • LIFF Mock
  • AWS Amplify
  • Vite
  • Subpath imports

材料

AWS Amplify プルリクエストのWebプレビュー

AWS Amplify には GitHubのプルリクエストごとにそのブランチ内容でデプロイ、ホスティングする プルリクエストの Web プレビュー 機能があります。

https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/pr-previews.html

この機能を使えば、プルリクエストで開発中の成果物をデプロイさせて動作確認することが可能です。
ローカルビルドせずともよくなるため、手間が減るのはもちろん、開発者間でのビルド環境の差異を吸収できたりとっても便利です。

プレビューURLは pr-2.************.amplifyapp.com pr-17.************.amplifyapp.com のようにプルリクエストごとに一意のサブドメインで発行されます。

LINEミニアプリ

LINEミニアプリはチャネルごとに「開発用」「審査用」「本番用」の3つの環境があり、エンドポイントURLは各環境1つのみ設定可能です。

環境 エンドポイントURL
開発用 https://developers.line.biz/assets/liff-default-dev.html
審査用 https://developers.line.biz/assets/liff-default-review.html
本番用 https://developers.line.biz/assets/liff-default-published.html

プルリクエスト単位でWebプレビューURLを発行する際、環境チャネルごとにエンドポイントURLが1つのみに定められているこの仕様とコンフリクトします。

AmplifyのプレビューURLは pr-2.************.amplifyapp.com pr-17.************.amplifyapp.com のようなプルリクエストごとのサブドメインで発行されるため、LINEミニアプリの開発用チャネルのエンドポイントに複数個のプルリクエストプレビューURLを設定できません。

LINEアカウントへのログイン liff.login() 成功時にはエンドポイントURLへリダイレクトされるため、LINEログインを前提とするアプリケーションの検証にプレビュー環境を利用するのはハードルがあります。

LIFF Mock

LIFF Mock は 公式プラグインの1つです。
公式プラグインのLIFF Mockは liff.login() をはじめとするLIFF APIのふるまいをモック化することが可能です。

LINE Developers ドキュメント より引用

LIFF Mockは、LIFFアプリのテストを簡単にするためのLIFFプラグインです。LIFF Mockを使うと、LIFF SDKにモックモードを追加できます。モックモードでは、LIFFアプリがLIFFサーバーから独立し、LIFF APIがモックデータを返すため、単体テストや負荷テストをより簡単に行うことができます。

https://github.com/line/liff-mock

liff.login() をモック化することで、ローカル環境など、設定されたエンドポイントURLではない環境であってもログイン状態を再現することが可能です。

LIFF Mockでログイン処理をモック化することで、プルリクエスト単位で発行されるプレビューURL上でLINEミニアプリの動作確認をしてみましょう。

手順

LIFFアプリプロジェクトの作成

LIFFアプリのひな形を作成しましょう。Create LIFF Appが簡単です。

https://developers.line.biz/ja/docs/liff/cli-tool-create-liff-app/

npm create @line/liff-app liff-mock-amplify
cd liff-mock-amplify
.
├── index.html
├── package-lock.json
├── package.json
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── favicon.ico
│   ├── main.tsx
│   └── vite-env.d.ts
├── tsconfig.json
└── vite.config.ts

LIFF Mockのインストール

LIFF Mockのセットアップをします。

手順はLIFF MockのGitHubにも詳しいです。

https://github.com/line/liff-mock?tab=readme-ov-file#npm

npm i @line/liff-mock

liff.init() を拡張する型定義ファイルを作成します。

src/liff.d.ts
import { ExtendedInit, LiffMockApi } from "@line/liff-mock";

declare module "@line/liff" {
  interface Liff {
    init: ExtendedInit;
    $mock: LiffMockApi;
  }
}

liff.init({ mock: true }) とすることでLIFF APIがモックモードになります。

liff.init() のオプション値を何らかの条件で分岐させれば良いですが、liff.init() のラッパーをモック用と非モック用の2つを作り、ビルド時に分岐させてみることにします。
呼び出すべきファイルを選択する条件には subpath imports を使ってみます。

https://nodejs.org/api/packages.html#subpath-imports

src/lib/liff-init/index.ts
import { liff } from "@line/liff";

export const liffInit = async () => {
  await liff
    .init({
      liffId: import.meta.env.VITE_LIFF_ID || "",
      withLoginOnExternalBrowser: true,
    })
};
src/lib/liff-init/index.mock.ts
// LIFF Mock
import { liff } from "@line/liff";
import LiffMockPlugin from "@line/liff-mock";

// モックデータ
import { getProfile } from "./mocks";

export const liffInit = async () => {
  try {
    // モックプラグインを設定
    liff.use(new LiffMockPlugin());

    // LIFFを初期化(モックを有効化)
    await liff.init({
      liffId: import.meta.env.VITE_LIFF_ID || "mock-liff-id",
      mock: true,
    });

    // ブラウザ環境ではログイン処理が必要
    if (!liff.isInClient()) {
      liff.login();
    }

    // モックデータを設定
    liff.$mock.set({
      getProfile,
    });

    console.debug("LIFF initialization completed (mock)");
  } catch (error) {
    console.error("LIFF mock initialization failed:", error);
    throw error;
  }
};

subpath imports を使って特定条件下でのみモックファイルをインポートさせるようにします。
package.jsonを変更します。

package.json
{
  "imports": {
    "#src/lib/liff-init": {
      "pull_request_preview": "./src/lib/liff-init/index.mock.ts",
      "default": "./src/lib/liff-init/index.ts"
    },
    "#*": [
      "./*",
      "./*.ts",
      "./*.tsx"
    ]
  }
}

liffInit() の呼び出し側では package.json に記載した #src/lib/liff-init パスでインポートします。

src/App.tsx
import { useEffect, useState } from "react";
import "./App.css";

import { liffInit } from "#src/lib/liff-init";

function App() {
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");

  useEffect(() => {
    liffInit()
      .then(() => {
        setMessage("LIFF init succeeded.");
      })
      .catch((e: Error) => {
        setMessage("LIFF init failed.");
        setError(`${e}`);
      });
  }, []);
  return (
    <div className="App">
      <h1>create-liff-app</h1>
      {message && <p>{message}</p>}
      {error && (
        <p>
          <code>{error}</code>
        </p>
      )}
      <a
        href="https://developers.line.biz/ja/docs/liff/"
        target="_blank"
        rel="noreferrer"
      >
        LIFF Documentation
      </a>
    </div>
  );
}

export default App;

AWS Amplifyのプルリクエストプレビューの場合にモックモードをONにしたいので、モック用のビルドコマンドを用意することにしましょう。

npm run build:mock で Viteのモードを "mock" として設定することとします。

package.json
{
  "scripts": {
    "dev": "vite",
    "build:mock": "tsc && vite build --mode=mock",
    "build": "tsc && vite build"
  },
}

"mock" モードの場合は resolve.conditions に mock を追加します。
conditions が mock となることで、package.json に設定した mock 条件のファイルを呼び出すことになります。

vite.config.ts
import { defineConfig, defaultClientConditions } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig(({ mode }) => {
  // プルリクエストプレビューの場合はモックを使用する
  const shouldUseMock = mode === 'mock'

  const conditions = shouldUseMock ? [
    ...defaultClientConditions,
    "mock"
  ] : undefined;

  return {
    plugins: [react()],
    resolve: {
      conditions
    },
  }
});

AWS Amplifyの設定

AWS Amplifyの設定ファイルを作成します。
プルリクエストプレビューは pr-* 形式のブランチ名となるため、 pr-* ではビルドコマンドに npm run build:mock を使用するように記述します。

amplify.yml
version: 1
frontend:
    phases:
        preBuild:
            commands:
                - 'npm ci --cache .npm --prefer-offline'
        build:
            commands:
                - |
                  case "${AWS_BRANCH}" in
                      pr-*)
                          echo "Building pull request preview in development mode..."
                          npm run build:mock
                          ;;
                      *)
                          echo "Building production..."
                          npm run build
                          ;;
                  esac
    artifacts:
        baseDirectory: dist
        files:
            - '**/*'
    cache:
        paths:
            - '.npm/**/*'

https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/environment-variables.html

AmplifyアプリをAWSマネジメントコンソールから作成します。

amplify-1

プレビュー環境では、Basic認証やIP制限を設定し、関係者以外のアクセスを制限してください。

amplify-4

プレビュー設定を行います。

amplify-3

動作確認

これで設定完了です!

GitHubでプルリクエストを作成すると、AWS Amplifyでプレビュー環境がデプロイされるはずです。
プルリクエストを作成してみましょう。

amplify-5

プレビュー環境がデプロイされ、LIFF APIもモック化されていますね!

amplify-6

まとめ

今回は、AWS AmplifyのプルリクエストのWebプレビューをLINEミニアプリにも使うためにLIFF Mockを活用してみました。

また、モック化する条件分岐に subpath imports を使用してみました。
ローカル環境でもモック化する場合には vite のモードは既定の development を利用しても良いかもしれません。

プレビュー環境ではLIFF APIはLIFF Mockによってモック化された状態であることをご承知のうえ、結合テストは正規の開発チャネルにて実施するなど、みなさまのアプリケーションの特性に応じてご参考いただけますと幸いです。

アノテーション株式会社 LINE / アプリ DevOpsチーム の草竹でした!

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。
サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイト をぜひご覧ください。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.