【日報】テスト導入、手続きはお早めに

 9月7日の日報です。

nuxtアプリ向けにjest導入

 フロントエンドにjestを導入して.ts, .js, .vueファイルすべてのカバレッジまで処理できるよう、設定だけは追加しました。テストそのものは今後ちょっとずつ書きます(本当はテスト設定と最初の1テストをまとめてサクッと入れるつもりでしたが、必要なリファクタリングが大物すぎたので分離)

 jestそのものの利用方法が簡単なこともあって、必要なライブラリーを追加し、そのたびコマンドを叩いてエラーを潰していくだけです。特に罠というほどの問題はありませんでした。ただ今日も yarn workspaces 由来と思われる「vue関連の依存関係がなぜか動かない」という現象が出ていまして、 package.json の変更がその対応になっています。

 なんというか、vueとworkspacesの相性が良くないのかなあという感じですが… まあ動いたのでいいです。

今後の作業

 ボトルの切り替えがうまく動かない所在不明のバグがあるので、その解消も兼ねてリファクタリングが続きます。ちなみにですが、今日は国保の手続きミスを取り戻すために半日使ったので、皆さんは就職・退職したらすぐ役所に行きましょう。

【日報】typescript、pug、夜行バス

 9月5日の日報です。

nuxt-edge 環境でのtypescript利用

 今日もまたえぐいバグを踏み抜いて直しました。

 TypeScriptが pages 配下のファイルでのみ正しく解釈されない (nuxt-i18nの問題)、なぜか正しく動かない (ts利用時に暗黙の決まり事がある) というようなやつで、ちょっと大変でした。可能ならあとで詳しく書きますが。

今後の作業

 これから夜行バスで東京に行くので、明日の作業はお休みです。

追記: pug

 まずタイトルに pug と書いてありますが、記事に書く前に寝ました。

 pugはhtml生成用のテンプレートエンジンで、実際の利用例を見ていただくと早いですが、vueの単一コンポーネントファイルでこんな感じに利用可能です。

<template lang="pug">
  section.section.has-background-light
    .container
      slot
</template>

 pug-loader ではなく pug-plain-loader を利用しているのは何か理由があったんですが、完全に失念しました。あとで調べ直します。

追記: nuxt pagesでts使うとエラー

 pages 配下のファイルでTypeScript (正確には、jsとして正しくない全ての構文) を使うと acorn がどうのこうのと謎エラーが発生し、nuxt が起動すらしなくなり、ぶっ壊れる問題がありました。

$ nuxt
[12:52:04 AM] Building project
[12:52:04 AM] Builder initialized
[12:52:04 AM] SyntaxError: Unexpected token (17:34)
at Parser.pp$4.raise (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2756:13)
at Parser.pp.unexpected (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:647:8)
at Parser.pp.expect (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:641:26)
at Parser.pp$2.parseBindingList (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:1694:19)
at Parser.pp$3.parseMethod (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2530:22)
at Parser.pp$3.parsePropertyValue (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2448:23)
at Parser.pp$3.parseProperty (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2433:8)
at Parser.pp$3.parseObj (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2379:23)
at Parser.pp$3.parseExprAtom (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2179:17)
at Parser.pp$3.parseExprSubscripts (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2047:19)
at Parser.pp$3.parseMaybeUnary (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2024:17)
at Parser.pp$3.parseExprOps (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:1966:19)
at Parser.pp$3.parseMaybeConditional (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:1949:19)
at Parser.pp$3.parseMaybeAssign (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:1925:19)
at Parser.pp$3.parsePropertyValue (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2442:87)
at Parser.pp$3.parseProperty (/Users/tottokotkd/dev/tagbottle.io/firebase-web/hosting/node_modules/acorn/dist/acorn.js:2433:8)

 これは一言でいうと nuxt-i18n による独自パースが原因です。ルーティング情報集めのために、何やら情報を集めてやっているんだそうです。そのうち治るのかもしれませんが、現状では parsePages オプションを使って nuxt-i18n の挙動を抑えるしかなさそう。

追記: tsコードでのimportが失敗する

 TypeScriptを利用して.vueファイルからモジュールをインポートするためには、利用される側のファイルにおいて export default {...} の記載が必須です。存在しないものはインポートすべくもないので、まあそれ自体は考えてみると当たり前という話ではあります。

 ただ今回は、この当たり前の挙動を訂正するために結構な時間を取られました。これは外部の問題ではなく、完全にタグボそのもののバグなのですが、

  1. いつの間にかtypescriptコンパイル時の型チェックが切れていた
  2. <script> そのものを欠くファイルは少数であり念頭になかった
  3. <script lang="ts"> を欠くファイルもあって問題がややこしくなった
  4. TS2307: Cannot find module というエラーから、.vueファイルそのものを発見できていないケースを想定した
  5. tsconfigに問題がある可能性をより強く疑った

 等々のアレな事情があったので、ファイルはあるけどモジュールをインポートできないという状態を認識するまでに時間がかかりました。そこに意識が向いてからはサクッと直せたと思いますが…

 いずれにせよ褒められた話ではないので、ちゃんとテストを書きましょうという方向で反省中。

【日報】送信ステータスの明確化、リファクタリング、たまこ

 9月4日の進捗おしらせです。

メッセージ送信時の表示改善

 yarn workspaces 導入後にGitLab CIのキャッシュを削除しなかったせいなのか、昨日盛大にバグを発生させました。その内容は「一見送信できたように見えるけれども、実は送信できておらずリロードすると画面から消える」というもので、バグに気付くまでは一見正しく動いているように見える(そして消える)という、かなり不快感のある挙動となっていました。

 このようなバグは出来る限り発生させたくないものですが、少なくともバグ再発時のストレスを軽減するために「メッセージの保存状況が画面上、明らかにわかる」UI上の改善を加えました。

 メッセージ送信後、「サーバー側での処理が完結した」と確認できるまで、ローディング表示が続きます。これにより、例え今回のようなバグが再発しても「一見送信できたように見える」という挙動は回避できます(ローディングが無限に回り続けるので、バグとわかります)。

今後の作業

 リファクタリング継続中です。たまこラブストーリーいいですよね、劇場で一人で見ました。

【日報】リファクタリング、バグ、寒い

 9月3日の日報です。

コンポーネント書き直し中

 新機能を増やす前に、現状のコンポーネントを整理すべくリファクタリング作業を進めています。コードの見通しを改善し、メンテナンス性を高めることが目的です。

workspacesマージしてデプロイしたらシステム崩壊

 ある時間帯から、突如として「FIrebaseが正しく動作しない」「一見するとメッセージを投稿できたように見えるがfirestoreに反映されない」という問題が発生しました。

 よく分かりませんが、おそらくCIキャッシュに含まれる node_modules のせいです。デプロイやり直しでなんとかなりました… たぶん。

今後の作業

 リファクタリング作業を継続していきます。しかし、なんか急に寒いですね。

【日報】yarn workspacesとnuxt / vuepressを組み合わせるとnohoist必須、あと台風

 9月2日の日報です。yarn workspaces + nuxt = しんどいバグという話です。

yarn workspaces あれこれ

 タグボトル内部の構造を修正し、yarn workspace導入しました。ところがバグっていたので修正しました

 ワークスペースを導入すると、複数プロジェクトで利用するモジュールを一括して1つの node_modules に入れられるというわけです。最高そうですね! ということで使ってみます。

 実際にやってみると、workspacesの導入そのものは簡単です。各 package.json にバージョンを持たせるとか、name とディレクトリ名を一致させておくとか(?)、ルートのプロジェクトをプライベートにするなどの細かい点はありますが、特に難しいことはありません。

 ただ、ワークスペースを導入してからnuxt内部の依存関係の解決が全く動かなくなりました。雑なコピペで nohoist 1導入したら、ついでにvuepressまで壊れました

Error: [BABEL] /builds/tagbottle/tagbottle.com/node_modules/vuepress/lib/app/clientEntry.js: Cannot find module '@babel/helper-module-imports'

 job失敗の詳細ログはここにあります。

 雑な修正以前は、 @nuxtjs/pwa が見つからないよーという別パターンのバグを踏んで無事終了しました。どうやら様々なものを相対パスで拾っているっぽいですが、なんだか困りますね。

 もちろんのこと動かないままでは困るので、見よう見まねで nohoist オプションを理解してみました。 記載場所はルートの package.json です。

"workspaces": {
  "packages": [
    "documents",
    "functions",
    "hosting"
  ],
  "nohoist": [
    "documents/vuepress",
    "documents/vuepress/**",
    "hosting/nuxt-edge",
    "hosting/nuxt-edge/**",
    "hosting/nuxt-i18n",
    "hosting/nuxt-i18n/**",
    "hosting/@nuxtjs/pwa",
    "hosting/@nuxtjs/pwa/**"
  ]
},

 公式ブログが詳しいのですが(というか他のドキュメントはなさげ) nohoist は2つのパターンを組み合わせて記述していきます。

  • documents/vuepress: documents プロジェクトが依存する vuepress モジュールを documents/node_modules に置いたままにします。ただし vuepress が依存するモジュール群は親ディレクトリで一括インストールします。
  • documents/vuepress/**: documents プロジェクトが依存する vuepress モジュールがさらに依存するモジュール群 (@babel とか) を documents/node_modules に置きます。

 ここでは、nuxt vuepress が怪しいということで、それぞれ名指しで除外しています2

 今回は露骨にワークスペース導入によりビルドエラーが出たので、nohoist を修正しては yarn.lock を削除し、 yarn install からの様子見でさらに記述を追加し… という作業をしています。ぶっちゃけこれは、原因がワークスペース周りにあると確信しているからこそ実行可能な作業です。いつの間にか壊してしまって「なんかおかしい、どこか壊れた…」レベルだと、これはなかなか厳しいことになると思います。yarn 周りで依存が壊れることってあんまりないので、そもそも「依存が壊れているのでは?」と考えつくまでのコストが高そう。

 今回は久しぶりにまともな先行例のない問題を踏んでどえらい目に遭いましたので、日報に記載しておきます。

今後の作業

  • issue 1つずつ消化してリファクタリング

 地道にいきます。あと台風が通過したら再び東京に行きます。


  1. nohoist = no hoist = 上に巻き取らない

  2. なぜだかよく分かりませんが、公式記事のサンプルでは上記のように対象プロジェクトを明示せず、ざっくり ** で消し飛ばす設定になっています。勿論それで動くんでしょうが、その記載だと何を意図して記述しているのかがサッパリ分からないので、今回は上記のように明示的な書き方をしてみました

【お知らせ】 アルファ版より以前に開発へ参加された方へ

アルファ版より以前に開発へ参加された方には、当時まともに会話できるインフラが整っていなかったため、tagbottle.ioからG suiteの有料アカウントを発行していましたが、アルファ版の運用が開始されたことを受けてこれらのアカウントを閉鎖しました。

お手数ですが

  1. 個人のグーグルアカウントでログインする
  2. ログイン用に新しくグーグルアカウントを作成する

いずれかの形で対応をお願いします。浮いた費用はインフラに突っ込ませていただきます。