うしろのこの本ください

なんでもかきます

Nuxtのpwa-moduleでプッシュ通知令和版

直近プッシュ通知の実装が必要になったためハマったところ中心に結果をメモる。

受け取り側

pwa-moduleはOneSignalをサポートしているため、Nuxtでプッシュ通知をやりたい場合これを使うのが一番簡単。

pwa.nuxtjs.org

とりあえずpwa moduleとone signal moduleを入れてnuxt.config.jsに設定を書けば受け取り側の設定は終わる。

yarn add @nuxtjs/onesignal @nuxtjs/pwa

nuxt.config.js

// 省略
  modules:
      [
          '@nuxtjs/onesignal',
          '@nuxtjs/pwa'
      ],
  oneSignal: {
    init: {
      appId: 'One Signalコンソールで発行したID',
      allowLocalhostAsSecureOrigin: true, // localhostで動作確認する場合true
      welcomeNotification: {
        disable: true
      },
    },
    importScripts: ['sw.js'], // 後述、必須
  },
  pwa: {
    workbox: {
      dev: true, // devモードで起動した時でもServiceWorkerを有効にする
    },
    manifest: {
      name: 'test',
      short_name: 'test',
      title: 'test',
      'og:title': 'test',
      description: 'test',
      'og:description': 'test',
      lang: 'ja',
      theme_color: '#ffffff',
      background_color: '#ffffff'
    },
  },
// 省略

ワーカーが複数ある場合、メインのワーカーに他のファイルをマージする必要がある。OneSignalのSDKが取り込めるように自動生成してくれるが、デフォルトのパス指定が/sw.js?xxxxxxxxのような形で生成されうまく読み込めないので、importScriptsで明示的に指定する。

うまくいっていればdeveloper consoleのApplicationタブで確認することができる。

f:id:apple19940820:20191101110929p:plain

送信側

OneSignalにサインアップする。GitHubアカウントやGoogleアカウントで登録できる。

Add a New Appでアプリケーションを作成する。適当に名前いれてADD APP。

その後どのプラットフォーム向けに作るかの選択肢がでるためWeb Pushを選ぶ。Choose IntegrationはTypical Siteで。

Site Setupは以下のように

f:id:apple19940820:20191101112158p:plain

ローカルで確認したいので、localhosthttps扱いにする。

Permission Prompt SetupはとりあえずNative Propmtで。カスタマイズもできるがブラウザデフォルトであるメリットの方が大きい。

これ

f:id:apple19940820:20191101114516p:plain

Welcome Notificationは受け取り側で無効にしたためスルーでOK。

Advancedは少し気をつける必要がある。ServiceWorkerでキャッシュしたいページがネストしてる場合ここで設定しないとうまく動かない。今回/mediaでやりたいので以下のように設定する。

f:id:apple19940820:20191101113407p:plain

前と後ろに/をつけないと壊れる。OneSignalSDKWorker.jsとかは自動生成されるCDNからSDKをとってくるためのワーカーファイルで、importScriptsのパスがあーだこーだはこのファイルの話。

ここまでできたらSAVEを押す。するとWeb Push設定用のページに行くのでここでappIdをコピペして、クライアント側のnuxt.config.jsのOneSignalの設定に追記する。

FINISHで設定完了。

プッシュ

OneSignalのヘッダーからMessagesに行ってNewPushを押すと設定画面にいける。

f:id:apple19940820:20191101144812p:plain

適当にtitleとか埋めたらSchedleでいつプッシュするかを決められる。今回はすぐ見たいのでデフォルトのままで。

f:id:apple19940820:20191101114202p:plain

誰に対して投げるか、購読しているユーザー数、内容とブラウザーなどを確認してSEND MESSAGEでプッシュ通知が飛ぶ。

f:id:apple19940820:20191101144824p:plain

いざプッシュ

f:id:apple19940820:20191101144439p:plain

できた

おわり

パス周りでわりとハマったものの受け取り側はモジュール入れて設定ちょっと書くだけで良いしついでにPWA化もできてコスパ良い。(プッシュ通知の是非は置いておいて)

OneSignalも技術的な知見がなくても操作できるコンソールが用意されているのでマーケティング担当者が自由に通知できる。

NuxtとComposition APIとtsxで素振り

した

github.com

setupとtsxを紐づけるため別途プラグインが必要だが、普通にかける。

以下の流れで環境を作れる。

プロジェクト生成

npx create-nuxt-app

必要なモジュールのインストール

yarn add @nuxt/typescript-runtime @vue/composition-api
yarn add -D @nuxt/typescript-build babel-preset-vca-jsx

package.jsonを修正

  "scripts": {
    "dev": "nuxt-ts",
    "build": "nuxt-ts build",
    "start": "nuxt-ts start",
    "generate": "nuxt-ts generate"
  },

composition apiプラグインに登録

滅多にないだろうけど.tsにしとけばtypoが減る。

import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'

Vue.use(VueCompositionApi)

nuxt.config.jsを修正(ついでにts化)

拡張子を.tsに変更

import { Configuration } from '@nuxt/types'

const config: Configuration = {
  buildModules: ['@nuxt/typescript-build'],

  ~省略~

  /*
  ** Plugins to load before mounting the App
  */
  plugins: ['@/plugins/composition-api'],

  ~省略~

  build: {
    babel: {
      presets({ isServer }) {
        return [
          [require.resolve('babel-preset-vca-jsx')],
          [
            require.resolve('@nuxt/babel-preset-app'),
            {
              targets: isServer ? { node: 'current' } : { ie: '9' },
            },
          ],
        ]
      },
    },
  },
}

export default config

tsconfig.jsonをルートに作成

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "jsx": "preserve", // これないと動きません
    "lib": [
      "esnext",
      "esnext.asynciterable",
      "dom"
    ],
    "esModuleInterop": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./*"
      ],
      "@/*": [
        "./*"
      ]
    },
    "types": [
      "@types/node",
      "@nuxt/types"
    ]
  },
  "exclude": [
    "node_modules"
  ]
}

ルートにshimsを置いてtsx用の型を拡張

shims-tsx.d.ts

import Vue, { VNode } from 'vue'
import { ComponentRenderProxy } from '@vue/composition-api'

declare global {
  namespace JSX {
    interface Element extends VNode {}
    interface ElementClass extends ComponentRenderProxy {}
    interface ElementAttributesProperty {
      $props: any;
    }
    interface IntrinsicElements {
      [elem: string]: any;
    }
  }
}

あとはお好みでtypescript-eslintを入れたりする。今回は省略。

書き方

SFCではなくtsxファイルで書く。exportするオブジェクトは createComponent でラップすると型推論が効くようになる。

propsは PropType に型を渡してアサーションすることで型付けする。setup()の第一引数内でも型推論してくれるようになるためpropsが増えまくってもtypoとかはなさそう。第二引数にコンテキストが入っていてemitとか使える。tsxはまあtsxって感じ。

import { createComponent, PropType, reactive } from '@vue/composition-api'

interface IncrementalObjProps {
  buttonText: string
  value: number
}

export default createComponent({
  props: {
    incrementalObj: {
      type: Object as PropType<IncrementalObjProps>,
      required: true
    },
  setup({ incrementalObj },{ emit }) {
    const r = reactive({count: incrementalObj.value})
    return () => (
      <div>
        <div>{r.count}</div>
        <button onClick={() => {
            r.count++
            emit('countUp', { count:r.count } )
          } } >{incrementalObj.buttonText}</button>
      </div>
    )
  }
})

読み込み側では普通にimportしてコンポーネントとして利用できる。SFCから読み込むことも可能。

Composition APIの出来が良くてReactじゃなくVueで書きたいけどテンプレートは嫌いなんだぜって人は良さそう。

余談

サンプルのGanahaBirthday.tsxは微妙に動かないんだけどいまいち原因がわからない。setupが1度しか評価されないのでpropsで渡ってきても変更を追えてない気がする。compositionはスマートにかけてとても良いんだけど今までのVueの直感とは微妙に違う点でハマりそうな気がしてる。

それからComposition APIでやるならTSは必須だと思っていて、Option APIでは必ず値の出所がわかる(methods,computedなど)ようになっていたけどそれがsetup()に埋もれてしまい、どこから出てきた値なのかがコードで追い辛い。型情報があればマシになるだろうという考え。

まだ聴いてないないなら聴いてほしい癖強めなアイマスの曲

アイマスは現行で5つのグループがあり、それぞれに文化、コミュニティが育ち、それぞれのサイクルでCDが発売されているため他のグループに手を出す機会が中々ないかもしれない。

歴史が長いのもあって、意外と知らない曲もあったりする。大体900後半くらいある。

ということで自分がおすすめする、聴いたことがないなら聴いてほしい曲を紹介する。

これみんなもっとやったらよくない?

CRIMSON LOVERS

www.youtube.com

ゴリッゴリのプログレ、マスロック系の曲でアイマス全体で見ても例がない。なので出た時結構注目されて聴いたことがある人は多いかも。

ただしこの曲はフルで聴いてこそ意味がある。すべてがアウトロの疾走感と開放感のためにあり、徐々に王道と言える音になっていく、実は爽やか系の曲だったりする。最後まで聴くとあーアイマスって最高やな…とエモエモになれる。

ベースはUNISON SQUARE GARDEN田淵智也。ベースが田淵の曲みたいな認識はありそう。

アンデッド・ダンスロック

www.youtube.com

音数が少なくてもロックはできるってことですよ。流石に構成がはちゃめちゃなので王道ではないけど、松永涼のボーカルがコード進行が変わって盛り上がる部分でソロで張るとすごく様になってて、狙ってやってるんだろうなーって思った。ちゃんと計算されてボーカルと曲の相性が考えられている。

CRIMSON LOVERSと同様ラスサビを聴くためにフルを聴きたい曲。多分これを聴いた100人中100人ラスサビすきと答えるだろう。

アンドデッドダンスロックはボケる方向性がいい意味でシンデレラっぽくないなくて、照れてない。純情Midnight伝説とか凸凹とかは照れてる部類。

普通に歌うよりアンデッドダンスロックって言う方が楽しいのが問題。

鳥籠スクリプチュア

www.youtube.com

爆音で聴いてほしい。とにかく音がカッコ良い。7つの誓い部分はセリフもあいまってカッコ良すぎてループしてしまうため中々ラスサビまでいけない。これが鳥籠なのか…?

余談だけどアウトロのピアノから蒼い鳥にめっちゃいい感じに繋がりそうな気配ある。

I did + I will

1:57~

youtu.be

コンセプトですでに勝ってる。現代で〇〇年代風の音楽をやろうとすると大体スベる印象があるけど、これは本当によくできてる。というか融合してる。

そもそもEDMで80年代なんてわけわからないんだけど、これはなんかしっくりくる懐かしさがある。「イマジネーション!イマジネーション!」みたいな繰り返しのフレーズとか、「この時代は元気ですか」みたいなワードは80〜90年代終わりまでの、いわゆるテレビの黄金期を思い起こさせる(気がする)

これも余談だけどCD,MDが出る前の時代はカセットテープで、さらに遡るとレコードなわけだけど、容量的な問題でそもそも長い曲を作るとSP盤(45回転盤)に収まらず、なるべく短く作ることが重要だった。安定して録音できて、かつラジオで流してもらうには3分程度で終わらせる必要がある。

そのルールで売れた音楽を聴いて育った人間が真似して同じように短い曲をつくるというサイクルもあったため、時代が進んでも変わらず少ない時間で脳に焼きつくような印象的なフレーズを作るのが流行り、それが繰り返しだったり強烈な短ワードだったりを生み出したというのもあるっぽい。とくに歌謡曲は平均して大体3分弱で終わったり、Aメロ→サビ→Bメロ→サビ→サビの構成で内容がかなりシンプルだったりする。

純情Midnight伝説

www.youtube.com

まずジャケットがダサい。そして歌詞がダサい。音もチンピラ感が半端ない。すべてがしっかりダサいので聴いてると笑顔になれる。一周回ってかっこよく感じる。アウトロを聴くと涙が出てくる。ダサいのに不思議だな?めっちゃ好きです。

炎陣ということでエンジンをカバーしていただきたい所存。

遠藤正明/エンジン MV - YouTube

It's Show

真ソロver

www.youtube.com

THE IDOLM@STER MASTER ARTIST 3 03菊地真

THE IDOLM@STER MASTER ARTIST 3 03菊地真

初出はこっち

THE IDOLM@STER MASTER LIVE 02 REM@STER-B

THE IDOLM@STER MASTER LIVE 02 REM@STER-B

どちらのバージョンもかっこいいが、個人的には先に出た方のが好き。ユニゾンが綺麗で、かつ無骨さも感じられるいいバランスになっている。聴けばわかる。 古いCDだけど意外と買える。

真verはもちろんあのボーカルで既に勝っているが、このCDには「絶険、あるいは逃げられぬ恋」が入っているのもポイント。マジで買ってほしい。

Miracle Night

www.youtube.com

説明不要の名曲。歌詞カード片手に聴きまくってほしい。

夢じゃないんだよね

夢じゃないんだ

夢じゃないんだ!

ずるくないですか?天才か?ちなみに作詞はMC_TCであってイノタクではない。しかしMC_TCとググると井上拓と出てくる。これは一体?

夢じゃない!このミラクルナイト!ヨネスケ

昏き星、遠い月

www.youtube.com

今となっては非常に有名な、ミリシタが覚醒した曲であり個人的には1年目のMVP。劇中劇シリーズの先発で、要所にセリフがあるとおりミュージカル仕立てのかなり変わった構成になっている。ミリオン版の眠り姫と言っても良いかもしれない。色々あって望まないままヴァンパイアになっちゃった男の子と、ヴァンパイアの女の子とヴァンパイアの女騎士とヴァンパイアの女城主のハートレスストーリー。

もしフルで聴いたことがないなら必ず聴いてほしいし、ここからミリオンに入るのも悪くないとも思う。ミリオンの癖が強いのを真面目にやる感じが伝わるいい曲だと思う。

三拍子の曲で、俗に言うずんちゃっちゃをやっている。サビ前からはなりを潜めてバスドラムみたいなのに乗っ取られる。

創造は始まりの風を連れて(朋花ソロ)

The Idolm@ster Live The@ter Solo Collection 06 フェアリースターズ

The Idolm@ster Live The@ter Solo Collection 06 フェアリースターズ

ソロコレクションの1曲。比較的手に入りやすい方。朋花のボーカルは結構特徴あるけど、創造を歌ってる時はかなり別物な感じがあってこれがすごく良い。歌い方がなんかすきなので頑張って手に入れて聴いてほしい。マジでいいぞ!

聖母感はないけどロック寄りの朋花が聴けるいいCD。そもそも曲も良い。

Next Life

自分よくわからないんだけど、Next Lifeは完璧だって思うぞ。だから聴いてみてよね!

あとシャイスマとTrial DanceとBrand New Day! とPon De Beachと天と海の島としあわせのレシピもよろしく!(Rebellionはみんな聴いてそう)

Lost in the Summer

Real Girls Project『THE IDOLM@STER.KR MUSIC Episode2』

Real Girls Project『THE IDOLM@STER.KR MUSIC Episode2』

KRの曲は多分聴いたことがある人の方が少ないと思う。実はアマプラなら聴き放題。 Lost in the SummerはMORでも紹介されていたけど全編英語。

ぶっちゃけ何を言ってるか聞き取れないがそれでも繰り返し聴いてしまうくらいリズムや音色、ボーカルが綺麗で好き。音楽に性別やら言語やら生まれやらは関係ねえんだって100万回言われてるんだよなぁ。

Let's get started

https://www.amazon.co.jp/dp/B077TRDNY7/ref=ap_ws_tlw_alb3

Real Girls Project『THE IDOLM@STER.KR MUSIC Episode5』

Real Girls Project『THE IDOLM@STER.KR MUSIC Episode5』

これもKRから。ぶっちゃけ何を言ってるのかマジで聞き取れないがそれでも繰り返し聴いてしまうくらいリズムや音色、ボーカルが好き。あまり日本にはない曲調な気がする。なんとなく使ってる楽器のせいかバンバードを思い出す。それも好き。

バンバード/mozell - YouTube

ACASIA

Real Girls Project(R.G.P)「THE IDOLM@STER.KR MUSIC Episode 1」 Type-B

Real Girls Project(R.G.P)「THE IDOLM@STER.KR MUSIC Episode 1」 Type-B

もはや何語かもわからない。なんかアカギとか崎陽軒とか言ってる。しかしなんども聴いてしまうくらい(ry

KRはそもそもドラマ自体見たことないので、世界観にマッチしているとか何話のどこにこの曲が流れてきてそれが思い出となって今や思い出すだけで泣けるとか、そういうアイマスあるあるで好きになったわけでなく単純に音楽として好きなものばっかり。(なにせみたこともないので)

ACASIAは強いて言うならサビのフレーズ(あからっか あからしあ♪)が好き。あと全体的に低いところでベースが鳴ってるんだけど鳴りっぱなしじゃなくてリズムに合わせて隙間がある。ブーン[白玉]ブーン[白玉]みたいな?これすき

おわり

結果AS多め。書く動機がAS曲みんなに聴いてほしいなだったのでしゃーなし。シャニとMも別記事でやりたいけど自分が勉強?不足なのでもっとちゃんとしてる人がちゃんとやった方がいいかな。むしろ教えてほしい。少し聞きかじった感じではシャニはビーチブレイバー、MはROMANTIC SHAKERとかがよかった。(2の時から北斗が好きです)

そのグループで活動してるなら聴いたことくらいあるよって曲と、そうでない曲両方出してみた。特にASの曲は年月で埋もれがちなので定期的に掘り起こして伝えていこうな。

ミリオンのワンナイトクルーズはガシャと比べてコスパが良いのか確認する

クルーズのステートプランがミリシタのガシャ天井より安いと話題なので、ガシャと比べてどれくらいお得なのかをざっくり調べてみる。

ガシャは狙いのSSRが出るまで引くものとすると、"好きなSSRが出る期待値"とクルーズの値段を比べてクルーズの方が下回っている場合ガシャよりコスパがいいとする。

前提条件

クルーズ側

  • ステートJ3名利用(61,600)

ガシャ側

  • SSRの排出率3%
  • ピックアップ排出率0.495%
  • 天井あり
  • 有償ジュエルのみ(消費税増税後)

計算に利用するサイト

ガチャの期待値の計算(天井付きガチャ用) - 高精度計算サイト

結果

f:id:apple19940820:20190924134439p:plain

クルーズの値段61,600円に対してSSRの期待値の値段は46,455円となった。期待値計算ではSSR取得の方がコスパが良いように見える。

しかしSSRは出た時点で実質無料となるためクルーズはガシャに比べ61,600円お得である。

おわりに

100万払っても買えないものが船にはあるはず(ドヤァ

NuxtMeetUpに登壇してきました

これに株式会社ROXX枠でLTしてきました。Composition APIについて、Nuxtと合わせて素振りした感想みたいな感じ。

nuxt-meetup.connpass.com

スライド

slides.com

初LTの割にはうまくやれたかなと思います。poaroファンとしてアナ尻遵守を心がけましたが15秒漏れました。(そもそも押してたけど)

懇親会でも色々な方と喋る機会があり色々と収穫があって良かったです。半分以上ラジオ/アイマスの話が流れるTLですがTwitterフォローしてくださった方はありがとうございます。

内容ですが意外とfunction api、つまり現composition apiについて知らない方が多かったなという印象です。まあまだRFCですし、プロダクトでのみVueやNuxtを使っている人には無用の長物というのはそれはそうなのでこんなもんかなーと。

このスライドは2週間前には完成していて、直後(ちょうど自分の誕生日)にNuxtが2.9にあがってしまい、TS周りのことも書いていたためかなり修正に時間をとられてしまいました。

さらに言うとこれは登壇後に気が付いたんですがvue-function-apiがcomposition-apiに変わっており、apiもいくつか変更されていたりして帰宅してから慌てて使用済みスライドを直すなどなかなかな体験でした。

composition apiのドキュメントまであります。(まだ薄めだけど)

vue-composition-api-rfc.netlify.com

こんな感じで簡単に破壊的変更が起こるのがこの界隈の今って思ってます。今の主役はVue3.0で、それに向けて周りが慌ただしく動いている最中です。 それでも現時点でcomposition apiの出来に関してはとても良いなとは思っていて、よく関数でやるならReactでよくないかと言われますが、言うのもまだ時期尚早な段階でcomposition apiがどういった変化をVue界隈にもたらすのかちゃんと観測してからそういうのやろうね、というのが自分の意見です。(何を言うのかは個人の自由です) 面白いおもちゃが手に入るんだからやってみようぜっていう。

Reactには似たAPIにReact Hooksがありますが、お試しで出てからの期間を考えるとユーザーに根付くまで十分な時間が経っています。Vueユーザーにはこの「HooksのようなAPI」について勘所や知見などまだ何もないのが現状で、ここが成長し成熟していくのがコミュニティであり技術だと考えています。何が言いたいかと言うと俺と一緒に人柱やらないか?ってことです。

何はともあれ数百人規模のイベントが無事に終わり、しっかり撤収まで出来たのは会場を提供いただいたメルペイの皆様のおかげですし、静かに見守っていただいた来場者の皆様のおかげですし、弊社開発チームとCTOメンバーのサポートあってのことですね。自分一人だけでは何もかも経験できないことと感じました。

次があればまた登壇したいです。あまりにも会社の話をしてなくてアレだったので今度はそっちよりの話ができればいいかも。

イベントレポート

techblog.scouter.co.jp

おわりだよ〜

Svelte3のストアを触ってみる

自分が書いたタイミングがv3リリース後すぐだったので今のSvelteと差異があるかも。

svelte.dev

つくったやつリポジトリ

github.com

つくったやつ

ushironoko-svelte-sample.netlify.com

つくったってほどでもないけど一応netlifyに投げた。

消えるフレームワークことSvelteが少し前にv3になったということで、少し前に触っていた。中でもstore周りが面白かったのでメモがてらに書き起こしてみる。

Svelteとは

Write less code、No VDOM、Truly reactiveを掲げる新し目のWebアプリケーションフレームワークで、ビルドするとランタイムが消える。つまりプレーンなjsアプリケーションとして動かすことができる。いつの間にかランタイム実装周りがTS化してた。

面白いのはSvelte本体がstoreを内包しているところで、実装自体も200行弱ととてもシンプル。

github.com

Svelteでは.svelteファイルの中にscriptとhtmlの双方を書くことができる。例えばカウントの値をstoreに管理させるコードはこうなる。

<script>
    import { count } from '../store/stores.js'
    export let incrementalButtonText
    export let decrementalButtonText
    export let resetButtonText
</script>

<p>count: {$count}</p>

<button on:click={count.increment}>{incrementalButtonText}</button>
<button on:click={count.decrement}>{decrementalButtonText}</button>
<button on:click={count.reset}>{resetButtonText}</button>

こんな風にscript内にロジックを記述して、外にJSXライクなマークアップを書く。これはボタンコンポーネントとしての実装だとして、ルートコンポーネントで使うときはこう。

<script>
    import Buttons from './components/Button.svelte'
    let incrementalButtonText = ' + '
    let decrementalButtonText = ' - '
    let resetButtonText = ' 0 '
</script>

<Buttons {incrementalButtonText} {decrementalButtonText} {resetButtonText} />

子でexportした変数を親からpropsで渡す。結構独特な記述。

肝心のstoreはこうなっている。

import { writable } from 'svelte/store';

function createCount() {
  const { subscribe, set, update } = writable(0);

  return {
    subscribe,
    increment: () => update(s => s + 1),
    decrement: () => update(s => s - 1),
    reset: () => set(0)
  };
}

export const count = createCount();

svelte/storeから必要なAPIをimportする。例えばwritableは初期値を渡すとsubscribesetupdateの3つを吐き、それぞれリアクティブに動作する関数を定義することができる。

ユニークな点としてreadableという読み取り専用ストアとderivedというストアを派生させるAPIが用意されている。派生させたストアは依存関係が更新されると引数にとったコールバックが実行される。

https://svelte.dev/docs#derived

TSで再実装されているのでTSで書けばストア周りの型が効くはず。

所感

シンプルかつ高速で型も効いて良さげ。store周りはコンポーネントごとに状態管理を持つ感じで、最近流行ってるやつだとは思う。

バケツリレー時のemitの記述量が少なくなるようなアプローチをとっている点もユニークで面白い。またアニメーション、モーション、トランジション等のサポートもコアに含まれているので、Vue飽きたなって人はこっちでそういうのやってみても面白いかもしれない。

すぐに試してみたい時は公式チュートリアルがあってブラウザ上で色々学べる。a tour of go的な。

svelte.dev

あとは公式REPLがあってこれもブラウザで試せる。

svelte.dev

ちなみに読み方はスヴェルテっぽい。フランス語でシュッとした的な意味らしい。

ミリシタAPI Princess の型定義かいた

書いた。

github.com

別にDefinitelyTypedとかにはあげてないしパッケージ化もしてないので使うときはクローンするか、index.d.tsをコピペでよろしく。

ドキュメントの型を型定義ファイルに落としただけ。

api.matsurihi.me

でれぽとかはやってなくて、あくまでミリシタのAPI部分のみ。やりたい人はPRで。 でれぽだけじゃなくて普通にissueとかもあればどんどん投げてください。周年イベラン中に書いたから自信ない。

使い方

types/princessとか切ってそこにindex.d.tsを配置、使うところで必要な型をimport

以下の設定をtsconfig.jsに書くといちいちディレクトリ構造を書かなくてもよくなる

"baseUrl": "./",
"paths": {"princess": ["types/princess"]},
"typeRoots": ["types", "node_modules/@types"],
import { Cards } from 'princess'
import axios from 'axios'

const card: Cards = axios.get('https://api.matsurihi.me/mltd/v1/cards/250')

みたいな。

レスポンスの型定義のみなのでメソッドとかはない。気が向いたらクエリメソッドの型も書くかも。

Role-Based Access Control (RBAC) をVue.jsで表現する

元ネタ

auth0.com

最近仕事で権限ごとに表示できるコンポーネントを制御する必要がでてきて、さてどうするかというタイミングでチームメンバーがRBACのことを教えてくれた。

Roleは1つ以上の権限を持ち、権限はコンポーネントの表示を制御する。まあ難しい考えかたは必要なくて、単にロールと権限の定義と、ログインユーザーのロール、コンポーネントを表示できる権限があれば簡単に実装できる。

以下は動的な制御が不要な場合の例

rbac.js

import rules from "./rbac-rules"

const check = (role, action) => {
  const permissions = rules[role]
  if (!permissions) {
    // ロールが存在しないためfalse
    return false
  }

  if (permissions.includes(action)) {
    // ロールが渡された権限を持つためtrue
    return true
  }

  return false
}

export default check

rbac-rules.js

export default {
  visitor: [
    'contents_read'
  ],
  writer: [
    'contents_read',
    'contents_update'
  ],
  admin: [
    'contents_read',
    'contents_update',
    'user_update'
  ]
}

Vueではslotを使ってコンポーネントを渡し、中でcheckで権限を見て出し分けると良い感じになる。そのためのラッパーコンポーネントを作る。

Can.vue

<template>
  <div>
    <slot v-if="checkRule" name="yes" />
    <slot v-else name="no" />
  </div>
</template>

<script>
import check from '~/auth/rbac'

export default {
  props: {
    role: {
      type: String
    },
    action: {
      type: String
    }
  },
  computed: {
    checkRule() {
      return check(this.role, this.action)
    }
  }
}
</script>

これで一応コンポーネント2つ渡せば権限NGだった時に任意のコンポーネントにフォールバックさせることができる。不要なら2つ目は渡さなくても良い。

Can.vueを使った例

Hoge.vue

<template> 
 <div>
    <Can role="visitor" action="contents_read">
      <template #yes>
        <Text text="権限あるよ" />
      </template>
      <template #no>
        <Text text="権限ないよ" />
      </template>
    </Can>
  </div>
</template>

<script>
import Can from '~/components/Can'
import Text from '~/components/Text'
export default {
  components: {
    Can,
    Text
  }
}

今回の場合ロールが複数あると判定できないので、ロールを配列で渡してキーとマッチングして取れた配列を単一の配列にマージする、もしくは同じことをするreducerを書くとかする必要がある。ロールはpropsじゃなくてCanからstoreを見るなりしても良い。

また、動的な権限制御が必要な時は定義にstaticとdynamicの概念を追加する必要がある。元ネタの方に載っているので興味ある人は実装してみると良いと思う。

おわり

Flutter始めたので導入周りメモ

Flutterがfor webを発表し名実ともにマルチプラットフォーム対応になったのでいっちょやるかと思い立ち、環境構築した。環境はmacOS64bit。

flutter.dev

FlutterはDartという言語を用いてマルチプラットフォームGUIアプリケーションを作ることができるGoogle製モバイルアプリケーションフレームワーク。モバイルとはいえ昨今はWebもモバイルファーストばかりなので問題なし。

環境は基本公式のドキュメントを見ながらやれば特につまづくことはないはず。

flutter.dev

今回はユーザーの下に落としたzipをunzipした。Goも同じ場所にあるしここでいいかみたいな感じで。ほんとはDeveloper直下とかのが良いはず。。。

パスを通すとflutterコマンドが使えるようになる。手順にはexportでやるとあるけど揮発するので.bash_profileに追記する方が良い。

その後はflutter doctorで足りない依存を検査してくれる。これがかなり親切で、○○が足りないから××をやれと教えてくれる。

自分の場合はAndroid Studioが入っていなかったので、以下のようになった。

f:id:apple19940820:20190512194328p:plain

VSCodeは入ってる人多いと思うけどなかったら最新版入れる。入れるだけでOK。

Visual Studio Code - Code Editing. Redefined

Android SDKのためにAndroid Studioを入れる。

Download Android Studio and SDK tools

Android Studio入れるだけではダメで、FlutterプラグインDartプラグインが必要らしい。セットアップ後pluginsからマーケットプレイス開けるのでそこでFlutterを入れるとついでにDartプラグインも入る。

f:id:apple19940820:20190512200037p:plain

あとxcodeのインストールが不完全とかbrewで色々いれろコマンドはこれだとかとにかく親切。よっぽど酒が回ってない限りは大丈夫なはず。

自分はターミナル分割して上で逐次doctorしながら下でbrewで必要なものを入れてインストーラあるやつは別でみたいな感じで作業を進めた。昨今はインストール作業自体軽くなってて同時に進行してもクソスペックPCじゃなければ固まることもない。(ブログも並行して書いてる)

f:id:apple19940820:20190512200400p:plain

特にcocoa podsのセットアップは時間かかるので先にやった方が良い。XCodeはクソ重くて後回し。

connected deviseは適当なスマホをPCに繋げればいい(はず)。色々やってもだめならflutter doctor -vで認識する(はず)。

自分のflutter doctor -vの結果

f:id:apple19940820:20190512203621p:plain

もろもろセットアップが終わったらflutter createでプロジェクトを生成でき、flutter runで起動するが、xcodeで署名を作った少し設定をいじる必要がある。詳細は以下が詳しい。実機で動かしたい場合も参考になる。

qiita.com

f:id:apple19940820:20190512203740p:plain

使うエディタは公式的にはAndroidStudio or Intelli J or VSCodeVSCodeがお手軽だしWebから来た人はflutterプラグイン入れるだけで良くておすすめ。プロジェクトを生成すると以下のような構成になる。

f:id:apple19940820:20190512204632p:plain

今気づいたけど、VSCodeは刺しているデバイスを検知して表示してくれるっぽい。

f:id:apple19940820:20190512204759p:plain

VSCodeのコマンドパレットでflutter Lunch EmulatorとするとAndroidか、iOSエミュレータが勝手に起動する。

Webを始める場合はflutter New Web Projectで作れる。すごい。

f:id:apple19940820:20190512210224p:plain

デプロイは面倒でまだやってない。けどドキュメントに各プラットフォーム向けに書かれている。

あとはDartゴリゴリ書いていくだけ。頑張ろう。

おわり

auto chessやろう

面白いので皆やりましょう

Dota2のおまけみたいな感じなのでDota2入れればできます。Dota2は無料なのでauto chessも無料です。

store.steampowered.com

mobile版も出るらしいのでそれまでに触っておくと流行にいい感じに乗れます。

確実に流行ります。ゲーム性が日本人に向きすぎていて、しかも無料。無料の麻雀。正直グウェント初めて触った時より感動してる。

絶対流行ります。海外の有名配信者はこぞってauto chessやってます。(AmazとかAsmodaiとかSavjzとか)

日本でもハースプレイヤーやシャドバプレイヤーが徐々に始めてます。今後auto chessの経験が長くて環境を良く知っている、または知識が深い配信者のauto chess入門動画が死ぬほど再生されるでしょう。

日本で競技化されるかは知りませんが、既にそういうのをやっているところはあります。詳しくはWikiで。

まあ、色々書きましたけど超面白いからやった方がいいぜ

おわり

令和最初の○○

令和最初の

聴いたラジオ

鷲崎健のヨルナイト×ヨルナイト

www.joqr.co.jp

書いたコード

github.com

born-the-reiwa.netlify.com

開いたウェブサイト

Twitter

twitter.com

投稿したツイート

いいねしたツイート

開いたゲーム

シャニマス

shinycolors.enza.fun

観た動画

www.nicovideo.jp

読んだ本

蒼き鋼のアルペジオ 17巻(Kindle

聴いた曲

I did + I will

youtu.be

(危く三角音源になるところだった…)

見た画像

https://cdn.discordapp.com/attachments/514369806351335431/572799479900536837/suga.jpg

笑い

和藤渚さんの三角音源

久しぶりに聴いたけどまだマイク吹いてて安心感あった

終わり

旧時代の人間として生きていきましょう

SI→スタートアップで成長感じる系男子

男子です。3月末で2年お世話になった会社を辞めてニートになろうと意気込んでいたらおかんに殴られそうになったので転職活動して今は東京のスタートアップでインターンとして働いてます。

元々はJavaとかC#でバックエンド書きつつたまにマークアップが仕事だったりだったんですが、今はほぼフロントエンド専門でじょいんしてます。3週間くらいたったのでお気持ち表明です。

なんでインターンかっていうと前職と働き方が大きく違うので様子見という感じです。僕が採用でも同じ事します。理にかなっとる。

成長を感じる

やんわりと感じる事もあればレベルアップの音がすることもあります。前職はゴリゴリのSI企業だったし全力ウォーターフォール(たまに逆流)みたいな感じでそれも愉快でしたが、今はスクラムやってます。

何もかも違う、正直初♡体♡験な事しかなくて覚えるの大変(特に業務面のドメイン知識)だけど、滅茶苦茶楽しい。良い刺激になってます。

開発メンバーやスクラムマスターに助けてもらいつつ、フロントエンドに関する部分は自分から提言してチームも真剣にそれを受け止めてくれてます。

スクラムではインクリメントという、そのスプリントで何を達成したかを明確にする目標みたいなものがあるんですが、「成長を感じた」をインクリメントとするなら自分の場合はこんな感じです。

  • GitHub使ったチーム開発ちゃんと覚えた

  • スクラムの基本的な流れを覚えた

  • Vue.js/Nuxt.jsの良い設計悪い設計が分かるようになってきた

ここら辺は個人の価値を直接あげるタイプの成長なので自然と身についていったのがありがたかった。設計の良し悪しは中規模以上の開発現場に入ってコード見て初めて合点がいったって感じでした。

知識として知っていたものが実際目の前に現れて辛い気持ちになった延長で直し方まで察せるようになってきた。分かりやすく成長したなと思えました。

結構早めに気が付いたことがあってスクラムとも関連するんですけど、出社してすぐその日のうちにやる事を明確にしてチーム全員が知っている状態にしておくと良いです。これやっとくと何が身に付きそうとかこいつどこまで出来るようになったんだとか全部透過的になるのでひじょーーーに健全です。そして金曜は感謝と共に終わる。素晴らしいね。

分報はいいぞ

自分はかなりお喋りな方だと思ってますが、それ以上に書く事が好きです。自由に書きなぐっていいし困ってそうだったらヘルプ貰えるチャットとして分報を書きまくってます。

まだ数週間しか働いてなくて、既存のコードとかに手を入れる場合結構深掘りしなきゃいけないんですが、脳内で出てきたワードは全部分報に出します。書きすぎて流れて行ったらコピペして戻します。つまり分報とは遊戯王でいう墓地みたいなもので、第二の手札なのです。つまり強い。墓地利用しないデュエリストおるか?おらんやろ。

人の分報をのぞくのも結構面白く、自分みたいにあーとかうーとか分報書いてからコードに落とす人もいれば〇〇終わった、プルリク出す。みたいな感じの人もいます。

流れていっちゃうのが勿体ないのでピックしてGistあたりに置いておけるといいなと思いました。勿論privateで。じゃないと脳直で書けなくなりそう。

余談:Vue/Nuxtの話

というよりVuexの話。実際に中規模以上のNuxtやVueアプリケーションを見て感じる事は、Fluxが守られてないことがままあるということ。僕自身はインターンやるまでフロントエンドを完全に独学でやってたので、どこまで通用するかという面で不安は感じてました。実際現場に入ってみると苦労はするものの読める。書かれた意図も何となく掴めて、どうすれば受け入れ条件を達成できるのかも大体浮かぶ。

みたいな感じなんですが、Vuexが本来の思想から大きくずれていると難易度が跳ね上がります。単一方向フローが破壊され、変更による影響範囲が分からなくなり、状態そのものが信頼できないものになります。Vuexは使う事ではなく守る事が大事なんだと。

ぶっちゃけmapStateはAPIごと消して欲しい。Flux守ってたらGettersで良いはずなので。

中規模開発で沢山関数書いて分離とかしてるとVuexに似た何かみたいなのが出来がちです。apiエンドポイントをまとめて外出しした場合、呼び出しは必ずコンポーネントかVuexのactionsでやりましょう。VueにはローカルステートとVuexの2種類しか状態が存在しないことを魂に刻んでおくと平和だと思います。

余談:TOKYOは高い

まず飯が高い。んで家賃が高い。友人宅に転がり込んでるから関係ないけど、家賃聞いてびっくりした。びっくりしたのでSEKIRO買ってあげた。

パンの安さに気付いた。米は高い。ローソンの500円で買える大盛パスタのコスパに感謝。

東京在住の方々、よく生きていけますね。こんなに違うのかと正直引いてます。友人はインターン始まる前に東京は住むとこじゃねえって何度も言ってましたが身に沁みました。食費追いつかない。。。

でもUber Eatsは神です。外国人の配達に部屋番教えたらThanks!と返ってきましたが日本人は今のところ返答なしです。人情だね。

余談:退職当月の給与は死ぬほど低い

社会保険2回分と住民税引かれて6000円くらいでした。GWでクレカの引き落としが5月まで伸びてなかったら即死だったぜ。神に感謝。

おわりに

経歴弱いしアウトプットも大したことない僕を拾ってくれたことに感謝してます。見てるか知らんけど前職の人、僕は元気ですのでご心配なさらず。

Vue.jsで全然使ってない機能とかが割とあるって思って

吾輩はなんか使ってない/使う機会がないみたいなVue.jsの機能がある。理由はまだない。

最初に言っちゃうとグローバルで使うようなのは殆ど書いてない。Vue.useくらい?

filter

<!-- mustaches -->
{{ message | capitalize }}

<!-- v-bind -->
<div v-bind:id="rawId | formatId"></div>
filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

マスタッシュ{{}}かv-bindでパイプ演算子をフィルタにかけたいdataに繋げていくことで使える。パイプは複数連結できて、前から順番に通る。

便利じゃん。なんで使ってないんだろう?って思ったけどdataの加工は全部computedでやってるからかな。よくなさそう。使おう。Vue.filterで使えばグローバルに定義もできる。こういうのはグローバルに生えてても良いのかもしれない。目的が明確だしね。

mixin

// `myOption` カスタムオプションにハンドラを注入する
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})

new Vue({
  myOption: 'hello!'
})
// => "hello!"

嘘です使ってない理由あります。グローバルmixinは主語がデカくて嫌。スコープを持てない奴は万死。みたいな感じ。なんかそういう事するときはprovideinjectがあるのでそっち使う。

jp.vuejs.org

一応、Vue 3.0からmixinを経由してもクラスAPIでの型が消えないようにはなってるらしいけど。。。使う気起きないな。

observable

const state = Vue.observable({ count: 0 })

const Demo = {
  render(h) {
    return h('button', {
      on: { click: () => { state.count++ }}
    }, `count is: ${state.count}`)
  }
}

2.6から追加された新参者、今後超重要なポジションに付く予定の逸材。しかし書いたことはない。新しいから仕方ないね。

簡単に言えば渡したオブジェクトをリアクティブにできるという機能。オブジェクトは再帰的に探索され、Object.definePropertyを通ってgetterとsetterが生える。2.x系では渡されたオブジェクトを直接弄るが3.0以降は別オブジェクトが返るようになる。

何故この機能の存在が重要かというのはVue.jsのrfcを眺めて見ると何となくわかる。

github.com

ワクワクするrfcだがあまり反響がないように感じる。。。何故。。。

render

render: function (createElement) {
  return createElement('h1', this.blogTitle)
}

所謂描画関数。ReactみたいにJSXがさらっとかける訳でもなく、そもそもtemplate捨ててる時点でVueの良さが死んでる気がして中々手を出し辛い。

templateにfunctionalって書く奴は稀に使う。あれはいいよね、なんか軽そうだし(適当)

Vue 3.0でfunctional componentは遂にただの関数になります!って言われてたけどよく分からない。そうですか。。。

updated

updated: function () {
  this.$nextTick(function () {
    // ビュー全体が再レンダリングされた後にのみ実行されるコード
  })
}

ReactのcomponentDidUpdateに相当するって考えると出番多そうだけど、何故か一回も書いたことがない。

コード例のように$nextTickで子のコンポーネントの再描画を待つことが出来る。便利。しかし書いたことはない。createdmountedは頻繁に書くのにね。

思うに値の変更監視はcomputedでできるVueでは更新時の処理を更新時のライフサイクルメソッドで書かないことが多いんじゃないかと。自分だけなのかな?

ref

<!-- vm.$refs.p は DOM ノード -->
<p ref="p">hello</p>

<!-- vm.$refs.child は child-component のインスタンス -->
<child-component ref="child"></child-component>

全く使った事がないわけではないけど、めったに書かない。要するに子への直接的な参照が欲しい時にrefへ公開させアクセスする。

konva系のライブラリを触った時にcanvasへの参照が必要で書いた。なんかやんちゃ方面なAPIって気がしてる。少なくとも連打して良いもんじゃない。参照を持つってそいつに束縛されるって事だもんね。

cloak

<div v-cloak>
  {{ message }}
</div>
[v-cloak] {
  display: none;
}

上記はv-cloakが付いたDOMはVueインスタンスコンパイル終了時まで見えなくなる。v-cloakCSSと組み合わせて、インスタンスコンパイル終了まで残り続けるcloakを作ることが出来る。(cloakってマントって意味らしいよ)

なにこれ便利じゃん知らんかったわ。使います。

おわり

細かい所言うとVue.versionとか全く使わないけど流石にスルーで。APIのページは結構読んでるつもりだけど知らないのもあって面白かった。

Vue 3.0になった時にまた大きく更新されるだろうし、それも楽しみですね。早くこないかな~~~~~~~~~~~~~~~

おわり

暫くTOKYO

です。インターン行ってきます。

フロントエンドのおしごとします。楽しみです。

東京おうち高いです。暮らすだけでせいいっぱいです。友達がいてよかったと思います。

自宅のPC達ともしばらくはお別れです。それが一番寂しいです。こんなに愛しているのに。

ブログは普通に更新するしMacもってくからコードも書けるのでリクエストあれば対応します。

おわり

最近のミリシタカード事情、スコアタとか

別に研究してるわけでもないので自分が感じていることだけ。間違ってたらTwitterのリプかなんかで言ってくれれば直すし、GitHubでプルリクもOK。

github.com

それから旧フェス限(紬、歌織)と特化限定を比べた時の差の情報も欲しい。わかる人教えて。

スキルについて

先日フェアリー組のフェス限が追加され、これでALL楽曲のサポートメンバーがすべてフェス限で埋まるようになった(と思う)。

センター効果は通常のタイプバフ90%、1色限定編成時タイプバフ95%の2種。

スキルは信号機とPFが持つダブルブースト(以下DB)と、通常のコンボボーナスより少し強い28%バフのフェス限コンボナ(以下Co)がある。

VoDaVi別にまとめると以下のようになる。(Exは省略)

Vo Da Vi 合計枚数
Fa 90%/Co,95%/DB (95%/Co)*2 95%/DB 5
An (95%/Co)*2 95%/DB 90%/Co,95%/DB 5
Pr 95%/DB 90%Co,95%/DB 95%/Co 4

全種95%編成ができるようになり、各タイプ2か所ずつDB持ちを組み込むことができる。

また、Prを除き強化Co持ちを2枚使う事ができる編成もある。

スコアについて

色々な計算式はググれば全部出てくるためここでは省略。計算結果から見て取れる傾向のみに触れる。

当然DB持ちを編成すると理論値は大幅に上がる。PF組が追加されるまでは総アピール値の差もあり「DBを編成に組み込むと理想が伸びて1%~周りが落ちる」という状況だったが現状はアピール値の差が詰まり、DB持ち編成が上回るケースもある。これは志保+伊織のFaDa編成と、貴音+紬のFaVo編成、静香編成等を比べると分かりやすい。

ミリシタにおいてスキル発動率の上限が40%である限り(発動しない確率の方が高い限り)「発動したら強い」カードよりも「発動しなかった時のロスが少ない」カードの方が重要視される。7秒間隔で4秒間発動するスキルが強いという理屈はこれ。

しかし、「7秒は強い」は真だが「7秒より13秒は弱い」は偽。また「偶数秒は弱い」も違う。楽曲の長さによって7秒スキルとの相性は変わるため、ある曲では探偵紬の方がスコアが伸びるけどある曲では限定ロコの方が伸びるという現象は平気で起きる。

基本7秒/4秒や9秒/5秒のようなコスパの良いカードは強いため即採用される。スコア2:コンボナ2~3(orコンボナ2: DB1)のバランスがもっとも良いとされている現在では相方のカードを変更する事が多いが、これは楽曲の長さに合わせなければロスするので注意。ここら辺は書き始めると面倒だから今はスルーで。

コンボナ3>スコア3の理屈はWikiで(誤差)

スコア計算

今後引かなければならないガシャ

特化ステータスカードを所持しているか否かが大きく影響する状態だが、今後はすべてのパターンでこれが発生しかねないためスコアタに影響のないカードだから引かない戦略がし辛くなった。全パターンで95%センター編成できるようになった影響。

今のところ優先順位は以下のようになる。

引いた方が良い

  • 特化ステカード

スルーして良い

  • フェス限と被る発動率のコンボナ

特化ステ律子の例を見ると7秒/4秒と9秒/5秒の特化ステータスカードは一度確保すれば半年以上使っていける。

それ以外は楽曲ごとに対応できるよう1枚は持っておきたい。

旧フェス限カードについて

冒頭でも触れたが、旧フェス限カードの性能はいつか通常限定SSRに追い抜かれる。

対象はフェス限の紬、歌織、星梨花、エミリーで、全員28%コンボボーナス持ち。特化ステータスのインフレが進んで26%コンボナでもそっちを使った方が良いみたいな状況になればフェス限だとしてもリストラする羽目になる。まだ先だとは思うけど気にしておくと良いかもしれない。