Nuxt + TypeScriptで

個人アプリを作って

得られたTips

v-sapporo MeetUp #2

2019.9.6.Fri 山田 典明

パンセのwebサイトにツッコミを入れることを勤しんでおります

@noliaki

話すこと

  1. 何を作ったの?

  2. なんで作ったの?

  3. 使ってる技術

    1. サーバーサイド

    2. クライアントサイド

  4. Tips

  5. まとめ

何を作ったの?

なんで作ったの?

こんなアプリを

作ってみたかったから

こんな技術を

使ってみたかったから

  • Dockerで開発環境を構築したかった

  • Nuxtのサーバーサイドのスクリプトを書きたかった

  • DBと連携させたかった

使ってる技術

TypeScript

Nuxt

サーバーサイド

  • express

  • Socket.io

  • TypeORM

  • MariaDB

  • ImageMagick

クライアントサイド

  • Socket.io-client

  • tailwindcss

アプリの起動は

ts-nodeを使用して

起動しています

Tips

docker遅い

  • 最初、alpine Linuxにnode、ImageMagickをインストールしてNuxtを起動させていたが、起動も変更検知も色々遅いので開発体験は良いものではなかった

  • dockerはmariaDBのコンテナだけ起動させて、nodeとImageMagickはMacにインストールして開発した

pathが解決できない

tsconfig.jsonで

こんな感じに設定してあげれば

こんな感じで読み込めるはず

\(^o^)/

issue発見

-r tsconfig-paths/register ってオプションを付与して起動で解決

tsconfigのmoduleが

サーバーと

クライアントで

違う

サーバーサイドはcommonjsで

クライアントサイドはesnextで

コンパイルしたい

怒られる

  • サーバーサイド用、クライアントサイド用でtsconfigを分けることも考えた

  • でも、moduleのみ変更したいだけなんだよなぁ…

  • と思って、いろいろ調べてたら

あった

Nuxtの起動コマンドは

TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' ts-node -r tsconfig-paths/register ./server/index.ts

こんな感じになった

サーバーサイドのスクリプトも

保存したら

Nuxtを再起動させたい

Nuxtはnodemonを使って

nodeを走らせてる

今回はTypeScriptで

書いてるので、

TypeScriptを走らせる

nodemon.json

{
  "watch": ["server", "./nuxt.config.ts", "src/serverMiddleware"],
  "ext": "ts",
  "env": {
    "TS_NODE_COMPILER_OPTIONS": "{\"module\":\"commonjs\"}"
  },
  "exec": "ts-node -r tsconfig-paths/register ./server/index.ts"
}

これでサーバーサイドも

保存したらNuxtが

再起動される✌️

vuexの型

  • Nuxtってかvuexの型について結構色々苦労話が多い印象

  • いろんな方法で何とかしようと思ったが、とりあえず完成までやりたかったので、ものすごく雑な方法でなんとかした

export interface State {
  socketId?: string
  roomName?: string
  status: Status
  stream?: MediaStream
  selectedFrameIndex?: number
  paused: boolean
  decided: boolean
  animationFileName?: string
  videoScreenCanvas: HTMLCanvasElement | null
}

src/store/signage.ts

import Vue from 'vue'

if (!('$signage' in Vue.prototype)) {
  Object.defineProperty(Vue.prototype, '$signage', {
    get(this: Vue) {
      return this.$store.state.signage
    }
  })
}

if (!('$controller' in Vue.prototype)) {
  Object.defineProperty(Vue.prototype, '$controller', {
    get(this: Vue) {
      return this.$store.state.controller
    }
  })
}

src/plugins/inject.ts

import Vue from 'vue'
import * as Signage from '@/store/signage'
import * as Controller from '@/store/controller'

declare module 'vue/types/vue' {
  interface Vue {
    $signage: Signage.State
    $controller: Controller.State
  }
}

@types/nuxt.d.ts

余談

注: @hiro_41さんの

パクリです🙇‍♂️

  • アプリを作ってる途中で3Dに出来ねーかなーって思った

  • すぐ思いつかなかったので、とりあえずいいやってなってた

深度マップさえ自動生成出来れば何とかなりそう

ごめんなさい、Reactで作りました

(最近Reactにもハマってて)

  • Tensorflow.jsを使って人物(の部位)を検出

  • そこを白っぽくしてあとは黒っぽくしただけ

  • たぶん、深度マップを生成するモデルは存在するはず

  • でも機械学習全然わかってないので、どうやって利用すれば良いかもわかってない

    • → 勉強あるのみ

まとめ

個人制作のすすめ

  • フロントエンドの開発に限って言えばDockerを使うまでもないかな

  • TypeScriptにすることで、躓くことがまぁまぁある

  • 型の恩恵を受けれるのは、やっぱりすばらしい

  • 昔から母親に「かたづけなさい!!」って言われてた意味がようやく身を持ってわかった

  • サーバー、クライアントサイドとNuxtに全部突っ込んだけど、これはこれで便利なんだけど、規模が拡大していくようなものには不向きだと思った

    • 例えばフロントエンドでNuxtよりも最適なフレームワークが出てきた場合、Nuxtから乗り換えることが結構たいへんになる

  • ちょうどNuxt2.9が出たので、試してみたら動かなくなった

    • たぶん、サーバーサイドのスクリプトのせいだと思う

    • サーバーサイドのスクリプトを書いていないNuxt案件は2.9でもすんなり動いたので…

  • 新たな目標が見つかる

    • テスト書く

    • 機械学習について勉強してみる

  • 実際に手を動かしてみないと見えてこない問題がわかる

ご静聴

ありがとうございました

deck

By noliaki

deck

  • 1,454