Angularでもいい感じに多言語化したい

はじめに

4月からVBおじさん改めナウでヤングなWebエンジニアになりました弊社です。

MS信者の弊社としましては、Blazorをぶっこんでヒャッハーしたいのですが、GAしていないものをプロダクションに投入するのはまぁ・・・ねぇ・・・*1

github.com

じゃけんAngularを投入しましょうね~ということになったのですが、Angularで多言語化するにはどうすればいいのかよく分からなかったので確認してみました。

ドキュメント

困ったら公式ドキュメントを参照する。万葉集にも書かれています。

公式ドキュメント答えて曰く

  1. デフォルトだとen-USしかロケールがインポートされていないから、他のロケールCurrencyPipeとかを使いたかったら自分でいい感じにインポートしてね(んで、ng serveとかng buildでパラメータとして与えてねとのこと)
  2. 翻訳したいタグに片っ端からi18n属性を放り込んでいってね
  3. ng xi18nでそのロケール用の翻訳用のファイルを生成して、そこに翻訳した結果を入力してね
  4. 翻訳用のファイルをアプリケーションに統合するにはAOT(Ahead of time)もしくはJIT(Just in time)の二つの手段があって、AOTは事前に各ロケール別のパッケージを生成しておく必要があるけどはやいよ。JITは実行時にやるから事前の準備は要らないけどおそいよ。好きなほうを選んでいってね

だそうです。

今回はAOTでやってみることにします。

angular.io

構成

f:id:jyuch:20190504224201p:plain

今回は、ビルド済みのAngularアプリケーションをnginxでホストします。また、APIサーバとして.NET Core Web APIを使用します。APIサーバはnginxでリバースプロキシをかますことでいい感じにAngularアプリケーションからアクセスできるようにします。

f:id:jyuch:20190505005422p:plain

クライアント側はhogefugaの二つのコンポーネントがあり、下部のリンクをクリックすると交互に画面が遷移します。

カウントはそれぞれの画面が遷移した回数を表し、これはクライアント個々の回数ではなくアプリケーション全体の数をカウントしています。そのためカウントはサーバ側のAPIでカウントをしています。この部分は.NET Core Web APIで実装されています。

言語化

まず、ベースとなるアプリケーションを用意します。

今回はあらかじめこちらに用意しておきました。(キュー〇三分クッキング風に)

github.com

翻訳属性の付与

とりあえずは多言語化する箇所にひたすらi18n属性を追加していきます。

github.com

翻訳ファイルの生成

以下のコマンドを使用し翻訳ファイルを生成します。

ng xi18n --output-path src/locale

デフォルトではsrc直下に作成されるのですが、それだとなんか嫌なのでとりあえずlocale以下に格納するようにします。

翻訳ファイルへの翻訳の記入

さっき作った翻訳ファイルをコピーし、翻訳(今回は日本語)を入力します。

github.com

serve及びbuild時の変換設定

デバッグ時及びビルド時に翻訳結果をマージできるように設定ファイルをいい感じに書き換えます。

github.com

すると、コマンドで日本語の翻訳結果がマージされたアプリケーションが起動します。

npm run startjp

f:id:jyuch:20190505020109p:plain

デプロイ

URL配置

今回は以下の感じでURLに配置します

  • /app/ja:日本語
  • /app/en:英語
  • /api:Web API

Angularはデフォルトだと/直下に配置される前提でビルドされるっぽいので、それぞれのURLから展開できるようにbase-hrefを設定します。

github.com

ビルド

それぞれ

dotnet publish -c Release -r win10-x64 --self-contained true

npm run build; npm run buildja

で成果物をビルドします。

配置

成果物をサーバにコピーして以下の感じに展開します。

└─/path/to/nginx/www/root
   └─app
       ├─en
       │  └─index.htmlとか
       └─ja
          └─index.htmlとか

そうしたら、いい感じにnginxの設定ファイルを書きます。

#user  nobody;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  s00010;
        
        location /app/ja/ {
            root   html;
            index index.html index.htm;
            try_files $uri /app/ja/index.html;
        }
        
        location /app/en/ {
            root   html;
            index index.html index.htm;
            try_files $uri /app/en/index.html;
        }
        
        location /api/ {
            proxy_pass    http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection keep-alive;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

確認

おわりに

悩んだ時間の大半はnginxの設定でした。つらいね

github.com

おわり

*1:4/18に正式プレビューになったのでそろそろGAだとは思うのですが