$30 off During Our Annual Pro Sale. View Details »

Vuexに型を付けるパターンを調べた #gotandajs

Vuexに型を付けるパターンを調べた #gotandajs

mizuki_r

July 26, 2019
Tweet

More Decks by mizuki_r

Other Decks in Technology

Transcript

  1. Vuexに型を付けるパターン
    を調べた
    2019/07/26 Gotanda.js #12 @mizuki_r

    View Slide

  2. @mizuki_r
    弁護士ドットコム株式会社
    税理士ドットコム事業部/開発チーム
    チームマネージャー
    2
    自己紹介
    PHP, Vue, Nuxt, Management,
    Recruitment, etc…

    View Slide

  3. 今日のお話

    View Slide

  4. 運用中のサービスに
    Vue+TypeScriptを導入した話

    View Slide

  5. ーーを、しようと思ったが…

    View Slide

  6. Vuexの型付けで悩み…

    View Slide

  7. 今日までに
    結論が出せなかった…

    View Slide

  8. ーーので、
    Vuexの型付を調べた話
    をします

    View Slide

  9. 免責事項
    • 個人の見解に基づく発表であり組織・団体の主張する意見
    ではありません
    • 業務の片手間でググった範囲なので最新の情報ではない可
    能性があります
    • 時間の都合上、各ライブラリの型定義までしっかり読み込
    んできたわけではないので間違いがあるかもしれません
    • 予めご了承ください

    View Slide

  10. 背景

    View Slide

  11. 税理士ドットコム
    • 日本最大級の税理士/税務ポータルサイト
    • 税理士紹介、Q&A、ニュースなど
    • 2016年〜
    • 私 + 業務委託エンジニアx5

    View Slide

  12. 管理画面 with Vue
    • もともとPHP Yii Frameworkが内包するUIモ
    ジュール+ jQuery を使っていた
    • 長年の運用と範囲の拡大にインタラクションが不

    • システムの一部でVueを導入(半年ほど前)
    • Form操作の複雑化に伴い、型が欲しくなる←イマココ

    View Slide

  13. 型に対する期待
    • データ構造の補完
    • データ構造のドキュメント化
    • 値の受け渡しミスの抑止
    • メンバーの学習

    View Slide

  14. 悩みどころ
    • Vueの中でのレールが無い
    • サードパーティを使う必要がある
    • Vue+Vuex+VueRouterの範囲なら公式のライブラリ使いたい
    • dispatch, getters, commitで型が落ちる
    • サードパーティ(ry
    • これまでの「Vueを使う」インタラクションから離れる必要がある
    • Vuexのパターンがライブラリに引っ張られる
    • VuexのモジュールをVueに露出させないといけない

    View Slide

  15. 方針

    View Slide

  16. 前提
    • Vueを使う
    • メンバーの知識的、学習補助のコスパ的に
    • 段階的にTypeScriptを導入する
    • 全体をまとめて、はリスクとコスト的にやらない
    • Multiple Page Application + Single Page Application
    • システムの一部をSPAにする

    View Slide

  17. 方針
    • Vue - Vuex 間で型情報を維持する
    • Vuexで構築するデータ構造には固く型を付
    けられる
    • 将来的にはAPIの構造が変わったらコンパイ
    ルで気付ける構造にしたい(遠い未来)

    View Slide

  18. Vuex + TypeScriptの
    パターンを調べた

    View Slide

  19. パターン
    • vuex + vuex-class
    • vuex-type-helper + vuex-class
    • vuex-module-decorator
    • vuex-smart-module

    View Slide

  20. vuex
    +
    vuex-class

    View Slide

  21. vuex + vuex-class
    • vuexに搭載されている型 + vuex-class を使う
    • 標準にもっとも近い形で書ける
    • dispatchとgetterをvuex-classが隠蔽する
    • Store内部でのdispatch, getterの型が抜ける
    • Component側のインタラクションが若干変わる

    View Slide

  22. import Vue from 'vue'
    import Vuex, { GetterTree, MutationTree, ActionTree } from 'vuex'
    import { RootState, NoteForm } from './types'
    import * as notes from './notes'
    Vue.use(Vuex)
    const state: RootState = {}
    const getters: GetterTree = {
    getNotes(state) {
    return () => (state.notes ? state.notes.rows : [])
    }
    }
    const mutations: MutationTree = {}
    const actions: ActionTree = {
    async viewIndex(ctx) {
    ctx.dispatch('notes/fetch')
    },
    async addNote(ctx, form: NoteForm) {
    ctx.dispatch('notes/add', form)
    }
    }
    const modules = {
    notes
    }
    export default new Vuex.Store({
    state,
    mutations,
    actions,
    modules
    })

    View Slide

  23. vuex-type-helper

    View Slide

  24. vuex-type-helper
    • vuexの型ではなくvuex-type-helperを使う
    • interfaceに基づいて片付けができる
    • dispatchとgetterにinterfaceを適応できる
    • ネストモジュールに対してはすべてのaction
    とpayloadをinterfaceに記載する必要がある

    View Slide

  25. JNQPSU\%FGJOF(FUUFST %FGJOF.VUBUJPOT %FGJOF"DUJPOT^GSPNWVFYUZQFIFMQFS
    FYQPSUDPOTUOBNFTQBDFEUSVF
    FYQPSUDPOTUTUBUF/PUFT4UBUF\SPXT<>^
    FYQPSUDPOTUHFUUFST%FGJOF(FUUFST/PUFT(FUUFST /PUFT4UBUF 3PPU4UBUF\
    SPXT TUBUF
    \
    SFUVSO
    TUBUFSPXT
    ^
    ^
    FYQPSUDPOTUNVUBUJPOT%FGJOF.VUBUJPOT/PUFT.VUBUJPOT /PUFT4UBUF\
    '&5$)@3&40-7& TUBUF \SPXT^
    \
    TUBUFSPXTSPXT
    ^
    "%%@3&40-7& TUBUF \GPSN^
    \
    DPOTUMBTU*ETUBUFSPXTJE
    DPOTUOPUF/PUF&OUJUZ\
    JEMBTU*E
    DPOUFOUGPSNDPOUFOU
    DSFBUFEOFX%BUF

    ^
    TUBUFSPXTQVTI OPUF

    ^
    ^
    FYQPSUDPOTUBDUJPOT%FGJOF"DUJPOT
    /PUFT"DUJPOT
    /PUFT4UBUF
    /PUFT.VUBUJPOT
    3PPU4UBUF
    \
    BTZODGFUDI DUY
    \
    DPOTUSPXT/PUF&OUJUZ<><
    \JE DPOUFOUUFTU DSFBUFEOFX%BUF
    ^
    >
    DUYDPNNJU '&5$)@3&40-7& \SPXT^

    ^
    BTZODBEE DUY \GPSN^
    \
    DUYDPNNJU "%%@3&40-7& \GPSN^

    ^
    ^

    View Slide

  26. vuex-module-decorator

    View Slide

  27. vuex-module-decorator
    • Vuexのモジュール一つのクラスとしてみなす
    • VuexModuleクラスを継承してデコレータで
    mutation, actionを定義する
    • vue-property-decratorに感触的には近い
    • Componentからはモジュールを直接呼び出す
    ことで型抜けを防ぐ

    View Slide

  28. JNQPSU\/PUF&OUJUZ /PUF'PSN^GSPNUZQFT
    JNQPSU\7VFY.PEVMF .VUBUJPO "DUJPO^GSPNWVFYNPEVMFEFDPSBUPST
    FYQPSUEFGBVMUDMBTT/PUFT.PEVMFFYUFOET7VFY.PEVMF\
    SPXT/PUF&OUJUZ<><>
    !.VUBUJPO
    '&5$)@3&40-7& SPXT/PUF&OUJUZ<>
    \
    UIJTSPXTSPXT
    ^
    !.VUBUJPO
    "%%@3&40-7& GPSN/PUF'PSN
    \
    DPOTUMBTU*EUIJTSPXTJE
    DPOTUOPUF/PUF&OUJUZ\
    JEMBTU*E
    DPOUFOUGPSNDPOUFOU
    DSFBUFEOFX%BUF

    ^
    UIJTSPXTQVTI OPUF

    ^
    !"DUJPO
    BTZODGFUDI
    \
    DPOTUSPXT/PUF&OUJUZ<><
    \JE DPOUFOUUFTU DSFBUFEOFX%BUF
    ^
    >
    SFUVSOSPXT
    ^
    !"DUJPO
    BTZODBEE GPSN/PUF'PSN
    \
    SFUVSOGPSN
    ^
    ^

    View Slide

  29. vuex-smart-module

    View Slide

  30. vuex-smart-module
    • state, getter, mutation, actionを継承してクラ
    ス化してModuleに集約する
    • ComponentからはModuleを呼び出す
    • Vuexの機能単位で分割できる部分を残しているので
    既存構造にも適応させやすい
    • Contextの概念があり、ネストしたModuleへの
    dispatch, getterが呼び出せる

    View Slide

  31. JNQPSU\(FUUFST .VUBUJPOT "DUJPOT .PEVMF^GSPNWVFYTNBSUNPEVMF
    JNQPSU\/PUF&OUJUZ /PUF'PSN^GSPNUZQFT
    FYQPSUDPOTUOBNFTQBDFEUSVF
    FYQPSUDMBTT/PUFT4UBUF\
    SPXT/PUF&OUJUZ<><>
    ^
    FYQPSUDMBTT/PUFT(FUUFSTFYUFOET(FUUFST/PUFT4UBUF\
    SPXT
    \
    SFUVSOUIJTTUBUFSPXT
    ^
    ^
    FYQPSUDMBTT/PUFT.VUBUJPOTFYUFOET.VUBUJPOT/PUFT4UBUF\
    '&5$)@3&40-7& SPXT/PUF&OUJUZ<>
    \
    UIJTTUBUFSPXTSPXT
    ^
    "%%@3&40-7& GPSN/PUF'PSN
    \
    DPOTUMBTU*EUIJTTUBUFSPXTJE
    DPOTUOPUF/PUF&OUJUZ\
    JEMBTU*E
    DPOUFOUGPSNDPOUFOU
    DSFBUFEOFX%BUF

    ^
    UIJTTUBUFSPXTQVTI OPUF

    ^
    ^
    FYQPSUDMBTT/PUFT"DUJPOTFYUFOET"DUJPOT
    /PUFT4UBUF
    /PUFT(FUUFST
    /PUFT.VUBUJPOT
    /PUFT"DUJPOT
    \
    BTZODGFUDI
    \
    DPOTUSPXT/PUF&OUJUZ<><
    \JE DPOUFOUUFTU DSFBUFEOFX%BUF
    ^
    >
    UIJTDPNNJU '&5$)@3&40-7& SPXT

    ^
    BTZODBEE GPSN/PUF'PSN
    \
    UIJTDPNNJU "%%@3&40-7& GPSN

    ^
    ^
    FYQPSUEFGBVMUOFX.PEVMF \
    TUBUF/PUFT4UBUF
    HFUUFST/PUFT(FUUFST
    NVUBUJPOT/PUFT.VUBUJPOT
    BDUJPOT/PUFT"DUJPOT
    ^

    View Slide

  32. まとめ

    View Slide

  33. Vuexに型をつけようと思ったら
    Vuex-Frameworkの選定になった

    View Slide

  34. Vuex-Typeパターン
    • Vuexに対して型を付与パターン(既存のVuexと相
    性が良い)
    • vuex
    • vuex-type-helper, etc
    • モジュール化パターン(新しくモジュール構成を考
    える)
    • vuex-module-decorator,
    • vuex-smart-module, etc

    View Slide

  35. 何を採用するか?
    • Vue-Vuexの間でどういうやり取りするかが
    大きく関わるので全体を考える必要がある
    • アプリがライブラリに依存する
    • サードパーティなので、アップデートの追
    従とかも考えたほうがいい
    • Vue+TypeScriptは発展途上

    View Slide

  36. まとめ
    • Vuexで片付けするパターンを紹介しました
    • まだVuexの型は方言が多い
    • 「ゆるく書ける」Vueの良さとどう同居していくか模
    索している
    • みなさんの意見を聞かせてください

    View Slide

  37. ご清聴ありがとうございました

    View Slide