🐫

【Flutter】4つの多言語化パッケージを試してみた【徹底比較】

2022/04/22に公開
1

はじめに

Flutter アプリを多言語化するパッケージがいくつもあってどれを採用すればよいのか迷ったので色々試してみました!

今回比較したのは次の 4 つです。最後に まとめ もありますので参考にしてください。すべてサンプルコードつきです。

結論

私の一押しは fast_i18n です!context 不要で定数アクセスできるのが最高です!パッケージ名は好みじゃないんですが😅
次点は flutter_localizations です!

それでは個々についてみていきましょう。

flutter_localizations

https://docs.flutter.dev/development/accessibility-and-localization/internationalization

使い方

lib/l10n/app_en.arb
{
  "@@locale": "en",
  "title": "Flutter Sample Localizations",
  "@title": {
    "description": "This is Comments."
  },
  "message": "You have pushed the button this many times: {count}",
  "@message": {
    "description": "引数を与えることは出来るけど名前付き引数になりません。",
    "placeholders": {
      "count": {
        "type": "int",
        "format": "compact"
      }
    }
  }
}
lib/l10n/app_ja.arb
{
  "@@locale": "ja",
  "title": "多言語化サンプル",
  "message": "ボタンを押した回数: {count}"
}

@@locale で言語を指定します。description はコメントです。placeholders で引数の型やフォーマットを指定できます。指定しない場合は Object 型になります。

リソースへのアクセス方法
AppLocalizations.of(context)!.title; // => '多言語化サンプル'
AppLocalizations.of(context)!.message(_counter); // => 'ボタンを押した回数: 10'

良いところ

  • SDK 標準の機能なのでメンテナンスされなくなるリスクがなく安心して使える
  • 導入方法を解説した日本語の記事が多い
  • リソースに定数でアクセスできる
  • リソースファイル形式に ARB が使える唯一の方法

悪いところ

  • リソースファイル形式が ARB のみ
  • リソースファイル内で別のリソースを参照できない
  • リソースにアクセスするときに context が必要
  • Android Studio で 自動生成ファイルがエラー表示になる(赤い下線がつく)
    • ビルドは通るので Android Studio のバグと思われるが、ものすごく気になる
    • 以下のように l10n.yaml ファイルに synthetic-package: false と指定して、自動生成ファイルを .dart_tool ではなく lib 配下に生成すれば解消する

https://github.com/susatthi/flutter-sample-localizations/blob/ba4e377754540eb63d21e72542356aec355dc51a/l10n.yaml#L6

導入方法

https://flutter.salon/flutter/l10n/
https://techgamelife.net/2021/10/21/flutter-simple-localization/
https://qiita.com/yukihiroK/items/d431036401ae5bbc06f9

サンプルコード

https://github.com/susatthi/flutter-sample-localizations

fast_i18n

https://pub.dev/packages/fast_i18n

使い方

lib/i18n/strings_ja.i18n.json
{
  "sample": {
    "title": "多言語化サンプル",
    "message": "[@:sample.title] ボタンを押した回数: $count",
    "@message": "これはコメントです"
  }
}

@:<リソース名> で他リソースを参照できます。リソース名の先頭に @ を付けるとコメント扱いになります。引数は $count の他に {count}{{count}} にすることもできます。

リソースへのアクセス方法
t.sample.title; // => '多言語化サンプル'
t.sample.message(count: _counter); // => '[多言語化サンプル] ボタンを押した回数: 10'

名前付き引数で値を与えます。グローバルインスタンスの t は設定で別名に変更できます。

lib/i18n/strings_ja.i18n.yaml
sample:
  title: '多言語化サンプル' # これはコメントです。
  message: '[@:sample.title] ボタンを押した回数: $count'

YAML 形式で書くことも出来ます。

lib/i18n/sample.i18n.csv
key,(comments),en,ja
title,これはコメントです。,Flutter Sample Localizations,多言語化サンプル
message,コメントはコメントとして出力されます。,[@:sample.title] You have pushed the button this many times: $count,[@:sample.title] ボタンを押した回数: $count

CSV 形式で書くことも出来ます。1行目の言語名を () にするとその列はコメント扱いにできます。

良いところ

  • README が充実していて導入が容易
  • リソースの名前空間[1]に対応している
  • リソースファイル形式が豊富(JSON / YAML / CSV)
  • リソースを List 形式や Map 形式で定義できる
  • リソースにアクセスするときに context が不要
  • リソースに定数でアクセスできる
  • リソースにアクセスするとき名前付き引数が使える
  • メンテナンスが頻繁に行われている

悪いところ

  • 事前の build_runner が必要

導入方法

https://qiita.com/popy1017/items/3495be9fdc028161bef9

サンプルコード

https://github.com/susatthi/flutter-sample-fast-i18n

easy_localization

https://pub.dev/packages/easy_localization

使い方

assets/translations/ja-JP.json
{
  "sample": {
    "title": "多言語化サンプル",
    "message": "[@:sample.title] ボタンを押した回数: {count}"
  }
}

@:<リソース名> で他リソースを参照できます。

リソースへのアクセス方法
'sample.title'.tr(); // => '多言語化サンプル'
'sample.message'.tr(
  namedArgs: {
    'count': '$_counter',
  },
);
// => '[多言語化サンプル] ボタンを押した回数: 10'
assets/translations/ja-JP.yaml
sample:
  title: '多言語化サンプル' # これはコメントです。
  message: '[@:sample.title] ボタンを押した回数: {count}'

YAML 形式で書くことも出来ます。

assets/translations/ja-JP.xml
<?xml version="1.0" encoding="utf-8" ?>
<strings>
    <sample.title>多言語化サンプル</sample.title>
    <sample.message>[@:sample.title] ボタンを押した回数: {count}</sample.message>
</strings>

XML 形式で書くことも出来ます。

assets/translations/strings.csv
key,en_US,ja_JP
sample.title,Flutter Sample Localizations,多言語化サンプル
sample.message,[@:sample.title] You have pushed the button this many times: {count},[@:sample.title] ボタンを押した回数: {count}

CSV 形式で書くことも出来ます。

良いところ

  • 使っている人が多い
  • リソースの名前空間に対応している
  • リソースファイル形式が豊富
  • 事前の build_runner が不要
  • リソースファイル内で別のリソースを参照できる
  • リソースにアクセスするときに context が不要
  • リソースにアクセスする方法が豊富
リソースにアクセスする方法が豊富
Text('title').tr(); // Text widget
print('title'.tr()); // String
var title = tr('title'); // Static function

悪いところ

  • リソースに定数でアクセスできない
    • 文字列でアクセスするため typo の可能性があったり、IDE の補完機能が使えない
  • リソースファイルにコメントが付けられない
  • ビルド直後翻訳されない文字があった[2](ホットリロードすると直る)
  • easy_localization_loader のドキュメントが少なく、CSV / XML / YAML のファイルフォーマットがよくわからない(デバッグしながら読み解く必要がある)

導入方法

https://www.kamo-it.org/blog/27/

サンプルコード

https://github.com/susatthi/flutter-sample-easy-localization

flutter_translate

https://pub.dev/packages/flutter_translate

使い方

assets/i18n/ja_JP.json
{
  "sample": {
    "title": "多言語化サンプル",
    "message": "ボタンを押した回数: {count}",
  }
}
リソースへのアクセス方法
translate('sample.title'); // => '多言語化サンプル'
translate(
  'sample.message',
  args: {
    'count': _counter,
  },
);
// => 'ボタンを押した回数: 10'

良いところ

  • リソースにアクセスするときに context が不要
  • リソースの名前空間に対応している
  • 選択中の言語設定を保存する機能がある
  • 事前の build_runner が不要

悪いところ

  • ドキュメントが不足している
  • リソースファイル形式が JSON のみ

導入方法

日本語の記事は見つからず。

サンプルコード

https://github.com/susatthi/flutter-sample-flutter-translate

まとめ

まとめてみても fast_i18n が断然使いやすそうです。是非試してみて下さい!

flutter_localizations fast_i18n easy_localization flutter_translate
pub.dev 👍 数 - 113 1476 146
GitHub ⭐ 数 - 123 607 297
初回リリース日 - 2020/07/26 2018/12/22 2019/10/10
最新リリース日 - 2022/04/12 2021/02/20 2021/05/08
ファイルフォーマット ARB JSON
YAML
CSV
JSON
YAML
CSV
XML
JSON
リソースファイルのコメント × ×
リソースにアクセスするとき名前付き引数が使える × [3] ×
リソースファイル内で別のリソースを参照 × ×
リソースにアクセスするときに context が不要 ×
リソースに定数でアクセス可能 × ×
リソースの名前空間に対応 ×
リソースを ListMap で定義可能 × × ×
事前の build_runner が不要 [4] ×
サンプルコード コード コード コード コード

最後に

Flutter 大学という Flutter エンジニアに特化した学習コミュニティに所属しています。オンラインでわいわい議論したり、Flutter の最新情報をゲットしたりできます!ぜひ Flutter 界隈を盛り上げていきましょう!

https://flutteruniv.com?invite_id=9hsdZHg0qtaMIr6RPRulAaRJfA83

あわせて読みたい

https://mabots.hatenablog.com/entry/20120214/1329225300

脚注
  1. 例えば page1.titlepage2.title みたいに同じ title だけど名前空間を分けることで別々に扱えること ↩︎

  2. バージョンは 3.0.0 でした ↩︎

  3. Mapが使えるので似たようなことが出来る ↩︎

  4. generate: trueで保存時に自動生成ができる ↩︎

Discussion