Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
レガシーなフロントエンドをリプレイスする
Search
jiko21
November 02, 2019
Technology
5
1.5k
レガシーなフロントエンドをリプレイスする
Frontend Conference 2019 #kfug2019
の登壇資料です
jiko21
November 02, 2019
Tweet
Share
More Decks by jiko21
See All by jiko21
Creating a Next.js-style Framework with Bun and Hono
jiko21
0
92
Array Grouping will soon be arriving at TypeScript
jiko21
0
94
Copying Array Methods arrived at TypeScript
jiko21
1
570
SSRで動的に OGP画像を生成したい! 〜Cloudflare Workersから@vercel/og移行編〜
jiko21
0
110
node:test will replace Jest?
jiko21
0
72
どこでも動かすために… TypeScriptでライブラリ開発の すゝめ
jiko21
2
330
NestJS a progressive web framework
jiko21
3
2.1k
Deep Dive Into Vue Composition API
jiko21
0
3.2k
Composition API TypeScriptはVue.jsの夢を見るか?
jiko21
1
1.5k
Other Decks in Technology
See All in Technology
アジャイルな開発チームでテスト戦略の話は誰がする? / Who Talks About Test Strategy?
ak1210
1
600
OCI Success Journey OCIの何が評価されてる?疑問に答える事例セミナー(2025年2月実施)
oracle4engineer
PRO
2
160
OSS構成管理ツールCMDBuildを使ったAWSリソース管理の自動化
satorufunai
0
650
スキルだけでは満たせない、 “組織全体に”なじむオンボーディング/Onboarding that fits “throughout the organization” and cannot be satisfied by skills alone
bitkey
0
180
JavaにおけるNull非許容性
skrb
2
2.6k
ディスプレイ広告(Yahoo!広告・LINE広告)におけるバックエンド開発
lycorptech_jp
PRO
0
380
php-conference-nagoya-2025
fuwasegu
0
150
4th place solution Eedi - Mining Misconceptions in Mathematics
rist
0
150
【内製開発Summit 2025】イオンスマートテクノロジーの内製化組織の作り方/In-house-development-summit-AST
aeonpeople
2
670
Snowflakeの開発・運用コストをApache Icebergで効率化しよう!~機能と活用例のご紹介~
sagara
1
460
分解して理解する Aspire
nenonaninu
2
1.1k
AI Agent時代なのでAWSのLLMs.txtが欲しい!
watany
2
230
Featured
See All Featured
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
GraphQLとの向き合い方2022年版
quramy
44
14k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
21
2.5k
Making the Leap to Tech Lead
cromwellryan
133
9.1k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
133
33k
Code Review Best Practice
trishagee
67
18k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.5k
Java REST API Framework Comparison - PWX 2021
mraible
29
8.4k
Rails Girls Zürich Keynote
gr2m
94
13k
Transcript
ϨΨγʔͳϑϩϯτΤϯυΛ ϦϓϨΠε͢Δ Frontend Conference 2019 #kfug2019 @Daikids2
খౡ େج / Daiki Kojima @Daikids2 @jiko21 ژେֶେֶӃใֶݚڀՊM2 (ଟ) ϑϩϯτΤϯυΤϯδχΞ
͓ͳ͢͠Δ͜ͱ • ϨΨγʔͳϑϩϯτΤϯυΛϦϓϨΠεͨ͠ • ϨΨγʔͬͯͲΜͳঢ়ଶͩͬͨͷ? • ٕज़બఆ? ઃܭ? • Ͳ͏ͬͯ͢͢Ί͍ͯͬͨͷ?
ͦͦ
ϨΨγʔͬͯ?
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
ཁ͢Δʹ… • ݹ͍!! • ෛ࠴ • ѻ͍ͮΒ͍…
ϑϩϯτͬͯ ΘΓ͔͠৽͍͠…
ϨΨγʔͱؔͳ͍?
NO!
ϑϩϯτϨΨγʔʹͳΔΘ͚ • ৽͍ٕ͠ज़͕͙͢ʹೖͬͯ͘Δ • TypeScript, es6… • ഁյతͳมߋɾUpdate͕ଟ͍ • Angular
1.x/2.xͰͷҧ͍
None
࣌ͷٕज़ελοΫ • Angular.js (1ܥ) • Vue.js (2ܥ) + TypeScript •
Pug + Sass • Gulp
࣌ͷٕज़ελοΫ • Angular.js (1ܥ) • ։ൃॳظʹಋೖ (Angular (2ܥ)͕ొͨ͜͠Ζ) • JavaScriptͰهड़
࣌ͷٕज़ελοΫ • Vue.js (2ܥ) • ʮAngular.js͕ͭΒ͍ΑͶʯͱ͍͏͜ͱͰ৽نը໘Ͱ ಋೖ • TypeScript +
Pug + SassͰهड़
Ϗϧυ·ΘΓ?
࣌ͷٕज़ελοΫ Vue.js Angular.js Gulp html, css, js "OHVMBSͱ7VFKTΛ (VMQͰϏϧυ
࣌ͷٕज़ελοΫ Vue.js Angular.js Gulp html, css, js "OHVMBSͱ7VFKTΛ (VMQͰϏϧυ
ϨΨγʔɾ·͍ͣ
ͬ͟ͱ(Ұྫ) • Angular.jsͱVue.js͕ڞଘ • Angular.jsଆςετ͕Ұͳ͠!! • i18nରԠ͕ͻͲ͍ (ຊޠɾӳޠΛผʑͷϑΝΠϧͰද ݱ)
ͬ͟ͱ • Angular.jsͱVue.js͕ڞଘ • Ұ෦Service͕Angularʹґଘ • VueͷComponentͰXHRͯ͠Δ • Angular.jsଆςετ͕Ұͳ͠!! •
i18nରԠ͕ͻͲ͍ (ຊޠɾӳޠΛผʑͷϑΝΠϧͰදݱ) ͕ଟ͍
Angular.jsͱVue.js ͕ڞଘ
Angular.jsͱVue.js͕ڞଘ • 2ͭͷFWΛ๊͑Δ͜ͱʹ… • Angular.jses5ɺVue.jsTypeScript(es6 base) • FWͲ͜Ζ͔ɺݴޠ(͍ͩͿ)ҧ͏ • Ұ෦Service͕Angularʹґଘ
• ࠶ར༻ੑ͕͍ ➡ VueͷComponentͰXHRͤ͟ΔΛಘͳ͍߹
Angular.jsଆςετ͕ Ұͳ͠!!
ςετͬͯ? ιʔείʔυ ࣦഊ ޭ ίʔυ͕ςετέʔεΛύε͢Δ͔ ࣮ߦͯ֬͠ೝ ςετπʔϧ ςετ࣮ߦ
ςετΛॻ͘ར • ڍಈ͕ਖ਼͍͜͠ͱΛอূͰ͖Δ • ͷΓ͚͕Ͱ͖Δ • ςετέʔε͕༷ʹͳͬͯ͘ΕΔ • etc…
ͱ͜Ζ͕… • ςετͷݱঢ় • Vue: ίϯϙʔωϯτͷςετ͋Δ • Angular.js: ςετ͕Ұͳ͠(Ϟδϡʔϧ!!)
i18nରԠ͕ͻͲ͍
i18nͬͯ • ࠃࡍԽରԠͷ͜ͱ • ༷ʑͳҬɾݴޠʹ߹ΘͤΔ͜ͱ ຊޠͰ ݟ͍ͨ ӳޠͰ ݟ͍ͨ ຊޠ൛
ӳޠ൛
ຊདྷͳΒ… • ઃఆϑΝΠϧͰݴޠΛཧ͓ͯ͘͠ • ϒϥβͷใΛ༻͍ͯද͖ࣔ͢ݴޠͰදࣔ • i18nαϙʔταʔόʔɾϑϩϯτΘͣ ༷ʑͳϥΠϒϥϦͰ࣮ݱͰ͖Δ
ݱঢ় • ଟݴޠରԠ͕ඞཁͳϖʔδӳޠ൛ɾຊޠ൛ͱ ςϯϓϨʔτ(html)Λ͚ͯɺϦϯΫผʑʹ… ➡ ίʔυͷมߋྔ͕ݴޠͷ͚ͩ૿͑Δ! hogehoge-ja.html(ຊޠ) hogehoge-en.html(ӳޠ)
ϨΨγʔΛվળ͢ΔͨΊʹ ϦϓϨΠεΛߦ͏͜ͱʹ!!
ٕज़બఆɾઃܭ
Δ͜ͱ • ٕज़ΛબͿ • FWɺUI Architectureɺςετ • σΟϨΫτϦͷઃܭ
ٕज़બఆ • FW: Vue.js • ίϨࣗମܾఆࣄ߲ • @vue/cliͰϘΠϥʔϓϨʔτΛੜ
ٕज़બఆ • ͦͷଞ • TypeScript: ࣾͰͲΜͲΜTSԽ͕… ܕ͋Δͱ͏Ε͍͠ • class-style-api: ܕָ͕ɻͰ…(ޙड़)
• Vuex: ෳࡶͳঢ়ଶཧ͕ඞཁͳ߹
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 Ұൠతͳॻ͖ํ
σΟϨΫτϦઃܭɹ • QiitaͳͲΛௐͯσΟϨΫτϦߏΛத৺ʹใूΊ • React + ReduxΛܦݧ͔ͯ͠ΒͷstatelessͳVue + Vuexߏʹ͍ͭͯ (https://qiita.com/_masakitm_/items/ff5df4da0247baeede35)
• vuexެࣜ (https://github.com/vuejs/vuex/tree/dev/examples/chat)
Ͱ͖͕͋ͬͨͷ 6*·ΘΓ ϩδοΫ ·ΘΓ
UI·ΘΓ 1BHFT 1BHFT 1BHFT /home /about /help DPOUBJOFS DPOUBJOFS DPNQPOFOU
DPNQPOFOU DPNQPOFOU ʔ͡͝ͱʹ 1BHFͷ3PPU$PNQPOFOU 7VFY4UPSFΛ࣋ͯΔ DPOUBJOFSDPNQPOFOU جຊతʹ TUBUFMFTTͳ $PNQPOFOU 7VFY
ϩδοΫपΓ • جຊతʹserviceɺutilͳͲͷܗͰϞδϡʔϧΛ۠Δ • service: APIͳͲΛୟ͘ • utils: ࣌ؒɺจࣈྻͳͲͷศརͳؔ •
͜ΕΒΛVue͔ΒҾ͖ണ͕͠ɺ UIϑϨʔϜϫʔΫʹґଘ͠ͳ͍ɺ࠶ར༻Մೳͳͷʹ
VuexपΓ • جຊతʹϖʔδ͝ͱʹmoduled store • άϩʔόϧͰڞ༗͢Δඞཁ͋·Γͳ͍ • ͨͩ͠moduleͳ͍Ͱঢ়ଶ͕૿͑Δ߹… • ؔ৺͝ͱϕʔεͰmoduleΛ۠Δ
(re-ducksύλʔϯ?)
ҙࣝͨ͜͠ͱ • ࣾͰReactΛಋೖͨ͠ͱ͖ͷলΛ׆͔͢ • ComponentͳΔ͘Statelessʹ • XHR͠ͳ͍ • ԿΑΓɺίʔυΛࣺͯΒΕΔΑ͏ʹ͢Δ •
Vueʹґଘ͠ͳ͍ॲཧmoduleʹ
ςετपΓ • ީิʹ্͕ͬͨπʔϧ • Jest • Mocha+Chai ͲͪΒ!WVFDMJͰબՄೳ
ͦΕͧΕͷҧ͍… • Jest vs Mocha: Which Should You Choose?[1]ʹΑΔͱ… •
Jest: ؆୯ʹ͔͚ͯฒߦ࣮ߦɻεφοϓγϣοτɹ • Mocha: ΧελϜ͕Ͱ͖Δ… [1] https://blog.usejournal.com/jest-vs-mocha-whats-the-difference-235df75ffdf3 ॻ͖͢͞͞Ͱ+FTU
ςετํ • ϞδϡʔϧɾVuex • ΧόϨοδ100%Λࢦ͢ • ίϯϙʔωϯτ • εφοϓγϣοτςετΛଟ༻ •
ΠϕϯτͰ͖ΔݶΓνΣοΫ
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> εφοϓγϣοτ ϑΝΠϧʹ ॻ͖ࠐΉ ॳճ
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ϑΝΠϧ
εφοϓγϣοτςετͷॴɾॴ ϝϦοτ σϝϦοτ ɾมߋ͕Θ͔Γ͍͢ ɾมߋʹऑ͍ ɾ6*ϥΠϒϥϦʹґଘ ɾ࣮ߦڥʹґଘ
ଞʹ… • ίʔυͷελΠϧ໘ͰͷࢦఠΛRVͰݮΒ͢ • ESLint • SnapshotςετͷมߋΛ༻ҙʹ • watch(ࢹ)ϞʔυͷςετΛ༰қ
࣮ࡍͷ։ൃʹ͍ͭͯ
։ൃͷྲྀΕ • ֤ϖʔδ͝ͱͷissue • ୲ऀΛAssigneeʹ • ը໘ɾϩδοΫ·ΘΓ(+Vuex)͝ͱʹPR • جຊϦϓϨΠεݩͷը໘ΛͳΔ͘࠶ݱ
ϓϩδΣΫτͷਐΊํ ҰਓͰ ։ൃΛਐΊΔ ࣍ୈʹଞͷਓ ։ൃʹࢀՃ νʔϜશମͰ ϦϓϨΠεΛ ऴ͍ྃͤͯ͘͞ 5݄ 9݄
7݄ ϦϓϨΠε ྃ ϦϓϨΠε 4UBSU Ұ൪Ή͍ͣͭ Angular.jsϦϓϨΠε։࢝ طଘͷVue͔Β
։ൃͷྲྀΕ • ֤ϖʔδ͝ͱͷissue • ୲ऀΛAssigneeʹ • ը໘ɾϩδοΫ·ΘΓ(+Vuex)͝ͱʹPR • جຊϦϓϨΠεݩͷը໘ΛͳΔ͘࠶ݱ
։ൃॱௐ͔ͩͬͨ?
NO
ͳͥ͏·͍͔͘ͳ͍͔ • ϑϨʔϜϫʔΫϥΠϒϥϦৗʹมԽ͍ͯ͠Δ • ಛʹRFCʹ্͕ΔΑ͏ͳٕज़࠾༻͞Εͳ͜ͱ • npm͕rc൛ͷϥΠϒϥϦΛinstall͢Δ͜ͱ͋Δ
࣮ࡍʹ͋ͬͨ͜ͱ • ϦϓϨΠεલͷίʔυͰಈ͍͍ͯͨςετ͕ ಈ͔ͳ͍ • @vue/cli͕͏Α͏ʹΞϐʔϧͯͨ͠class-style-api͕ ඇਪʹ
ϦϓϨΠεલͷίʔυͰ ಈ͍͍ͯͨςετ͕ಈ͔ͳ͍
ϦϓϨΠεલͷίʔυͰ ಈ͍͍ͯͨςετ͕ಈ͔ͳ͍ • ݪҼ => Bootstrap-Vueͷόʔδϣϯ • Ҡߦલ: 1.5ܥ •
Ҡߦઌ: 2.0.x-rc • ͦͦComponentͷmount͕͏·͍ͬͯ͘ͳ͍…
ରॲ๏ • ςετΛॻ͘͜ͱ͕తͰͳ͍ͷͰҰ୴Skip • ۩ମతʹ… • ςετίʔυΛ͠ͳ͕Β࣮ߦΛඈͤΔ it.skip('correctly
renders html', () => { const wrapper = shallowMount(Count); expect(wrapper.html()).toMatchSnapshot(); });
@vue/cli͕͏Α͏ʹ Ξϐʔϧͯͨ͠class-style-api͕ ඇਪʹ
@vue/cli͕͏Α͏ʹΞϐʔϧͯͨ͠ class-style-api͕ඇਪʹ • ઃܭஈ֊ͰTypeScriptΛ͏લఏͷͨΊར༻ • Vue.extendsΑΓܕ·ΘΓ͕ྑ͔ͬͨ… • class style apiͷར༻Λܾఆͨ࣌͠ظ
• 20191݄ • ͜ΕΛͬͯ։ൃΛਐΊ͍ͯͨ…
͋Δ… https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121
͜ΕΛ౿·͑ͯɹ • ৽نͰ։ൃ͢ΔComponentʹؔͯ͠ • class style apiΛར༻ͤͣʹ࣮ • ͢Ͱʹ։ൃͨ͠Componentʹ͍ͭͯ •
Ұ୴อཹ (͙͢͞·αϙʔτ͞Εͳ͘ͳΒͳ͍ͨΊ) • ͨͩ͠issueͱͯ͠ഉআܭըΛ͓ͯ͘͠ (ϦϑΝΫλϦϯά)
࠷ޙʹ
ϦϓϨΠεΛऴ͑ͯ • VueࣗମͰͷϦϓϨΠεϦϦʔεྃ • ྑ͔ͬͨ͜ͱ • ࠓ·Ͱٕ͋ͬͨज़తෛ࠴ҰͰ͖ͨɻ • ϞμϯͳϑϩϯτΤϯυͷݟ •
ѱ͔ͬͨ͜ͱ • ٕज़બͷϛεʹΑΔ৽ͨͳ՝ • ଞʹࠓ͔ΒݟΔͱGoodͰͳ͍ίʔυ
ϦϓϨΠεΛऴ͑ͯ • VueࣗମͰͷϦϓϨΠεϦϦʔεྃ • ྑ͔ͬͨ͜ͱ • ࠓ·Ͱٕ͋ͬͨज़తෛ࠴ҰͰ͖ͨɻ • ϞμϯͳϑϩϯτΤϯυͷݟ •
ѱ͔ͬͨ͜ͱ • ٕज़બͷϛεʹΑΔ৽ͨͳ՝ • ଞʹࠓ͔ΒݟΔͱGoodͰͳ͍ίʔυ ࠓޙϦϑΝΫλϦϯάͰ ղফ
࠷ޙʹ
·ͱΊ • ϑϩϯτΤϯυ࣌ͱͱʹϨΨγʔͳίʔυ͕ݱΕΔ • Λղܾ͠ɺ։ൃͷ͢͠͞Λ֬อ͢ΔͨΊʹ ϦϓϨΠεେࣄɻ • ϦϓϨΠεޙͷΞϓϦʹඞͣ͋Γɺ ϦϑΝΫλϦϯά͍ͯ͘͜͠ͱ͕ॏཁɻ
͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·͢