Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

jiko21
November 02, 2019

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

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

jiko21

November 02, 2019
Tweet

More Decks by jiko21

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

  4. ͦ΋ͦ΋

    View Slide

  5. ϨΨγʔͬͯ?

    View Slide

  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

    View Slide

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

    View Slide

  8. ϑϩϯτͬͯ

    ΘΓ͔͠৽͍͠…

    View Slide

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

    View Slide

  10. NO!

    View Slide

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

    View Slide

  12. View Slide

  13. ౰࣌ͷٕज़ελοΫ
    • Angular.js (1ܥ)
    • Vue.js (2ܥ) + TypeScript
    • Pug + Sass
    • Gulp

    View Slide

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

    View Slide

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

    ಋೖ
    • TypeScript + Pug + SassͰهड़

    View Slide

  16. Ϗϧυ·ΘΓ͸?

    View Slide

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

    (VMQͰϏϧυ

    View Slide

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

    (VMQͰϏϧυ

    View Slide

  19. ϨΨγʔɾ·͍ͣ఺

    View Slide

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

    View Slide

  21. ͬ͟ͱ໰୊఺
    • Angular.jsͱVue.js͕ڞଘ
    • Ұ෦Service૚͕Angularʹґଘ
    • VueͷComponentͰXHRͯ͠Δ
    • Angular.jsଆ͸ςετ͕Ұ੾ͳ͠!!
    • i18nରԠ͕ͻͲ͍ (೔ຊޠɾӳޠΛผʑͷϑΝΠϧͰදݱ)
    ໰୊఺͕ଟ͍

    View Slide

  22. Angular.jsͱVue.js
    ͕ڞଘ

    View Slide

  23. Angular.jsͱVue.js͕ڞଘ
    • 2ͭͷFWΛ๊͑Δ͜ͱʹ…
    • Angular.js͸es5ɺVue.js͸TypeScript(es6 base)
    • FWͲ͜Ζ͔ɺݴޠ΋(͍ͩͿ)ҧ͏
    • Ұ෦Service૚͕Angularʹґଘ
    • ࠶ར༻ੑ͕௿͍
    ➡ VueͷComponentͰXHRͤ͟ΔΛಘͳ͍৔߹΋

    View Slide

  24. Angular.jsଆ͸ςετ͕
    Ұ੾ͳ͠!!

    View Slide

  25. ςετͬͯ?
    ιʔείʔυ
    ࣦഊ
    ੒ޭ
    ίʔυ͕ςετέʔεΛύε͢Δ͔

    ࣮ߦͯ֬͠ೝ
    ςετπʔϧ
    ςετ࣮ߦ

    View Slide

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

    View Slide

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

    View Slide

  28. i18nରԠ͕ͻͲ͍

    View Slide

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

    ݟ͍ͨ
    ӳޠͰ
    ݟ͍ͨ
    ೔ຊޠ൛
    ӳޠ൛

    View Slide

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

    ༷ʑͳϥΠϒϥϦͰ࣮ݱͰ͖Δ

    View Slide

  31. ݱঢ়
    • ଟݴޠରԠ͕ඞཁͳϖʔδ͸ӳޠ൛ɾ೔ຊޠ൛ͱ

    ςϯϓϨʔτ(html)Λ෼͚ͯɺϦϯΫ΋ผʑʹ…
    ➡ ίʔυͷมߋྔ͕ݴޠͷ෼͚ͩ૿͑Δ!
    hogehoge-ja.html(೔ຊޠ) hogehoge-en.html(ӳޠ)

    View Slide

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

    View Slide

  33. ٕज़બఆɾઃܭ

    View Slide

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

    View Slide

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

    View Slide

  36. ٕज़બఆ
    • ͦͷଞ
    • TypeScript: ࣾ಺ͰͲΜͲΜTSԽ͕… ܕ͋Δͱ͏Ε͍͠
    • class-style-api: ܕָ͕ɻͰ΋…(ޙड़)
    • Vuex: ෳࡶͳঢ়ଶ؅ཧ͕ඞཁͳ৔߹

    View Slide

  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
    Ұൠతͳॻ͖ํ

    View Slide

  38. σΟϨΫτϦઃܭɹ
    • QiitaͳͲΛௐ΂ͯσΟϨΫτϦߏ੒Λத৺ʹ৘ใूΊ
    • React + ReduxΛܦݧ͔ͯ͠ΒͷstatelessͳVue + Vuexߏ੒ʹ͍ͭͯ

    (https://qiita.com/_masakitm_/items/ff5df4da0247baeede35)
    • vuexެࣜ (https://github.com/vuejs/vuex/tree/dev/examples/chat)

    View Slide

  39. Ͱ͖͕͋ͬͨ΋ͷ
    6*·ΘΓ
    ϩδοΫ
    ·ΘΓ

    View Slide

  40. UI·ΘΓ
    1BHFT 1BHFT 1BHFT
    /home /about /help
    DPOUBJOFS DPOUBJOFS
    DPNQPOFOU DPNQPOFOU
    DPNQPOFOU
    ΃ʔ͡͝ͱʹ

    1BHFͷ3PPU$PNQPOFOU
    7VFY΍4UPSFΛ࣋ͯΔ

    DPOUBJOFSDPNQPOFOU
    جຊతʹ
    TUBUFMFTTͳ

    $PNQPOFOU
    7VFY

    View Slide

  41. ϩδοΫपΓ
    • جຊతʹserviceɺutilͳͲͷܗͰϞδϡʔϧΛ۠੾Δ
    • service: APIͳͲΛୟ͘
    • utils: ࣌ؒɺจࣈྻͳͲͷศརͳؔ਺
    • ͜ΕΒΛVue͔ΒҾ͖ണ͕͠ɺ

    UIϑϨʔϜϫʔΫʹґଘ͠ͳ͍ɺ࠶ར༻Մೳͳ΋ͷʹ


    View Slide

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

    View Slide

  43. ҙࣝͨ͜͠ͱ
    • ࣾ಺ͰReactΛಋೖͨ͠ͱ͖ͷ൓লΛ׆͔͢
    • Component͸ͳΔ΂͘Statelessʹ
    • ௚઀XHR͠ͳ͍
    • ԿΑΓɺίʔυΛࣺͯΒΕΔΑ͏ʹ͢Δ
    • Vueʹґଘ͠ͳ͍ॲཧ͸moduleʹ

    View Slide

  44. ςετपΓ
    • ީิʹ্͕ͬͨπʔϧ
    • Jest
    • Mocha+Chai
    ͲͪΒ΋!WVFDMJͰબ୒Մೳ

    View Slide

  45. ͦΕͧΕͷҧ͍…
    • Jest vs Mocha: Which Should You Choose?[1]ʹΑΔͱ…
    • Jest: ؆୯ʹ͔͚ͯฒߦ࣮ߦɻεφοϓγϣοτ΋ɹ
    • Mocha: ΧελϜ͕Ͱ͖Δ…
    [1] https://blog.usejournal.com/jest-vs-mocha-whats-the-difference-235df75ffdf3
    ॻ͖΍͢͞΍͸΍͞Ͱ+FTU

    View Slide

  46. ςετํ਑
    • ϞδϡʔϧɾVuex
    • ΧόϨοδ100%Λ໨ࢦ͢
    • ίϯϙʔωϯτ
    • εφοϓγϣοτςετΛଟ༻
    • Πϕϯτ΋Ͱ͖ΔݶΓνΣοΫ

    View Slide

  47. Snapshotςετͱ͸?
    ඳը


    {{ count }}

    +
    -



    ίϯϙʔωϯτ
    exports[`Count.vue correctly renders html 1`] = `

    0
    +
    -
    εφοϓγϣοτ
    ϑΝΠϧʹ

    ॻ͖ࠐΉ
    ॳճ

    View Slide

  48. Snapshotςετͱ͸?
    ඳը


    {{ count }}

    +
    -



    ίϯϙʔωϯτ
    EJ⒎Λͱͬͯ

    ֬ೝ
    ͦΕҎ߱
    is equal to
    ඳը͞ΕͨComponent
    ?
    SnapshotϑΝΠϧ

    View Slide

  49. εφοϓγϣοτςετͷ௕ॴɾ୹ॴ
    ϝϦοτ σϝϦοτ
    ɾมߋ͕Θ͔Γ΍͍͢
    ɾมߋʹऑ͍
    ɾ6*ϥΠϒϥϦʹґଘ
    ɾ࣮ߦ؀ڥʹґଘ

    View Slide

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

    View Slide

  51. ࣮ࡍͷ։ൃʹ͍ͭͯ

    View Slide

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

    View Slide

  53. ϓϩδΣΫτͷਐΊํ
    ๻ҰਓͰ

    ։ൃΛਐΊΔ
    ࣍ୈʹଞͷਓ΋

    ։ൃʹࢀՃ
    νʔϜશମͰ

    ϦϓϨΠεΛ

    ऴ͍ྃͤͯ͘͞
    5݄ 9݄

    ϦϓϨΠε
    ׬ྃ
    ϦϓϨΠε
    4UBSU
    Ұ൪Ή͍ͣ΍ͭ
    Angular.jsϦϓϨΠε։࢝
    طଘͷVue͔Β

    View Slide

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

    View Slide

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

    View Slide

  56. NO

    View Slide

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

    View Slide

  58. ࣮ࡍʹ͋ͬͨ͜ͱ
    • ϦϓϨΠεલͷίʔυͰ͸ಈ͍͍ͯͨςετ͕

    ಈ͔ͳ͍
    • @vue/cli͕࢖͏Α͏ʹΞϐʔϧͯͨ͠class-style-api͕

    ඇਪ঑ʹ

    View Slide

  59. ϦϓϨΠεલͷίʔυͰ͸

    ಈ͍͍ͯͨςετ͕ಈ͔ͳ͍

    View Slide

  60. ϦϓϨΠεલͷίʔυͰ͸

    ಈ͍͍ͯͨςετ͕ಈ͔ͳ͍
    • ݪҼ => Bootstrap-Vueͷόʔδϣϯ
    • Ҡߦલ: 1.5ܥ
    • Ҡߦઌ: 2.0.x-rc
    • ͦ΋ͦ΋Componentͷmount͕͏·͍ͬͯ͘ͳ͍…

    View Slide

  61. ରॲ๏
    • ςετΛॻ͘͜ͱ͕໨తͰ͸ͳ͍ͷͰҰ୴Skip
    • ۩ମతʹ…



    • ςετίʔυΛ࢒͠ͳ͕Β࣮ߦΛඈ͹ͤΔ
    it.skip('correctly renders html', () => {
    const wrapper = shallowMount(Count);
    expect(wrapper.html()).toMatchSnapshot();
    });

    View Slide

  62. @vue/cli͕࢖͏Α͏ʹ

    Ξϐʔϧͯͨ͠class-style-api͕

    ඇਪ঑ʹ

    View Slide

  63. @vue/cli͕࢖͏Α͏ʹΞϐʔϧͯͨ͠

    class-style-api͕ඇਪ঑ʹ
    • ઃܭஈ֊ͰTypeScriptΛ࢖͏લఏͷͨΊར༻
    • Vue.extendsΑΓܕ·ΘΓ͕ྑ͔ͬͨ…
    • class style apiͷར༻Λܾఆͨ࣌͠ظ
    • 2019೥1݄
    • ͜ΕΛ࢖ͬͯ։ൃΛਐΊ͍ͯͨ…

    View Slide

  64. ͋Δ೔…
    https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121

    View Slide

  65. ͜ΕΛ౿·͑ͯɹ
    • ৽نͰ։ൃ͢ΔComponentʹؔͯ͠
    • class style apiΛར༻ͤͣʹ࣮૷
    • ͢Ͱʹ։ൃͨ͠Componentʹ͍ͭͯ
    • Ұ୴อཹ (͙͢͞·αϙʔτ͞Εͳ͘ͳΒͳ͍ͨΊ)
    • ͨͩ͠issueͱͯ͠ഉআܭըΛ࢒͓ͯ͘͠ (ϦϑΝΫλϦϯά)

    View Slide

  66. ࠷ޙʹ

    View Slide

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

    View Slide

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

    ղফ

    View Slide

  69. ࠷ޙʹ

    View Slide

  70. ·ͱΊ
    • ϑϩϯτΤϯυ΋࣌୅ͱͱ΋ʹϨΨγʔͳίʔυ͕ݱΕΔ
    • ໰୊఺Λղܾ͠ɺ։ൃͷ͠΍͢͞Λ֬อ͢ΔͨΊʹ΋

    ϦϓϨΠε͸େࣄɻ
    • ϦϓϨΠεޙͷΞϓϦʹ΋໰୊͸ඞͣ͋Γɺ

    ϦϑΝΫλϦϯά͍ͯ͘͜͠ͱ͕ॏཁɻ

    View Slide

  71. ͝ਗ਼ௌ

    ͋Γ͕ͱ͏͍͟͝·͢

    View Slide