レガシーなフロントエンドをリプレイスする

06a095e125c2016e983e183e10209b9a?s=47 jiko21
November 02, 2019

 レガシーなフロントエンドをリプレイスする

Frontend Conference 2019 #kfug2019
の登壇資料です

06a095e125c2016e983e183e10209b9a?s=128

jiko21

November 02, 2019
Tweet

Transcript

  1. ϨΨγʔͳϑϩϯτΤϯυΛ ϦϓϨΠε͢Δ Frontend Conference 2019 #kfug2019 @Daikids2

  2. খౡ େج / Daiki Kojima @Daikids2 @jiko21 ژ౎େֶେֶӃ৘ใֶݚڀՊM2 (ଟ෼) ϑϩϯτΤϯυΤϯδχΞ

  3. ͓͸ͳ͢͠Δ͜ͱ • ϨΨγʔͳϑϩϯτΤϯυΛϦϓϨΠεͨ͠࿩ • ϨΨγʔͬͯͲΜͳঢ়ଶͩͬͨͷ? • ٕज़બఆ͸? ઃܭ͸? • Ͳ͏΍ͬͯ͢͢Ί͍ͯͬͨͷ?

  4. ͦ΋ͦ΋

  5. ϨΨγʔͬͯ?

  6. Wikipediaͩͱ… https://ja.wikipedia.org/wiki/%E3%83%AC%E3%82%AC%E3%82%B7%E3%83%BC%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0

  7. ཁ͢Δʹ… • ݹ͍!! • ෛ࠴ • ѻ͍ͮΒ͍…

  8. ϑϩϯτͬͯ
 ΘΓ͔͠৽͍͠…

  9. ϨΨγʔͱ͸ؔ܎ͳ͍?

  10. NO!

  11. ϑϩϯτ΋ϨΨγʔʹͳΔΘ͚ • ৽͍ٕ͠ज़͕͙͢ʹೖͬͯ͘Δ • TypeScript, es6… • ഁյతͳมߋɾUpdate͕ଟ͍ • Angular

    1.x/2.xͰͷҧ͍
  12. None
  13. ౰࣌ͷٕज़ελοΫ • Angular.js (1ܥ) • Vue.js (2ܥ) + TypeScript •

    Pug + Sass • Gulp
  14. ౰࣌ͷٕज़ελοΫ • Angular.js (1ܥ) • ։ൃॳظʹಋೖ (Angular (2ܥ)͕ొ৔ͨ͜͠Ζ) • JavaScriptͰهड़

  15. ౰࣌ͷٕज़ελοΫ • Vue.js (2ܥ) • ʮAngular.js͕ͭΒ͍ΑͶʯͱ͍͏͜ͱͰ৽نը໘Ͱ
 ಋೖ • TypeScript +

    Pug + SassͰهड़
  16. Ϗϧυ·ΘΓ͸?

  17. ౰࣌ͷٕज़ελοΫ Vue.js Angular.js Gulp html, css, js "OHVMBSͱ7VFKTΛ
 (VMQͰϏϧυ

  18. ౰࣌ͷٕज़ελοΫ Vue.js Angular.js Gulp html, css, js "OHVMBSͱ7VFKTΛ
 (VMQͰϏϧυ

  19. ϨΨγʔɾ·͍ͣ఺

  20. ͬ͟ͱ໰୊఺(Ұྫ) • Angular.jsͱVue.js͕ڞଘ • Angular.jsଆ͸ςετ͕Ұ੾ͳ͠!! • i18nରԠ͕ͻͲ͍ (೔ຊޠɾӳޠΛผʑͷϑΝΠϧͰද ݱ)

  21. ͬ͟ͱ໰୊఺ • Angular.jsͱVue.js͕ڞଘ • Ұ෦Service૚͕Angularʹґଘ • VueͷComponentͰXHRͯ͠Δ • Angular.jsଆ͸ςετ͕Ұ੾ͳ͠!! •

    i18nରԠ͕ͻͲ͍ (೔ຊޠɾӳޠΛผʑͷϑΝΠϧͰදݱ) ໰୊఺͕ଟ͍
  22. Angular.jsͱVue.js ͕ڞଘ

  23. Angular.jsͱVue.js͕ڞଘ • 2ͭͷFWΛ๊͑Δ͜ͱʹ… • Angular.js͸es5ɺVue.js͸TypeScript(es6 base) • FWͲ͜Ζ͔ɺݴޠ΋(͍ͩͿ)ҧ͏ • Ұ෦Service૚͕Angularʹґଘ

    • ࠶ར༻ੑ͕௿͍ ➡ VueͷComponentͰXHRͤ͟ΔΛಘͳ͍৔߹΋
  24. Angular.jsଆ͸ςετ͕ Ұ੾ͳ͠!!

  25. ςετͬͯ? ιʔείʔυ ࣦഊ ੒ޭ ίʔυ͕ςετέʔεΛύε͢Δ͔
 ࣮ߦͯ֬͠ೝ ςετπʔϧ ςετ࣮ߦ

  26. ςετΛॻ͘ར఺ • ڍಈ͕ਖ਼͍͜͠ͱΛอূͰ͖Δ • ໰୊ͷ੾Γ෼͚͕Ͱ͖Δ • ςετέʔε͕࢓༷ʹͳͬͯ͘ΕΔ • etc…

  27. ͱ͜Ζ͕… • ςετͷݱঢ় • Vue: ίϯϙʔωϯτͷςετ͸͋Δ • Angular.js: ςετ͕Ұ੾ͳ͠(Ϟδϡʔϧ΋!!)

  28. i18nରԠ͕ͻͲ͍

  29. i18nͬͯ • ࠃࡍԽରԠͷ͜ͱ • ༷ʑͳ஍Ҭɾݴޠʹ߹ΘͤΔ͜ͱ ೔ຊޠͰ
 ݟ͍ͨ ӳޠͰ ݟ͍ͨ ೔ຊޠ൛

    ӳޠ൛
  30. ຊདྷͳΒ… • ઃఆϑΝΠϧͰݴޠΛ؅ཧ͓ͯ͘͠ • ϒϥ΢βͷ৘ใΛ༻͍ͯදࣔ͢΂͖ݴޠͰදࣔ • i18nαϙʔτ͸αʔόʔɾϑϩϯτ໰Θͣ
 ༷ʑͳϥΠϒϥϦͰ࣮ݱͰ͖Δ

  31. ݱঢ় • ଟݴޠରԠ͕ඞཁͳϖʔδ͸ӳޠ൛ɾ೔ຊޠ൛ͱ
 ςϯϓϨʔτ(html)Λ෼͚ͯɺϦϯΫ΋ผʑʹ… ➡ ίʔυͷมߋྔ͕ݴޠͷ෼͚ͩ૿͑Δ! hogehoge-ja.html(೔ຊޠ) hogehoge-en.html(ӳޠ)

  32. ϨΨγʔΛվળ͢ΔͨΊʹ ϦϓϨΠεΛߦ͏͜ͱʹ!!

  33. ٕज़બఆɾઃܭ

  34. ΍Δ͜ͱ • ٕज़ΛબͿ • FWɺUI Architectureɺςετ • σΟϨΫτϦͷઃܭ

  35. ٕज़બఆ • FW: Vue.js • ίϨࣗମ͸ܾఆࣄ߲ • @vue/cliͰϘΠϥʔϓϨʔτΛੜ੒

  36. ٕज़બఆ • ͦͷଞ • TypeScript: ࣾ಺ͰͲΜͲΜTSԽ͕… ܕ͋Δͱ͏Ε͍͠ • class-style-api: ܕָ͕ɻͰ΋…(ޙड़)

    • Vuex: ෳࡶͳঢ়ଶ؅ཧ͕ඞཁͳ৔߹
  37. Class-style api Class-style api @Component export default class Count extends

    Vue { @Prop() msg!: string; private count: number = 0; private add(): void { this.count += 1; } private minus(): void { this.count -= 1; } get isEven(): boolean { return this.count % 2 === 0; } } export default Vue.extend({ name: "Count", props: { msg: { type: String, required: true, }, }, data() { return { count: 0, }; }, computed: { isEven(): boolean { return this.count % 2 === 0; }, }, methods: { add(): void { this.count += 1; }, minus(): void { this.count -= 1; }, }, }); Class-style api Ұൠతͳॻ͖ํ
  38. σΟϨΫτϦઃܭɹ • QiitaͳͲΛௐ΂ͯσΟϨΫτϦߏ੒Λத৺ʹ৘ใूΊ • React + ReduxΛܦݧ͔ͯ͠ΒͷstatelessͳVue + Vuexߏ੒ʹ͍ͭͯ
 (https://qiita.com/_masakitm_/items/ff5df4da0247baeede35)

    • vuexެࣜ (https://github.com/vuejs/vuex/tree/dev/examples/chat)
  39. Ͱ͖͕͋ͬͨ΋ͷ 6*·ΘΓ ϩδοΫ ·ΘΓ

  40. UI·ΘΓ 1BHFT 1BHFT 1BHFT /home /about /help DPOUBJOFS DPOUBJOFS DPNQPOFOU

    DPNQPOFOU DPNQPOFOU ΃ʔ͡͝ͱʹ
 1BHFͷ3PPU$PNQPOFOU 7VFY΍4UPSFΛ࣋ͯΔ
 DPOUBJOFSDPNQPOFOU جຊతʹ TUBUFMFTTͳ
 $PNQPOFOU 7VFY
  41. ϩδοΫपΓ • جຊతʹserviceɺutilͳͲͷܗͰϞδϡʔϧΛ۠੾Δ • service: APIͳͲΛୟ͘ • utils: ࣌ؒɺจࣈྻͳͲͷศརͳؔ਺ •

    ͜ΕΒΛVue͔ΒҾ͖ണ͕͠ɺ
 UIϑϨʔϜϫʔΫʹґଘ͠ͳ͍ɺ࠶ར༻Մೳͳ΋ͷʹ

  42. VuexपΓ • جຊతʹϖʔδ͝ͱʹmoduled store • άϩʔόϧͰڞ༗͢Δඞཁ͸͋·Γͳ͍ • ͨͩ͠moduleͳ͍Ͱঢ়ଶ͕૿͑Δ৔߹͸… • ؔ৺͝ͱϕʔεͰmoduleΛ۠੾Δ

    (re-ducksύλʔϯ?)
  43. ҙࣝͨ͜͠ͱ • ࣾ಺ͰReactΛಋೖͨ͠ͱ͖ͷ൓লΛ׆͔͢ • Component͸ͳΔ΂͘Statelessʹ • ௚઀XHR͠ͳ͍ • ԿΑΓɺίʔυΛࣺͯΒΕΔΑ͏ʹ͢Δ •

    Vueʹґଘ͠ͳ͍ॲཧ͸moduleʹ
  44. ςετपΓ • ީิʹ্͕ͬͨπʔϧ • Jest • Mocha+Chai ͲͪΒ΋!WVFDMJͰબ୒Մೳ

  45. ͦΕͧΕͷҧ͍… • Jest vs Mocha: Which Should You Choose?[1]ʹΑΔͱ… •

    Jest: ؆୯ʹ͔͚ͯฒߦ࣮ߦɻεφοϓγϣοτ΋ɹ • Mocha: ΧελϜ͕Ͱ͖Δ… [1] https://blog.usejournal.com/jest-vs-mocha-whats-the-difference-235df75ffdf3 ॻ͖΍͢͞΍͸΍͞Ͱ+FTU
  46. ςετํ਑ • ϞδϡʔϧɾVuex • ΧόϨοδ100%Λ໨ࢦ͢ • ίϯϙʔωϯτ • εφοϓγϣοτςετΛଟ༻ •

    Πϕϯτ΋Ͱ͖ΔݶΓνΣοΫ
  47. Snapshotςετͱ͸? ඳը <template> <div class="count"> <h1>{{ count }}</h1> <div class="buttons">

    <button class="add" @click="increment">+</button> <button class="minus" @click="decrement">-</button> </div> </div> </template> ίϯϙʔωϯτ exports[`Count.vue correctly renders html 1`] = ` <div class="count"> <h1>0</h1> <div class="buttons"><button class="add">+</button> <button class="minus">-</button></div> εφοϓγϣοτ ϑΝΠϧʹ
 ॻ͖ࠐΉ ॳճ
  48. Snapshotςετͱ͸? ඳը <template> <div class="count"> <h1>{{ count }}</h1> <div class="buttons">

    <button class="add" @click="increment">+</button> <button class="minus" @click="decrement">-</button> </div> </div> </template> ίϯϙʔωϯτ EJ⒎Λͱͬͯ
 ֬ೝ ͦΕҎ߱ is equal to ඳը͞ΕͨComponent ? SnapshotϑΝΠϧ
  49. εφοϓγϣοτςετͷ௕ॴɾ୹ॴ ϝϦοτ σϝϦοτ ɾมߋ͕Θ͔Γ΍͍͢ ɾมߋʹऑ͍ ɾ6*ϥΠϒϥϦʹґଘ ɾ࣮ߦ؀ڥʹґଘ

  50. ଞʹ΋… • ίʔυͷελΠϧ໘ͰͷࢦఠΛRVͰݮΒ͢ • ESLint • SnapshotςετͷมߋΛ༻ҙʹ • watch(؂ࢹ)ϞʔυͷςετΛ༰қ

  51. ࣮ࡍͷ։ൃʹ͍ͭͯ

  52. ։ൃͷྲྀΕ • ֤ϖʔδ͝ͱͷissue • ୲౰ऀΛAssigneeʹ • ը໘ɾϩδοΫ·ΘΓ(+Vuex)͝ͱʹPR • جຊ͸ϦϓϨΠεݩͷը໘ΛͳΔ΂͘࠶ݱ

  53. ϓϩδΣΫτͷਐΊํ ๻ҰਓͰ
 ։ൃΛਐΊΔ ࣍ୈʹଞͷਓ΋
 ։ൃʹࢀՃ νʔϜશମͰ
 ϦϓϨΠεΛ
 ऴ͍ྃͤͯ͘͞ 5݄ 9݄

    7݄ ϦϓϨΠε ׬ྃ ϦϓϨΠε 4UBSU Ұ൪Ή͍ͣ΍ͭ Angular.jsϦϓϨΠε։࢝ طଘͷVue͔Β
  54. ։ൃͷྲྀΕ • ֤ϖʔδ͝ͱͷissue • ୲౰ऀΛAssigneeʹ • ը໘ɾϩδοΫ·ΘΓ(+Vuex)͝ͱʹPR • جຊ͸ϦϓϨΠεݩͷը໘ΛͳΔ΂͘࠶ݱ

  55. ։ൃ͸ॱௐ͔ͩͬͨ?

  56. NO

  57. ͳͥ͏·͍͔͘ͳ͍͔ • ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ͸ৗʹมԽ͍ͯ͠Δ • ಛʹRFCʹ্͕ΔΑ͏ͳٕज़͸࠾༻͞Εͳ͜ͱ΋ • npm͕rc൛ͷϥΠϒϥϦΛinstall͢Δ͜ͱ΋͋Δ

  58. ࣮ࡍʹ͋ͬͨ͜ͱ • ϦϓϨΠεલͷίʔυͰ͸ಈ͍͍ͯͨςετ͕
 ಈ͔ͳ͍ • @vue/cli͕࢖͏Α͏ʹΞϐʔϧͯͨ͠class-style-api͕
 ඇਪ঑ʹ

  59. ϦϓϨΠεલͷίʔυͰ͸
 ಈ͍͍ͯͨςετ͕ಈ͔ͳ͍

  60. ϦϓϨΠεલͷίʔυͰ͸
 ಈ͍͍ͯͨςετ͕ಈ͔ͳ͍ • ݪҼ => Bootstrap-Vueͷόʔδϣϯ • Ҡߦલ: 1.5ܥ •

    Ҡߦઌ: 2.0.x-rc • ͦ΋ͦ΋Componentͷmount͕͏·͍ͬͯ͘ͳ͍…
  61. ରॲ๏ • ςετΛॻ͘͜ͱ͕໨తͰ͸ͳ͍ͷͰҰ୴Skip • ۩ମతʹ…
 
 
 • ςετίʔυΛ࢒͠ͳ͕Β࣮ߦΛඈ͹ͤΔ it.skip('correctly

    renders html', () => { const wrapper = shallowMount(Count); expect(wrapper.html()).toMatchSnapshot(); });
  62. @vue/cli͕࢖͏Α͏ʹ
 Ξϐʔϧͯͨ͠class-style-api͕
 ඇਪ঑ʹ

  63. @vue/cli͕࢖͏Α͏ʹΞϐʔϧͯͨ͠
 class-style-api͕ඇਪ঑ʹ • ઃܭஈ֊ͰTypeScriptΛ࢖͏લఏͷͨΊར༻ • Vue.extendsΑΓܕ·ΘΓ͕ྑ͔ͬͨ… • class style apiͷར༻Λܾఆͨ࣌͠ظ

    • 2019೥1݄ • ͜ΕΛ࢖ͬͯ։ൃΛਐΊ͍ͯͨ…
  64. ͋Δ೔… https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121

  65. ͜ΕΛ౿·͑ͯɹ • ৽نͰ։ൃ͢ΔComponentʹؔͯ͠ • class style apiΛར༻ͤͣʹ࣮૷ • ͢Ͱʹ։ൃͨ͠Componentʹ͍ͭͯ •

    Ұ୴อཹ (͙͢͞·αϙʔτ͞Εͳ͘ͳΒͳ͍ͨΊ) • ͨͩ͠issueͱͯ͠ഉআܭըΛ࢒͓ͯ͘͠ (ϦϑΝΫλϦϯά)
  66. ࠷ޙʹ

  67. ϦϓϨΠεΛऴ͑ͯ • VueࣗମͰͷϦϓϨΠε͸ϦϦʔε׬ྃ • ྑ͔ͬͨ͜ͱ • ࠓ·Ͱٕ͋ͬͨज़తෛ࠴͸Ұ૟Ͱ͖ͨɻ • ϞμϯͳϑϩϯτΤϯυͷ஌ݟ •

    ѱ͔ͬͨ͜ͱ • ٕज़બ୒ͷϛεʹΑΔ৽ͨͳ՝୊ • ଞʹ΋ࠓ͔ΒݟΔͱGoodͰ͸ͳ͍ίʔυ΋
  68. ϦϓϨΠεΛऴ͑ͯ • VueࣗମͰͷϦϓϨΠε͸ϦϦʔε׬ྃ • ྑ͔ͬͨ͜ͱ • ࠓ·Ͱٕ͋ͬͨज़తෛ࠴͸Ұ૟Ͱ͖ͨɻ • ϞμϯͳϑϩϯτΤϯυͷ஌ݟ •

    ѱ͔ͬͨ͜ͱ • ٕज़બ୒ͷϛεʹΑΔ৽ͨͳ՝୊ • ଞʹ΋ࠓ͔ΒݟΔͱGoodͰ͸ͳ͍ίʔυ΋ ࠓޙϦϑΝΫλϦϯάͰ
 ղফ
  69. ࠷ޙʹ

  70. ·ͱΊ • ϑϩϯτΤϯυ΋࣌୅ͱͱ΋ʹϨΨγʔͳίʔυ͕ݱΕΔ • ໰୊఺Λղܾ͠ɺ։ൃͷ͠΍͢͞Λ֬อ͢ΔͨΊʹ΋
 ϦϓϨΠε͸େࣄɻ • ϦϓϨΠεޙͷΞϓϦʹ΋໰୊͸ඞͣ͋Γɺ
 ϦϑΝΫλϦϯά͍ͯ͘͜͠ͱ͕ॏཁɻ

  71. ͝ਗ਼ௌ
 ͋Γ͕ͱ͏͍͟͝·͢