Nuxt.js プロジェクトに firebase パッケージを追加したらビルドエラーが発生した

ある Nuxt.js プロジェクトで Firebase Authentication を利用するために firebase パッケージを追加したところ、ビルドエラーが発生した。解決した方法をメモ。

使用しているパッケージのバージョンは以下。

  • nuxt: 2.11.0
  • firebase: 7.15.5
  • firebaseui: 4.5.1

yarnfirebase パッケージを追加した。

yarn add firebase firebaseui

yarn dev を実行した時にビルドエラーが発生するようになった。以下がエラーログ。

These dependencies were not found:

* core-js/modules/es6.array.find in ./.nuxt/client.js
* core-js/modules/es6.array.iterator in ./.nuxt/client.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./components/FirebaseAuth.vue?vue&type=script&lang=js& and 1 other
* core-js/modules/es6.date.to-string in ./.nuxt/utils.js, ./.nuxt/components/nuxt.js
* core-js/modules/es6.function.name in ./.nuxt/client.js, ./middleware/authenticated.ts
* core-js/modules/es6.object.assign in ./.nuxt/client.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./components/FirebaseAuth.vue?vue&type=script&lang=js& and 1 other
* core-js/modules/es6.object.keys in ./.nuxt/client.js, ./node_modules/babel-loader/lib??ref--13-0!./node_modules/ts-loader??ref--13-1!./node_modules/vue-loader/lib??vue-loader-options!./pages/templates.vue?vue&type=script&lang=ts&
* core-js/modules/es6.object.to-string in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 1 other
* core-js/modules/es6.promise in ./.nuxt/client.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./components/FirebaseAuth.vue?vue&type=script&lang=js& and 1 other
* core-js/modules/es6.regexp.constructor in ./.nuxt/utils.js
* core-js/modules/es6.regexp.match in ./.nuxt/client.js
* core-js/modules/es6.regexp.replace in ./.nuxt/utils.js, ./.nuxt/components/nuxt.js
* core-js/modules/es6.regexp.search in ./.nuxt/utils.js
* core-js/modules/es6.regexp.split in ./.nuxt/utils.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./.nuxt/components/nuxt-build-indicator.vue?vue&type=script&lang=js&
* core-js/modules/es6.regexp.to-string in ./.nuxt/utils.js, ./.nuxt/components/nuxt.js
* core-js/modules/es6.string.includes in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js
* core-js/modules/es6.string.iterator in ./.nuxt/client.js
* core-js/modules/es6.string.repeat in ./.nuxt/utils.js
* core-js/modules/es6.string.starts-with in ./.nuxt/utils.js
* core-js/modules/es6.symbol in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 1 other
* core-js/modules/es7.array.includes in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js
* core-js/modules/es7.object.get-own-property-descriptors in ./.nuxt/index.js, ./node_modules/babel-loader/lib??ref--13-0!./node_modules/ts-loader??ref--13-1!./node_modules/vue-loader/lib??vue-loader-options!./pages/templates.vue?vue&type=script&lang=ts&
* core-js/modules/es7.promise.finally in ./.nuxt/client.js, ./node_modules/babel-loader/lib??ref--2-0!./node_modules/vue-loader/lib??vue-loader-options!./components/FirebaseAuth.vue?vue&type=script&lang=js& and 1 other
* core-js/modules/es7.symbol.async-iterator in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js
* core-js/modules/web.dom.iterable in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js and 1 other


To install them, you can run: npm install --save core-js/modules/es6.array.find core-js/modules/es6.array.iterator core-js/modules/es6.date.to-string core-js/modules/es6.function.name core-js/modules/es6.object.assign core-js/modules/es6.object.keys core-js/modules/es6.object.to-string core-js/modules/es6.promise core-js/modules/es6.regexp.constructor core-js/modules/es6.regexp.match core-js/modules/es6.regexp.replace core-js/modules/es6.regexp.search core-js/modules/es6.regexp.split core-js/modules/es6.regexp.to-string core-js/modules/es6.string.includes core-js/modules/es6.string.iterator core-js/modules/es6.string.repeat core-js/modules/es6.string.starts-with core-js/modules/es6.symbol core-js/modules/es7.array.includes core-js/modules/es7.object.get-own-property-descriptors core-js/modules/es7.promise.finally core-js/modules/es7.symbol.async-iterator core-js/modules/web.dom.iterable

core-js のモジュールが見つからない、という旨のログが表示されている。

そもそも core-js についてちゃんと理解していなかったので簡単に整理すると、ECMAScript の新しい仕様や機能を古いブラウザで動かすための Polyfill を提供するライブラリ、という認識。 現在は v3 (core-js@3) が開発されているが、事情により開発が止まっているという話もある。 *1

github.com

yarn.lock の diff を確認すると、@firebase/polyfillcore-js@3 に依存している。

+"@firebase/polyfill@0.3.36":
+  version "0.3.36"
+  resolved "https://registry.yarnpkg.com/@firebase/polyfill/-/polyfill-0.3.36.tgz#c057cce6748170f36966b555749472b25efdb145"
+  integrity sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==
+  dependencies:
+    core-js "3.6.5"
+    promise-polyfill "8.1.3"
+    whatwg-fetch "2.0.4"

Nuxt.js では、@nuxt/babel-preset-app という、Babel のプリセットを提供するパッケージが core-js に依存している。 デフォルトでは core-js@2 を使用するが、設定で core-js@3 に切り替えることができる。

core-js 自体は core-js@3 の開発を進めるようだし @firebase/polyfillcore-js@3 に依存しているので、core-js@3 に切り替えることにした。

切り替え方については、@nuxt/babel-preset-app の README に設定方法が書かれている。

nuxt.js/README.md at v2.13.1 · nuxt/nuxt.js · GitHub

nuxt.config.js に以下の設定を追加する。

  build: {
    babel: {
      presets({ isServer }) {
        return [
          [
            require.resolve('@nuxt/babel-preset-app'),
            {
              buildTarget: isServer ? 'server' : 'client',
              corejs: { version: 3 }
            }
          ]
        ]
      }
    }
  },

僕の環境では、これでビルドエラーを解消できた。高度な使い方をしていないので後で問題が起こるかもしれない。

@firebase/auth など必要なパッケージのみインストールすることで回避する方法も試してみたものの、 firebaseui を使っている関係か別のビルドエラーが発生したので、core-js@3 を使う方法に落ち着いた。

walk-diagonally.hatenablog.com

Digital Things

何年かに一回、昔やったゲームを思い出して「あのゲーム何だったっけ?」としばらく悩むやつ。 久々に悩んで思い出したので、次思い出す時のために残しておく。

www.vector.co.jp

Digital Things という 20 年以上前*1のアドベンチャーゲーム。シナリオが分岐するもので、ダークな内容だったと思う。 Vector でダウンロードしたか、雑誌のフリーソフト集で入手したはず。

ストーリーを進めるうちに、いつの間にか引き込まれて熱中した思い出。 今やって引き込まれるかは分からないけれど、ずっと記憶に残っている。

いい感じでストーリーを進めていたのに、途中でストーリーが終わって「あれ、開発途中なのかな」と思ったけど、バッドエンドだったのだろうか... 「ストーリーの続きは開発中です」のようなメッセージがあった記憶があるが、ただの記憶違いかも。

Vector からダウンロードした LZH アーカイブを解凍すると、ゲーム本体の他に、HTML ファイルが入っており、そこにマニュアルや製作後記などのコンテンツがあった。 当時は子どもだったので読んだ記憶はないが、今読むと理解できる話もあって、なんだか感慨深い。 ゲーム本体は Windows 10 で起動することを確認した。今でも起動するのがすごい。いつかやるかも。

いくつかこの作品に言及していたサイトがあったのでメモしておく。

freegamedouraku.doorblog.jp

www.zephyr.dti.ne.jp

hp.vector.co.jp

Digital Things は cool_ER という 2 人組?のチームが開発したもので、今は何か作っているのかなと検索してみたが、残念ながら活動は終了されているもよう。 元気にされているだろうか。


もう一つ名前が思い出せないゲームがあって、縦スクロール型の 2D のレースゲームだったのだが、たまにネットを検索するけれど、どうしても名前が思い出せない。 確か Digital Things と同じぐらいに出たゲームだったと思う。

*1:LZH アーカイブに含まれている HTML によると開発終了は 1997 年と書かれている

f:id:cho_co_by:20200330193024j:plain

ここ数ヶ月、気分が晴れないことが多い。

些細なこともあるし、極めて個人的なこと、人間関係、将来のことなど、心配しても意味がないこともある。 最近では外を歩くのも難しくなっているけれど、気晴らしの手段はいろいろと用意しておかなければならない。

ただ、こんな状況でも働くことができて、ご飯を食べられて、住む場所があって、身体が動くことは本当に幸せだと思う。

ここ最近でやってよかったことは、YouTube Premium に加入したので、YouTube 上の広告が表示されなくなったこと。 動画を観ている途中で広告が挟まったり、それが不快な広告だったりするのが地味なストレスだった。こういうストレスを少しずつ取り除いて行くのも大切だなぁ。

Sidekiq v6.0.6 + sidekiq-cron + fakeredis で Redis に接続しようとして CI のテストが失敗する

2020/04/06 追記: この問題は sidekiq-cron v1.2.0 で解消されました👏

2020/04/01 追記: はじめは Sidekiq 単体の問題かと思っていましたが、sidekiq-cron と組み合わせている場合に発生するようなので、全体的に更新しました。

Sidekiq v6.0.6 がリリースされました。

Sidekiq v6.0.6 + sidekiq-cron v1.1.0 + fakeredis の組み合わせで、CircleCI で DB のマイグレーションを行う際にテストが失敗するようになり、対応したメモです。

僕が参加しているプロジェクトでは、RSpec を実行するときは、fakeredis という Redis をシミュレートする Gem を使用しています。

以下が CI のテストが失敗したときのログです。 DB のマイグレーション後、本来は Redis に接続しないはずの処理なのに、127.0.0.1:6379 の Redis に接続できないとエラーが発生しています。

bin/rails db:create db:migrate

# ...

Traceback (most recent call last):

# ...
    26: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/sidekiq-6.0.6/lib/sidekiq/launcher.rb:103:in `flush_stats'
    25: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/sidekiq-6.0.6/lib/sidekiq.rb:94:in `redis'
    24: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:61:in `with'
    23: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:61:in `handle_interrupt'
    22: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:64:in `block in with'
    21: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:64:in `handle_interrupt'
    20: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/connection_pool-2.2.2/lib/connection_pool.rb:65:in `block (2 levels) in with'
    19: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/sidekiq-6.0.6/lib/sidekiq.rb:97:in `block in redis'
    18: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/sidekiq-6.0.6/lib/sidekiq/launcher.rb:104:in `block in flush_stats'
    17: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis.rb:2411:in `pipelined'
    16: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis.rb:52:in `synchronize'
    15: from /usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
    14: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis.rb:52:in `block in synchronize'
    13: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis.rb:2416:in `block in pipelined'
    12: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:162:in `call_pipeline'
    11: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:306:in `with_reconnect'
    10: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:164:in `block in call_pipeline'
     9: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:196:in `call_pipelined'
     8: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:230:in `process'
     7: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:319:in `logging'
     6: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:231:in `block in process'
     5: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:381:in `ensure_connected'
     4: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:105:in `connect'
     3: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:306:in `with_reconnect'
     2: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:106:in `block in connect'
     1: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:343:in `establish_connection'
/home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/redis-4.1.3/lib/redis/client.rb:362:in `rescue in establish_connection': Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED) (Redis::CannotConnectError)

対応方法

github.com

github.com

上記の Issue によると、Sidekiq の問題ではなく、sidekiq-cron が sidekiq/launcherrequire しているためだ、とあります。 エラーログのバックトレースに sidekiq-cron が出てこなかったので疑っていませんでしたが、試しに Gemfile の sidekiq-cron をコメントアウトすると、問題が発生しませんでした。

従って、暫定対応になりますが、Gemfile では sidekiq-cron を require: false にして、Sidekiq の initializer で sidekiq-cron を require するようにしました。

# Gemfile
gem "sidekiq-cron", require: false
# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  # ...

  require "sidekiq-cron"
  schedule_file = "#{Rails.root}/config/schedule.yml"
  Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
end

なぜなのか

Ruby インタプリタを終了する際に Sidekiq の統計情報を Redis に書き込む変更が、v6.0.6 で追加されました。

github.com

sidekiq-cron を require すると、内部で sidekiq/launcherrequire されるので、インタプリタを終了する際に上記の処理が実行され、Redis にアクセスできずにエラーになるようです。 fakeredis を使用しておらず、Redis にアクセスできる状態なら、今回の問題は発生しないものと考えられます。

最後に

今回の問題に対する Pull Request も送られているようなので、今後のアップデートで解消されるかもしれません。 その際は追記します。

有償ですが Sidekiq Enterprise に cron 機能があるので、可能ならそれを使う方が安心できるんじゃないかなぁと思う、今日このごろです。

fakeredis は今回あまり関係がありませんでしたが、テストのパフォーマンスが大きく劣化することがなければ、fake ではない本物の Redis を使った方がいいな、と感じました。

GitHub Actions の Ruby プロジェクトで use-ruby-action を使う

GitHub Actions で Ruby を使う場合、何も考えなければ GitHub 謹製の setup-ruby を使うと思います。

github.com

しかし、この setup-ruby、驚くことに 2020/01 上旬時点で使用できる Ruby のバージョンが 2.4 - 2.6 となっています。 setup-ruby の状況や、それ以外の選択肢については、以下の記事で詳しく書かれています。

mstshiwasaki.hatenablog.com

今回 jp_prefecture gem のビルドを GitHub Actions に移行するにあたって、 use-ruby-action というサードパーティ製の Action を使って Ruby のバージョンを指定するようにしました。

github.com

jp_prefecture gem の設定は以下にあります。

jp_prefecture/build.yml at 1f93bc05062dca365956257e55404453497c4154 · chocoby/jp_prefecture · GitHub

Ruby に関する指定を抜粋するとこんな感じ。

jobs:
  matrix:
    # 省略
    strategy:
      matrix:
        ruby:
          - 2.3
          - 2.4
          - 2.5
          - 2.6
          - 2.7

    steps:
      # 省略
      - name: Set up Ruby ${{ matrix.ruby }}
        uses: eregon/use-ruby-action@master
        with:
          ruby-version: ${{ matrix.ruby }}

使い勝手としては、Ruby のバージョンを 2.6 と指定できるので便利です。もちろん 2.6.5 と指定することもできます。 2.6 と指定した場合は、2.6 系の最新のパッチバージョンを使用します。プロジェクトに .ruby-version が存在すれば、そこに記述している Ruby を使用してくれます。

しかし、use-ruby-action がサポートしている以外の Ruby を使いたい場合は、手動で Ruby をビルドする必要があります。 例えば、rubicure gem では Ruby の Docker コンテナを指定し、複数バージョンの Ruby でビルドを行うアプローチを取っているようです。

rubicure/test.yml at b71e872082dfcc53530f90f20670fdad11e1d7a7 · sue445/rubicure · GitHub

GitHub Actions は使われはじめたばかりで、use-ruby-action は選択肢の一つなので、今後の setup-ruby に期待です。

ThinkPad T495s に Manjaro Linux Xfce Edition を入れたら画面がグリッチした

f:id:cho_co_by:20200119224245j:plain
top コマンドを実行した図

環境

  • Lenovo ThinkPad T495s (AMD Ryzen 5 PRO 3500U)
  • Manjaro Linux 18.1.5
  • Xfce 4.14.2

ThinkPad T495s を入手し Manjaro Linux Xfce Edition をインストールしたのですが、画面がグリッチする現象に遭遇しました。 Manjaro Linux というよりは Xfce の問題で、Radeon の GPU が載った Ryzen CPU を搭載している環境で発生するようです。

解決方法

以下のスレッドに解決方法が書かれていました。

xfconf-query を使って vblank_mode というプロパティに xpresent をセットし、再起動することで解決しました。

forum.manjaro.org

xfconf-query -c xfwm4 -p /general/vblank_mode -t string -s "xpresent" --create

以下のフォーラムには、vblank_modeglx を設定すると、NVIDIA の GPU に適した状態に、vpresent は AMD の GPU に適した状態になると書かれています。 正直なところ、両者の違いが分かりません。Xfce 4.14 では glx がデフォルトで適用されるそうです。

forum.xfce.org

果たしてこれが根本的な解決になっているか不明ですが、とりあえず動いているので良しとします。

RubyMine で rbenv でインストールした Ruby が表示されない時の対応

最初にまとめ

  • rbenv で Ruby をインストールしたのに、RubyMine で認識されないことがある
  • rbenv を入れ直しましょう
  • RubyMine を再起動しましょう

以上


Homebrew で入れた rbenv で Ruby 2.6.5 をインストールしたのに、RubyMine の Ruby SDK & Gems にインストールした Ruby が表示されない。 Ruby を入れ直したり、RubyMine を再起動しても変わらず。

最終的に rbenv を入れ直しました。(ruby-build については手を入れていません)

brew uninstall rbenv
brew install rbenv
rbenv install 2.6.5

RubyMine を再起動します。 きっと表示されるはず。

f:id:cho_co_by:20191220114955p:plain