Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

ͦ΋ͦ΋

Slide 5

Slide 5 text

ϨΨγʔͬͯ?

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

ϨΨγʔͱ͸ؔ܎ͳ͍?

Slide 10

Slide 10 text

NO!

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Ϗϧυ·ΘΓ͸?

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

ϨΨγʔɾ·͍ͣ఺

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Angular.jsͱVue.js ͕ڞଘ

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

i18nରԠ͕ͻͲ͍

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

ٕज़બఆɾઃܭ

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

σΟϨΫτϦઃܭɹ • QiitaͳͲΛௐ΂ͯσΟϨΫτϦߏ੒Λத৺ʹ৘ใूΊ • React + ReduxΛܦݧ͔ͯ͠ΒͷstatelessͳVue + Vuexߏ੒ʹ͍ͭͯ
 (https://qiita.com/_masakitm_/items/ff5df4da0247baeede35) • vuexެࣜ (https://github.com/vuejs/vuex/tree/dev/examples/chat)

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

UI·ΘΓ 1BHFT 1BHFT 1BHFT /home /about /help DPOUBJOFS DPOUBJOFS DPNQPOFOU DPNQPOFOU DPNQPOFOU ΃ʔ͡͝ͱʹ
 1BHFͷ3PPU$PNQPOFOU 7VFY΍4UPSFΛ࣋ͯΔ
 DPOUBJOFSDPNQPOFOU جຊతʹ TUBUFMFTTͳ
 $PNQPOFOU 7VFY

Slide 41

Slide 41 text

ϩδοΫपΓ • جຊతʹserviceɺutilͳͲͷܗͰϞδϡʔϧΛ۠੾Δ • service: APIͳͲΛୟ͘ • utils: ࣌ؒɺจࣈྻͳͲͷศརͳؔ਺ • ͜ΕΒΛVue͔ΒҾ͖ണ͕͠ɺ
 UIϑϨʔϜϫʔΫʹґଘ͠ͳ͍ɺ࠶ར༻Մೳͳ΋ͷʹ


Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Snapshotςετͱ͸? ඳը

{{ count }}

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

0

+ -
εφοϓγϣοτ ϑΝΠϧʹ
 ॻ͖ࠐΉ ॳճ

Slide 48

Slide 48 text

Snapshotςετͱ͸? ඳը

{{ count }}

+ -
ίϯϙʔωϯτ EJ⒎Λͱͬͯ
 ֬ೝ ͦΕҎ߱ is equal to ඳը͞ΕͨComponent ? SnapshotϑΝΠϧ

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

࣮ࡍͷ։ൃʹ͍ͭͯ

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

ϓϩδΣΫτͷਐΊํ ๻ҰਓͰ
 ։ൃΛਐΊΔ ࣍ୈʹଞͷਓ΋
 ։ൃʹࢀՃ νʔϜશମͰ
 ϦϓϨΠεΛ
 ऴ͍ྃͤͯ͘͞ 5݄ 9݄ 7݄ ϦϓϨΠε ׬ྃ ϦϓϨΠε 4UBSU Ұ൪Ή͍ͣ΍ͭ Angular.jsϦϓϨΠε։࢝ طଘͷVue͔Β

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

։ൃ͸ॱௐ͔ͩͬͨ?

Slide 56

Slide 56 text

NO

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

ରॲ๏ • ςετΛॻ͘͜ͱ͕໨తͰ͸ͳ͍ͷͰҰ୴Skip • ۩ମతʹ…
 
 
 • ςετίʔυΛ࢒͠ͳ͕Β࣮ߦΛඈ͹ͤΔ it.skip('correctly renders html', () => { const wrapper = shallowMount(Count); expect(wrapper.html()).toMatchSnapshot(); });

Slide 62

Slide 62 text

@vue/cli͕࢖͏Α͏ʹ
 Ξϐʔϧͯͨ͠class-style-api͕
 ඇਪ঑ʹ

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

࠷ޙʹ

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

࠷ޙʹ

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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