Nuxt.jsプロジェクトをDockerで起動できるようにした

f:id:clash_m45:20200912170054p:plain
nuxt.js + docker

実装中のNuxt.jsプロジェクトのサービスをDockerで起動できるようにしたので、ログを残しておく。

Pull Request

github.com

Nuxt.js を Dockerコンテナで起動する

サンプルないかなーと awesome-nuxt を見てたらあった。

github.com

⭐️を付けて拝借する。

ちょっとした解説

ただこのサンプル古いみたいで、nodeが v7.8 のイメージを使ってて修正が必要だった。

nodeはつい最近 v14 が出たんだけど、プロジェクトでは node v12 を使ってたので、一旦 v12 のDockerイメージを使うことにした。

hub.docker.com

FROM node:7.8.0-alpine
 ↓
FROM node:12.18.3-alpine3.12

alpine3.12を選んでるのは、一緒に開発してるAPIサービスがこのバージョンだったから合わせとくか、くらいの感じです。


あとは、 yarn をインストールして、yarn install , build , start って順にビルドしてあげればOK。
この辺は yarn のビルド設定 package.json がちゃんとしてれば問題ない。

Tailwindcssのpurge設定警告メッセージ

f:id:clash_m45:20200912160102p:plain

Tailwind CSS を使ってるプロジェクトで yarn build したらこんな警告メッセージが出た。

Tailwind is not purging unused styles because no template paths have been provided.
If you have manually configured PurgeCSS outside of Tailwind or are deliberately not
removing unused styles, set `purge: false` in your Tailwind config file to silence
this warning.

https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css

どうやら purge というオプションがあって、production buildの時に使ってないCSS定義を削除してくれるらしい。

tailwindcss.com

とりあえず使わない場合は、 purge: false としたら良いらしいので、一旦falseにしたら警告メッセージは消えた!

対応した時のコミット

github.com

HanamiのサービスをDockerで起動できるようにした

f:id:clash_m45:20200912124437p:plain
hanami + docker

Hanamiで実装中のサービスをDockerで起動できるようにしたのでログを残しておく。

Pull Request

Docker化したPull Requestはこちら

github.com

HanamiをDockerで起動する

サンプルないかなーと awesome-hanami を見てみたらちゃんとあった。

github.com

⭐️を付けて拝借する。

ちょっとした解説

dockerで起動するために追加したファイルは 3ファイル。

  1. Dockerfile
  2. docker-compose.yml
  3. Makefile

Dockerfile

サンプルではPostgreSQLを使用する構成になっているが、本プロジェクトではSqliteを使っているので書き換えた。
あとはRubyイメージのバージョンを2.6.0にしたくらいでほとんど変えてない。

dockerイメージに ruby:2.6-alpine を使っているので、bashが使えない。 ash を使う。

ポート 2300(hanamiのデフォルト)を開放している。

CMD ["bundle", "exec"] で hanami コマンドを受け付けたりできるようになってる。

docker run -p 2300:2300 api hanami server --host=0.0.0.0

docker-compose.yml

とくに変哲もないdocker-compose.yml

サンプルからPostgreSQLの記述を削除して、webサービスのdepends_onも消した。

Makefile

makeコマンドの設定ファイル。
こんなふうにランチャーとして使っているのを始めてみたので、新鮮だった。
本来こうやって使うのかもしれない。ビルドでしか使ったことなかった。

dockerizeが --build オプション がついていて毎回時間がかかるので、 up タスクを追加した。

up — Docker-docs-ja 17.06 ドキュメント

課題

make up で起動したらHanamiの標準出力がでなくなった。 また別途対処しよう。

Rails + webpacker + Vue.js + TypeScript で `export 'default' (imported as 'mod') was not found`

Railswebpacker gem を使って、Vue.js with TypeScript な環境を作った中で長くハマった部分があったのでご紹介したい。

ハマったところ

webpacker で vue と typescript を初期設定して、Vue.js の SFC (Single File Component) で開発していた。
webpacker でコンパイルするときに、export 'default' (imported as 'mod') was not found というエラーが起きた。

結論としては、 vue-loader が ts-loader を使いたいが、ts-loader 側で .vue ファイルを受け入れる設定になっていなかった(みたいな感じ)。

初期設定の再現

$ gem install webpacker
$ rake webpacker:install
$ rake webpacker:install:typescript
$ rake webpacker:install:vue

解決法

webpacker が生成してくれる config/webpack/loaders/typescript.js を以下のように変更する。

Before

const PnpWebpackPlugin = require('pnp-webpack-plugin')

module.exports = {
  test: /\.(ts|tsx)?(\.erb)?$/,
  use: [
    {
      loader: 'ts-loader',
      options: PnpWebpackPlugin.tsLoaderOptions()
    }
  ]
}

After

const PnpWebpackPlugin = require('pnp-webpack-plugin')

module.exports = {
  test: /\.(ts|tsx)?(\.erb)?$/,
  use: [
    {
      loader: 'ts-loader',
      options: PnpWebpackPlugin.tsLoaderOptions({
        appendTsSuffixTo: [/\.vue$/]
      })
    }
  ]
}

これを調べるのに vue-loader のソースを結構読んだ。

vue-loader は Vue.js の SFC 単一ファイルコンポーネントコンパイルするために他のコンパイラ(xx-loader)へ橋渡しする役目を担ってるのかなとわかった。

SFC では HTML を書く template と JSで実装する scriptCSS を書く style と3つの領域それぞれで他の言語を使うことができる。

たとえば、template で pug を使ったり、
script で TypeScript を使ったり、
style で SCSS や SASS を使うことができる。

<template lang="pug">
</template>
<script lang="ts">
</script>
<style lang="scss">
</style>

それぞれコンパイラが違うのでそれを vue-loader さんは

  • "template は pug-loader!!"
  • "script は ts-loader!!"
  • "style は scss-loader!!"

と振り分けてくれている。

実は vue-loader のドキュメント Vue Component の仕様 を熟読するとそういうことが書いてある。

Vue Component の仕様 · vue-loader


参考資料:

FirebaseでTwitterアカウント認証出来た

FirebaseでTwitterアカウント認証出来た

Firebase Authentication で Twitter アカウントを使った認証を作れた。
まだ認証しか出来ないけど、そこまでにハマった点を残しておこうと思う。

用意するもの:

  • Twitter Developer Apps 登録
  • Firebase Project

Twitter Developer Apps

developer.twitter.com

随分前に取得済みだったので、忘れたが、取得はそんなに難しくなかった。

たぶんちゃんと英語を読んで、自分なりに考えたアプリの説明なりを書いていけば承認される。

Firebase Project

firebase.google.com

こちらはすっごく簡単につくれる。 たくさん参考記事はネット上にあるので、検索されたし。

firebase-toolsを使って firebase init とかで実装開始できる。

難しかったところ

Firebase UI の導入

この記事を見ながらやってた。

qiita.com

Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).

自分でアレンジして組み込んでいったら、firebase.initializeApp() が何度も呼ばれて、Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app). というエラーが発生した。

ちょっと検索したら、この記事があったので、リンク先のやり方で解決。

ReactとFirebaseの構成でチャットシステムを目指した · PengNote - 勉強した事や行った場所の感想を書くブログ

Firebase App named '[DEFAULT]' already exists (app/duplicate-app) · Issue #1999 · zeit/next.js · GitHub

f:id:clash_m45:20190908142416p:plain

この問題が解決したらこんなボタンが出た😊 f:id:clash_m45:20190908142433p:plain

Desktop applications only support the oauth_callback value 'oob'

次に遭遇したのはこのエラー。

Twitter API のほうでエラーになっている感じがしたのと、どうもデスクトップアプリと誤認してるようだった。

検索してみると、この記事に行き着いた。

TwitterのOAuthでCallbackさせるときの注意点

Twitter Developer のページへ行って、Apps から自分のアプリの設定詳細ページを開く。

私の場合は、

  • Sign in with TwitterDisabled だった。
  • Callback URLが 空だった。

なので、以下を変更した。

  • Sign in with TwitterEnabled
  • Callback URLが に以下を追加
    • https://${firebaseのドメイン}.firebaseapp.com
    • https://${firebaseのドメイン}.firebaseapp.com/__/auth/handler

callback urlは実際にはコールバックさせたいアドレスにしたら良い。(今回はお試しでトップページに返すだけにした)
2つ目はfirebase uiが使うのかな?1つ目を追加したらエラーメッセージに現れたので追加した。

出来た!

そんなこんなして、ハマりつつも Twitter アカウントで認証できました!

f:id:clash_m45:20190908142444p:plain

Firebase Functions ローカルで関数を実行する時に失敗する件について

Firebase Functionsは firebase-tools を使って、ローカルで関数を実行してテストできる。

結論

firebase functions:shell を使おう!

使い方はこちら

firebase.google.com

例えば、 myFunc という関数を定義したら、

firebase > myFunc.get()

とかで呼べるし、express で myFunc配下に関数 ( /greet ) がある場合には、

firebase > myFunc.get('/greet')

で呼べる。

続きを読む

vueで開いたり閉じたりするコンポーネントを作る

最近vanillaのjavascriptで開いたり閉じたりするUIを作ってて、すっげぇ苦労したので、 「くっ…!!(vueなら簡単に書けるのに…!!)」という気持ちを発散するために、実際に作ってみた。

仕様

開くボタン

  • 「開く」ボタンをクリックするとフォームが開く。
    • 開いている間は開くボタンは消える。

閉じるボタン

  • フォームには「閉じる」ボタンがあり、押すとフォームが閉じる。
    • 閉じている間は閉じるボタンは消える。

作ったもの

See the Pen Vue expand form by clash_m45 (@clash_m45) on CodePen.

コード

styleをはしょってるので、全文はcodepenのほう見てください。

単純に v-if を使って、プロパティ expand がtrueのとき開く、としているだけ。 buttonのon-clickで openメソッド、closeメソッドを呼んで、 expandを書き換えると、vueの力でbindingされて、動的にUIが変化する!

素晴らしい!

<template>
  <div>
    <h3>開いたり閉じたりする入力フォーム</h3>
    <hr>

    <button v-if="!expand" @click="open">開く</button>
    <div v-if="expand">

      <label for="hamburger">Do you like hamburger?</label>
      <input type="checkbox" name="hamburger" id="hamburger">
      <span>checked</span>
      <br>

      <button @click="close">閉じる</button>
    </div>
  </div>
</template>

<script>
  export default {
    name: "count",
    data () {
      return {
        expand: false
      }
    },
    methods: {
      open: function() {
        this.expand = true
      },
      close: function() {
        this.expand = false
      }
    }
  }
</script>