
AWS AmplifyプルリクエストWebプレビューをLINEミニアプリでもやってみた
はじめに
こんにちは!
アノテーション株式会社 LINE / アプリ DevOpsチーム の草竹です。
AWS Amplifyの プルリクエストの Web プレビューは便利ですよね!
GitHub プルリクエストごとにWeb上にデプロイできるので、コードレビューの際にWeb上での動作確認がとってもお手軽になります。
今回はLINEミニアプリ開発の文脈で、このAmplifyのプレビュー機能を活用してみました!
リポジトリを公開しておりますので、あわせて参照ください。
関連用語
- LINEミニアプリ
- LIFF Mock
- AWS Amplify
- Vite
- Subpath imports
材料
AWS Amplify プルリクエストのWebプレビュー
AWS Amplify には GitHubのプルリクエストごとにそのブランチ内容でデプロイ、ホスティングする プルリクエストの Web プレビュー 機能があります。
この機能を使えば、プルリクエストで開発中の成果物をデプロイさせて動作確認することが可能です。
ローカルビルドせずともよくなるため、手間が減るのはもちろん、開発者間でのビルド環境の差異を吸収できたりとっても便利です。
プレビュー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のふるまいをモック化することが可能です。
LIFF Mockは、LIFFアプリのテストを簡単にするためのLIFFプラグインです。LIFF Mockを使うと、LIFF SDKにモックモードを追加できます。モックモードでは、LIFFアプリがLIFFサーバーから独立し、LIFF APIがモックデータを返すため、単体テストや負荷テストをより簡単に行うことができます。
liff.login()
をモック化することで、ローカル環境など、設定されたエンドポイントURLではない環境であってもログイン状態を再現することが可能です。
LIFF Mockでログイン処理をモック化することで、プルリクエスト単位で発行されるプレビューURL上でLINEミニアプリの動作確認をしてみましょう。
手順
LIFFアプリプロジェクトの作成
LIFFアプリのひな形を作成しましょう。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にも詳しいです。
npm i @line/liff-mock
liff.init()
を拡張する型定義ファイルを作成します。
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 を使ってみます。
import { liff } from "@line/liff";
export const liffInit = async () => {
await liff
.init({
liffId: import.meta.env.VITE_LIFF_ID || "",
withLoginOnExternalBrowser: true,
})
};
// 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を変更します。
{
"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
パスでインポートします。
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" として設定することとします。
{
"scripts": {
"dev": "vite",
"build:mock": "tsc && vite build --mode=mock",
"build": "tsc && vite build"
},
}
"mock" モードの場合は resolve.conditions に mock を追加します。
conditions が mock となることで、package.json に設定した mock 条件のファイルを呼び出すことになります。
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
を使用するように記述します。
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/**/*'
AmplifyアプリをAWSマネジメントコンソールから作成します。
プレビュー環境では、Basic認証やIP制限を設定し、関係者以外のアクセスを制限してください。
プレビュー設定を行います。
動作確認
これで設定完了です!
GitHubでプルリクエストを作成すると、AWS Amplifyでプレビュー環境がデプロイされるはずです。
プルリクエストを作成してみましょう。
プレビュー環境がデプロイされ、LIFF APIもモック化されていますね!
まとめ
今回は、AWS AmplifyのプルリクエストのWebプレビューをLINEミニアプリにも使うためにLIFF Mockを活用してみました。
また、モック化する条件分岐に subpath imports を使用してみました。
ローカル環境でもモック化する場合には vite のモードは既定の development を利用しても良いかもしれません。
プレビュー環境ではLIFF APIはLIFF Mockによってモック化された状態であることをご承知のうえ、結合テストは正規の開発チャネルにて実施するなど、みなさまのアプリケーションの特性に応じてご参考いただけますと幸いです。
アノテーション株式会社 LINE / アプリ DevOpsチーム の草竹でした!
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。
サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイト をぜひご覧ください。