お久しぶりです、Geolonia 小林です!
今回のトピックですが、 MapLibre / Mapbox GL のスタイルを編集するツール maputnik
の翻訳の仕組み導入について書こうと思います。
Geolonia は一般的なウェブサイトに地図を埋め込むツールとして最初立ち上げました。当時は日本のみならず、英語エリアもサービス提供したいと思ってサービスの管理画面を多言語対応するようにしていました(私がジョインする前の頃ですが笑)。そのときは、開発者が WordPress の開発に慣れていたので、 WordPress で使っている @wordpress/i18n
を選択しました。
WordPress の PHP バックエンドは、昔から GNU gettext を利用しています。 gettext で使う PO ファイルを管理、生成したりするパイプラインや、そのプロセスに慣れているボランテイアの翻訳者が大勢いたため、 JavaScript の利用が多くなったときに JavaScript でも gettext と同様に開発できるように、先程の @wordpress/i18n
が作られました。
利点としては翻訳ツールや翻訳用ストリングを抽出するツールのエコシステムが豊富(例えば、 Poedit というエディタは自動翻訳からプロジェクトごとの翻訳メモリ、20年以上前から開発してきている)
ただ、弱点としてはライセンスが GPL だ。 JavaScript の世界は、 MIT または ISC ライセンスが多く、 GPL との相性があまり良くなく、特にライブラリに GPL ライセンスを導入することはほぼ無理。
2021年から「翻訳できますか?」という課題がずーとオープンし、maputnikのメンテナーの一人が react-i18next
はいかがでしょう?というところからヒントをもらいました。
調べたら、 React との相性がとても良くて、クラスコンポーネントや関数コンポーネント、React外のコードでも簡単に使える。個人的に魅力的だったところは拡張性でした。例えばブラウザで稼働する前提なら i18next-browser-languageDetector
や、翻訳ファイルを外部サービスでホスティングしたり、翻訳されていないストリングを検知したときにサーバーにお知らせする拡張など、エコシステムが揃っています。
react-i18next
の導入基本的に “Step by step guide” をそのまま上から下に使いました。
i18n.ts
ファイルを作成し、基本的な設定を行う。一番最初では、テスト用に翻訳ストリングをすべてそのままハードコードしました。withTranslation
の Higher-Order Component (HOC) でラッピングしました。t
関数でラッピングした。例えば、 <a href="..">Help</a>
の箇所は、 <a href="..">{t("Help")}</a>
というように変更。import { WithTranslation, withTranslation } from 'react-i18next';
type MyComponentInternalProps = {
...
} & WithTranslation;
class MyComponentInternal extends React.Component<MyComponentInternalProps> {
render() {
const t = this.props.t;
return <a href="..">{t("Hello!")}</a>;
}
}
const MyComponent = withTranslation()(MyComponentInternal);
export default MyComponent;
const MyComponent: React.FC<MyComponentProps> = () => {
const { t } = useTranslation();
return <a href="..">{t("Hello!")}</a>;
};
export default MyComponent;
先ほどリンクした HOC のドキュメンテーション ではクラスコンポーネントがもう推奨されていなくて、関数コンポーネントを推奨します、と書いてあるのでそのうちマイグレーションしていきたいと思っています。 react-i18next
も、関数コンポーネントの方の書き方もシンプルになります。
maputnik は単体テストも導入されていますが、 エンド・ツー・エンド(E2E)テストも含まれています。翻訳機能も、E2Eテスト対象となるので、翻訳切り替え等のテストも追加しております。 maputnik は cypress というE2Eテストフレームワークを導入していて、初めて使ったので合わせて感想を書きます。
cypress のサイトの表紙にある動画通り、ローカルでテスト実行するときは実際の画面を見ることができます。また、それぞれのテストの中にステップ等ありますが、失敗あるときにそれぞれのステップを見ることができ、「失敗したときの画面」「どこで失敗した」が非常にわかりやすい。
現在 Geolonia の社内プロジェクトではいくつかのテストフレームワークを puppeteer とつなぎ合わせてE2Eテストを実施したりしているのですが、今後 cypress を導入したいと思いました。
現在、プルリクがまだ作成途中です!翻訳ストリングを追加したり、手伝いたいなら声をかけてください!プルリクがマージされたら、他の言語もどんどん追加していきましょう。