目次
- LIFFとは
- LIFF Mock活用前のコード
- 抱えていた問題
- 解決に用いたLIFF Mockとは
- 解決方法
- まとめ
LIFFとは
LINE Front-end Frameworkの略です。
LINEが提供するウェブアプリのプラットフォーム
と公式リファレンスに記載ありました。また、
このプラットフォームで動作するウェブアプリを、LIFFアプリと呼びます
とあるので、以降はLIFFアプリという名称も使っていきたいと思います。
LIFFアプリでは、LINEのユーザーIDなど、LINEの持つ情報を活用して、機能を作ることができます。
LIFF Mock活用前のコード
React × TypeScriptで作ったアプリをNetlifyにHostingして、それをLIFFアプリとして公開しています。
LIFFアプリを作る時、ユーザーへwebページを表示する前に、LINEログインをしてもらうようにしました。それが以下のコードです。(本筋とは関係ないChakraのコードが混じっています。。すみません。 )
import React from 'react';
import {createRoot} from 'react-dom/client';
import './index.css';
import App from './App';
import {extendTheme, ChakraProvider} from '@chakra-ui/react';
import liff from '@line/liff';
const colors = {
brand: {
900: '#1a365d',
800: '#153e75',
700: '#2a69ac',
},
};
export const theme = extendTheme({colors});
const liffId = 'liffId'; // 個々のLIFFIDになります
liff
.init({liffId})
.then(async () => {
if (!liff.isLoggedIn()) {
await liff.login();
}
root.render(
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>
);
return;
})
.catch((e) => {
alert(`LIFF error: ${e.message}`);
});
抱えていた問題
これでは yarn start
をしてlocalhostでページを開きLINEログインすると、本番環境にリダイレクトしてしまいます。(イメージは以下です)
今のままだと、ログイン後の画面の実装をしたとしても確認方法は
- LINEログインの機構をコメントアウトする
- storybookでコンポーネント単位で見た目を整えていく
など手間がかかったり、局所的な解決しかできなかったです。
(僕の調べ方が甘かったりはするかも。。)
理想の挙動はlocalhostにリダイレクトされて欲しいです。(イメージは以下です)
解決に用いたLIFF Mockとは
ここでは上記の問題を、LIFF Mockを用いて解決します。
LIFF Mockとは
LIFFアプリのテストを簡単にするためのLIFFプラグイン
です。また、
LIFFアプリがLIFFサーバーから独立し、LIFF APIがモックデータを返すため、単体テストや負荷テストをより簡単に行うことができます
とあるので、テストの際に使われることを想定したプラグインだと考えられます。
今回僕はこのLIFF Mockを開発環境で用いて、以下のような構成にしてみました。
解決方法手順
手順は
- liff-mockをインストール
- 本番環境以外はLiffMockPluginを使用する
- 環境変数を生成する
- liff.initしてからレンダリング処理を行う
です。では、順を追ってみていきます。
liff-mockをインストール
$ yarn add @line/liff-mock
なお、
LIFF Plugin feature is available since LIFF SDK v2.19.0.
とあるように、LIFF Mockを使用するには、LIFF SDKをv2.19.0以上にあげる必要があります。
本番環境以外はLiffMockPluginを使用する
コードは以下になります。
if (process.env.NODE_ENV !== 'production') {
liff.use(new LiffMockPlugin());
// https://github.com/line/liff-mock
}
環境変数を生成する
export const generateEnv = () => {
let liffId: string;
let mock: boolean;
switch (process.env.NODE_ENV) {
case 'production':
liffId = process.env.REACT_APP_LIFF_ID ?? '';
mock = false;
break;
case 'development':
case 'test':
liffId = 'dummyId';
mock = true;
break;
}
return {liffId, mock};
};
const {liffId, mock} = generateEnv();
generateEnv
という関数を用いて、各環境の変数を定義しましたが、ここは環境別に用意できればなんでも良いです。
mockに関しては、本番環境ではfalse、開発環境ではtrueになるようにします。
liff.initしてからレンダリング処理を行う
liff.init時にmock modeにするかどうかを指定します。
liff
.init({liffId, mock}) // mockをliff.init時に渡している
.then(async () => {
if (!liff.isLoggedIn()) {
await liff.login();
}
root.render(
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>
);
return;
})
.catch((e) => {
alert(`LIFF error: ${e.message}`);
});
これで、本番環境は実際のLINEのサーバーと通信をし、開発環境ではLINEのモックサーバーと通信をするようになります。
最終的なコード
最終的にはこうなります。
import React from 'react';
import {createRoot} from 'react-dom/client';
import './index.css';
import App from './App';
import {extendTheme, ChakraProvider} from '@chakra-ui/react';
import liff from '@line/liff';
import LiffMockPlugin from '@line/liff-mock';
import {generateEnv} from './generateEnv';
const colors = {
brand: {
900: '#1a365d',
800: '#153e75',
700: '#2a69ac',
},
};
export const theme = extendTheme({colors});
const root = createRoot(document.getElementById('root') as HTMLElement);
if (process.env.NODE_ENV !== 'production') {
liff.use(new LiffMockPlugin());
// https://github.com/line/liff-mock
}
const {liffId, mock} = generateEnv();
liff
.init({liffId, mock})
.then(async () => {
if (!liff.isLoggedIn()) {
await liff.login();
}
root.render(
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>
);
return;
})
.catch((e) => {
alert(`LIFF error: ${e.message}`);
});
まとめ
これで、開発環境と本番環境の差分を気にしなくて良くなりました!
しかし、まだ開発初期なので、今後この解決方法が役に立たなくなる時が来るかもしれません。その時は懺悔の記事を書きますのでお楽しみに(?)しておいていただけると幸いです