nuxtjsで日付を扱う(@nuxtjs/date-fns)

日付のformatをちょろっと変えたいと思ったのに、それなりに嵌ってしまったのでメモ。

version

nuxt@2.14.9
vue@2.6.12

ライブラリ(@nuxtjs/date-fns)

jsって日付の扱いが微妙で、ライブラリ使うのが無難なんですが、ググるとmomentの例がいくつかありました。 しかし、momentはもうメンテナンスモードという扱いで、新しいプロジェクトで利用するには推奨されていません。 Moment.js | Docs

いくつか代替ライブラリはあるのですが、nuxtjsで利用するには、下記が便利そうでした。

nuxt-community/date-fns-module: Modern JavaScript date utility library - date-fns for Nuxt.js https://github.com/nuxt-community/date-fns-module/

利用方法

現在のnuxtjsでは、vueは2系であるため modules に設定します。

# nuxt.config.js
   modules: [
+    '@nuxtjs/date-fns',

基本これで、 $dateFns が利用できるようになります。
templateで以下のようにすれば利用できます。

{{$dateFns.format(new Date(), 'yyyy-MM-dd')}}

jsで利用したければ、以下のようにすれば良いです。

  asyncData({ $dateFns }) {
    return {
      dateFormatted: $dateFns.format(new Date())
    }
  }

はまったところ

こういうのって、共通化(global filter化)したいんですが、$dateFns は asyncData であり、vueのfilterはasyncDataが扱えない?ようです。(この辺り正しく理解はできてないですが)

ではどうするか?

date-fns/format を直接使うで、とりあえずしのぎました。 なんかこの辺り他に良い方法がありそうなんですが、、、

# plugins/filter.js
import Vue from 'vue'
import format from 'date-fns/format'

Vue.filter('formatDate', (date) => {
  return format(date, 'yyyy-MM-dd')
})
# nuxt.config.js
   plugins: [
+    '~/plugins/filter.js'
   ],

そうすると、こんな感じで利用できます。

{{article.date | formatDate}}

sesrverless frameworkを使ってrubyでAPIを作る

The Serverless Application Framework | Serverless.com
以前から気にはなっていたのですが、簡易的なAPIを作るために利用してみました。
 
同様のServerless Frameworkとしては、Ruby on Jets というのがあります。
こちらも触ってみたいところ。

ざっくり利用方法

Installation

sesrverless入れるだけです。

mkdir your_project
cd your_project
yarn init
yarn add serverless -D

Create your project

yarn run serverless create --template aws-ruby

Deploy

コマンド1発で、CloudFormation作ってくれて、s3、IAM、Lambda、ApiGateway、CloudWatchまで一気にやってくれます。
これはめちゃ便利で、驚きました。

yarn run serverless deploy -v

各種設定

Serverless Framework - AWS Lambda Guide - Serverless.yml Reference
ここに全部乗ってるので、詳細は公式Documentみるのが良いでしょう。

以下、今回利用した設定内容。baseはこれだけ。

provider

こんな感じ。

provider:
  name: aws
  runtime: ruby2.7
  stage: dev
  region: ap-northeast-1
  apiGateway:
    shouldStartNameWithService: true

shouldStartNameWithService は、正直どっちでも良いですが、次のmajor versionからAPI Gatewayのnaming-ruleが変更されるため、新しい方式に合わせるために入れてます。
Serverless Framework Deprecations

functions

こんな感じ。ポイントはcors: trueぐらいでしょうか。

functions:
  exec:
    handler: handler.exec
    events:
      - http:
          path: html2haml
          method: post
          cors: true

注意事項

あとはhandler.rbにロジック書くだけで出来ちゃいますが、2つハマったところがあるので記載していきます。

Native Extension Gem

今回html2hamlを利用としたのですが、当然の如くnokogiri使ってまして、macでbuildしたgemをdeployしても動かないわけです。
そこで利用するのがlambci/lambda - Docker Hub
buildの例にrubyがなかったり、ruby2.5の例のままですが、現在のlambda同様2.7が利用できます。

# build
docker run -v `pwd`:/var/task -it lambci/lambda:build-ruby2.7 bundle install --path vendor/bundle --without development test
# local実行例
# handler、eventが指定できる
docker run --rm -v $PWD:/var/task:ro,delegated lambci/lambda:ruby2.7 handler.exec  '{"body": "{\"html\":\"<span foo=\\\"foo\\\">test</span>\"}"}'

 
しかし、bundle installしたgemなどをzipに含めると転送量が多くなるという問題があり、これを解決するためにはlayerとして別管理するか、serverless-hooks-pluginを使ってdockerでinstallするという手法があるようです。(後者試してないのであとでやってみます。) 個人的にはどうも、この辺が面倒だと感じるので、serverlessバンザイ!という気持ちには今一つなれません。

API GatewayのResponse形式

ここに書いてるんですが、Responseの形式が決まっています。
API ゲートウェイでの「不正な Lambda プロキシ応答」または 502 エラーの解決

見落としてハマっていたのが、bodyの形式です。JSON.stringifyした文字列が必要でした。 rubyなので、hashをto_jsonすることで解消。

"body": JSON.stringify(responseBody),

ご参考

See Also

htmlをhamlに変換するサイトhtml2hamlを勢いで作った - rochefort's blog

vuecliでの環境変数の利用方法

ここに全部書いてるんだけど、知らずにハマったのでメモ。
Modes and Environment Variables | Vue CLI

Mode

環境ごとの処理を分けれるように、modeという概念がある。
defaultは、development,、test、production。

ちなみに、vue-cli-service build 時は、productionが自動でセットされる。
 

Environment

.env                # loaded in all cases
.env.local          # loaded in all cases, ignored by git
.env.[mode]         # only loaded in specified mode
.env.[mode].local   # only loaded in specified mode, ignored by git

という感じに環境変数を書いていく。
アプリで利用するために VUE_APP_ というprefixをつける必要がある。これを理解していなくてハマってしまった。

あとは、secret keyとか書くなよということが一応書いている。

WARNING

Do not store any secrets (such as private API keys) in your app!

Environment variables are embedded into the build, meaning anyone can view them by inspecting your app's files.

一応、このprefixを利用している理由としては、ついうっかり他の環境変数もjsにbundleされないようにするためのよう。