ほたてメモ

日々学んだことをメモメモ

FirebaseUIを日本語化する

Nuxt.jsで使っているfirebaseを8→9に上げる際に、合わせてfirebaseuiのバージョンも最新にした。 これまでFIrebaseUIの日本語化に firebaseui-ja - npm を使用していたが、3年以上メンテナンスされていなかったので、オフィシャルな方式に変更した。

開発環境

開発環境はM1 Macでdocker化した環境

対応方法

公式を見ると、自前でビルドする方法が載っているのでこちらを参考にした。 https://www.npmjs.com/package/firebaseui-ja

github.com

ざっくり手順を書くと

  1. git clone https://github.com/firebase/firebaseui-web.git
  2. npm install
  3. npm run build build-npm-ja
  4. import firebaseui from 'firebaseui/dist/npm__ja' で利用する

失敗パターン

最初にうまくいかなかった方法のまとめ。

今回ビルドが必要なので、dockerのマルチステージビルドでファイルを生成してから本体にコピーする形にした。

ベースイメージは、node:16.14-alpine

FROM node:16.14-alpine AS builder

WORKDIR /var/builder
RUN apk add \
  git \
  bash \
  openjdk11-jre-headless
RUN git clone https://github.com/firebase/firebaseui-web.git
WORKDIR /var/builder/firebaseui-web
RUN git checkout refs/tags/v6.0.1
RUN npm install -g npm@8.5.5
RUN npm install
RUN npm run build build-npm-ja

FROM node:16.14-alpine
# ...

COPY --from=builder /var/builder/firebaseui-web/dist/npm__ja.js $BASE_PATH/node_modules/firebaseui/dist/npm__ja.js

# ...

試した結果

まず、alpineでgitが入っていないので追加。

apk add git

特定バージョンをインストールするためにcheckout後にタグを指定する。

git checkout refs/tags/v6.0.1

npm install をすると、package.jsonに書かれている

"prepublish": "npm run test && cp -r dist demo/public"

も動くため、npm run testが実行される。

ちなみに、npm run testの定義は

"test": "npm run build && npm run generate-test-files && ./buildtools/run_tests.sh"

このまま、npm run testが実行されるとエラーになる。エラーになってもnpm run buildだけなら動くので最終的に生成したいファイルは作られるが、自動化する場合は途中でエラーになると困る。

エラーの解消を試みる

[Closure Templates Error] Java (JRE) is needed!

Javaが必要なので入れる。

apk add openjdk11-jre-headless

Javaを入れると先に進むが、Sassのdeprecateエラーがたくさん出る。エラーではないのでいったんスルー。 今度は

sh: ./buildtools/generate_test_files.sh: not found

というエラーが出る。

ファイルはあるので、最初分からなかったが、generate_test_files.shの中身が、#!/bin/bashなので、bashも追加が必要。

apk add bash

再度、npm run testを実行。

python: command not found
google-chrome: command not found

pythonとgoogle-chromeも必要。。 pythonは入れられるが、google-choromeはarm64のパッケージがないので入れられない。

これ以上がんばってビルドを通してもビルド時間が長くなりすぎそうだったので方向転換。

成功パターン

最終的に実行したいのは

npm run build build-npm-{LANGUAGE_CODE}

なので、

npm install後の、prepublishをスキップすることにした。

一時的なスキップは下記でできる。

npm set-script prepublish ""

最終的な Dockerfile はこちら

FROM node:16.14-alpine AS builder

WORKDIR /var/builder
RUN apk add \
  git \
  openjdk11-jre-headless
RUN git clone https://github.com/firebase/firebaseui-web.git
WORKDIR /var/builder/firebaseui-web
RUN git checkout refs/tags/v6.0.1
RUN npm install -g npm@8.5.5
RUN npm set-script prepublish ""
RUN npm install
RUN npm run build build-npm-ja


FROM node:16.14-alpine
# ...

COPY --from=builder /var/builder/firebaseui-web/dist/npm__ja.js $BASE_PATH/node_modules/firebaseui/dist/npm__ja.js

# ...

テストを通さないはどうかというのはあるが、firebaseui自体では通っているものなので今回はこの形とした。

Vuetifyでデートタイムピッカー(datetime picker)を利用する

Vuetifyで日付や時刻の選択をするのに、日付だけや時刻だけであればコンポーネントが用意されている。

一方、日付と時刻を同時に選ばせるには、コンポーネントがないので調べてみた。

外部ライブラリ

vue-datetime というそのものを公開している方がいたが、残念ながら2022年1月でアーカイブされていた。

https://github.com/mariomka/vue-datetime

HTMLのdatetime-localを利用する

利用できるブラウザが限られるが、<input type="datetime-local"> を利用すると同時に選択ができる。

Vuetifyで書くとこんな感じ。

<v-text-field
  v-model="created_at"
  label="作成日"
  type="datetime-local"
/>

f:id:hotatekun:20220314145322p:plain
Chrome datetime-local (デフォルト)

デフォルトだと、分までしか選択できないが、step="1" を指定すると秒単位まで選択できる。

UIはブラウザ差異があるので注意。 SafariやFirefoxは時刻の部分を手動入力するUIだった。

Chrome (v98) Safari (v15) Firefox (v98)
f:id:hotatekun:20220314145353p:plain
Chrome datetime-local (秒まで指定)
f:id:hotatekun:20220314145500p:plain
Safari datetime-local
f:id:hotatekun:20220314145438p:plain
Firefox datetime-local

他にもIEでは使えなかったり、将来UIが変わる可能性があるなど制約は大きいが、今回は管理画面でブラウザも限定できるのでこの方法を採用。

dockerでRedash環境を立ち上げる

意外とはまってしまったので手順を残しておく。

下記のリポジトリをcloneする。
git clone https://github.com/getredash/redash.git
後でnpmが必要だが入っていないのでDockerfileを編集する。
RUN apt-get update && \
  apt-get install -y \
    (省略)
    unzip \
    npm \  # 追加
    libsasl2-modules-gssapi-mit && \
npmをアップデートする

apt-get update の次辺りに下記を追記。

RUN npm install npm@6.14.3 -g

ここで、Node / npm をこの時点の最新版(Node: 16.3.0 / npm: 7.15.1) にすると、npm installが通らなかった。 redashがnpm: 6.0以上だったので、npmは6系の最新にした。

Node自体も https://nodejs.org/ja/download/releases/ を見ながら、14系に上げてみたが、こちらもエラーとなったので、Node自体はデフォルトの10系のままにした。

build

Dockerfileを変更したらbuildする。

docker-compose build
DB作成
docker-compose run --rm server create_db
npm install
docker-compose run --rm server npm install
build
docker-compose run --rm server npm run build
起動
docker-compose up
アクセス

うまく立ち上がれば、http://localhost:5000/ でアクセスできる。

docker環境でbinding.pryのコンソールが表示されなかった件

問題

docker-compose上で、rails6.1(APIモード) + nginxの構成を作った。

binding.pryをすると、そのステップで止まっているが、docker attachしてつないでもコンソールが表示されない。

continue や exit すると先に進むので、動いてはいそうだが表示されないと不便なので調査した。

解決方法

最終的に、puma.rbで、標準出力が log/puma.stdout.log にリダイレクトされていたのが原因だった。

stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true

開発環境ではファイルにリダイレクトしない形にしたらコンソールが表示されるようになった。

unless ENV.fetch("RAILS_ENV", "development") == "development"
  stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true
end

その他、設定した箇所

docker-compose.ymlに下記の2つは必要

stdin_open: true
tty: true

binding.pryで止めると、60秒で500エラーになってしまう。

  • これはnginx側でタイムアウトになっていたので、proxy_read_timeout を300秒にして回避した(本番は要調整)

また、今回は関係なかったが、下記も参考になった

sqliteで月の日数を取得する

select strftime('%d', '2020-02-01', '+1 month', 'start of month', '-1 day')

やっていること

指定日(2020-02-01)以降が順に処理される。

  • +1 month
    • 指定日の翌月
  • start of month
    • (翌月の)月初(指定日が1日なら不要だが念のため)
  • - 1day
    • (翌月の月初の)前日