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
Micro Frontends (example from micro-frontends.org)
Search
nobuhikosawai
July 31, 2018
Programming
0
970
Micro Frontends (example from micro-frontends.org)
Microservices meetup vol.7の発表資料です。
マイクロフロントエンドの概要とサンプルをmicro-frontends.orgの例をもとに解説しています。
nobuhikosawai
July 31, 2018
Tweet
Share
More Decks by nobuhikosawai
See All by nobuhikosawai
GraphQLを用いたサイトに おけるパフォーマンス改善 (ECサイトを題材に)/ Improving online shopping site performance which using the GraphQL
nobuhikosawai
3
5.9k
Micro Frontends の理論と実践 -価値提供を高速化する真のマイクロサービスのあり方- / The Theory and Practice of Micro Frontends
nobuhikosawai
17
40k
Railsのタイムゾーン
nobuhikosawai
4
2.4k
Other Decks in Programming
See All in Programming
AIに安心して任せるためにTypeScriptで一意な型を作ろう
arfes0e2b3c
0
370
兎に角、コードレビュー
mitohato14
0
130
WebAssemblyインタプリタを書く ~Component Modelを添えて~
ruccho
1
830
変化を楽しむエンジニアリング ~ いままでとこれから ~
murajun1978
0
730
Claude Code と OpenAI o3 で メタデータ情報を作る
laket
0
130
CEDEC 2025 『ゲームにおけるリアルタイム通信への QUIC導入事例の紹介』
segadevtech
3
890
#QiitaBash TDDで(自分の)開発がどう変わったか
ryosukedtomita
1
370
実践!App Intents対応
yuukiw00w
1
280
あまり知られていない MCP 仕様たち / MCP specifications that aren’t widely known
ktr_0731
0
270
Infer入門
riru
4
1.5k
decksh - a little language for decks
ajstarks
4
21k
Flutter로 Gemini와 MCP를 활용한 Agentic App 만들기 - 박제창 2025 I/O Extended Seoul
itsmedreamwalker
0
140
Featured
See All Featured
Being A Developer After 40
akosma
90
590k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Thoughts on Productivity
jonyablonski
69
4.8k
RailsConf 2023
tenderlove
30
1.2k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.4k
Art, The Web, and Tiny UX
lynnandtonic
301
21k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Navigating Team Friction
lara
188
15k
Music & Morning Musume
bryan
46
6.7k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Fireside Chat
paigeccino
39
3.6k
Transcript
.JDSP'SPOUFOET .JDSPTFSWJDFT.FFUVQ7PM
ࣗݾհ !2 • ໊લ: ᖒҪ એ ʢ͞Θ͍ ͷͿͻ͜ʣ • twitter/github:
nobuhikosawai • ΤϯδχΞྺ: 2ͪΐ͍ • αʔόʔαΠυ(Rails) • ϑϩϯτΤϯυ(React.js)
͍͖ͳΓͷએ !3 IUUQTPUBZCPPUIQNJUFNT ٕज़ॻయ4ͰʮMicroservices architecture ΑΖͣຊʯͱ͍͏ຊΛग़͠·ͨ͠ɻ ୈ5ষͰMicro Frontends৮Ε͍ͯ·͢ɻ ΈΜͳങͬͯͶ
.JDSP'SPOUFOETʹཉ͍͠ͷ !4 • 6*ίϯϙʔωϯτͷఏڙ • 6*ίϯϙʔωϯτؒͷڠௐ • 6*ίϯϙʔωϯτؒͷΠϕϯτϋϯυϦϯά • 6*ɾϢʔβʔମݧͷ౷Ұ
.JDSP'SPOUFOETͷύλʔϯ !5 • نͱΓ͍ͨ͜ͱͰ͍͔ͭ͘ͷύλʔϯ͕͋Δ • ϖʔδભҠΛͯ͠ྑ͍ύλʔϯ • ϖʔδʹෳίϯϙʔωϯτΛද͍ࣔͨ͠ύλʔϯ
ϖʔδભҠΛͯ͠ྑ͍ύλʔϯ !6 • ैདྷͷϝχϡʔόʔͳͲ͔ΒભҠ͢Δύλʔϯɻ • جຊతʹͭͷαʔϏε͕ͭͷ7JFXΛ࣋ͭɻ • ମݧͷҰ؏ੑΛ୲อ͢ΔͨΊʹҎԼ͕ඞཁ • 4JOHMF4JHO0O
• 6*ͷ౷Ұ • ϔομʔͳͲͷϩδοΫΛؚΉΑ͏ͳίϯϙʔωϯτ – ίϐϖ – ϥΠϒϥϦͰఏڙ͢Δ – ͭͷαʔϏε͕ฦ͢ JGSBNFͰදࣔ͢Δʣ • ϘλϯͳͲͷγϯϓϧͳ6*ύʔπ
ϖʔδʹෳίϯϙʔωϯτΛද͍ࣔͨ͠ύλʔϯ !7 ෳίϯϙʔωϯτͷදࣔํ๏େ͖͚ͯͭ͘ • JGSBNFΛ͏ύλʔϯ • 8FC$PNQPOFOUTΛ͏ύλʔϯ
JGSBNFΛ͏ํ๏ !8 • 6*ίϯϙʔωϯτͷఏڙ֤νʔϜ͕)5.-Λఏڙ • 6*ίϯϙʔωϯτؒͷΠϕϯτϋϯυϦϯάJGSBNF ͷQPTU.FTTBHF
JGSBNFΛ͏߹ͷίʔυΠϝʔδ !9 • ࢠίϯϙʔωϯτ function receiveMessage(event) { if (event.origin !==
'http://example.com') { return; } ɹif (event.data === 'getHelloWorld') { event.source.postMessage( 'hello world', event.origin ); } } window.addEventListener('message', receiveMessage, false);
JGSBNFΛ͏߹ͷίʔυΠϝʔδ !10 • ίϯϙʔωϯτ class Parent extends React.Component { componentDidMount()
{ window.addEventListener('message', this.doSomething, false); } componentWillUnmount() { window.removeEventListener('message', this.doSomething, false); } doSomething() { // do something } }
8FC$PNQPOFOUTΛ͏ํ๏ !11 • ͏ͪΐͬͱϞμϯͳํ๏ͱͯ͠8FC$PNQPOFOUTΛ ༻͢Δ
ͪΐͬͱͦΕͯ8FC$PNQPOFOUTͱͳʹ͔ !12 • શʹཧղ͔ͨ͠Γ ͪΐͬͱυΩϡϝϯτݟͨͩ ͚ʣͳͷͰɺϚαΧϦ͓खॊΒ͔ʹ͓ئ͍͠·͢
8FCDPNQPOFOUTͱͳʹ͔ !13 • 8FCDPNQPOFOUTBSFBTFUPGXFCQMBUGPSN"1*T UIBUBMMPXZPVUPDSFBUFOFXDVTUPN SFVTBCMF FODBQTVMBUFE)5.-UBHTUPVTFJOXFCQBHFTBOE XFCBQQT •
8FCDPNQPOFOUTͱɺΣϒϖʔδΣϒΞϓϦͷ தͰར༻Մೳͳɺಠࣗͷ࠶ར༻ՄೳͰΧϓηϧԽ͞Εͨ )5.-λάΛ࡞ΔͨΊͷXFCϓϥοτϑΥʔϜͷ"1*Ͱ͢ɻ
8FCDPNQPOFOUTͱͳʹ͔ !14 • ҎԼͷओͳ༷͔ΒΔɻ • $VTUPN&MFNFOUT • 4IBEPX%0. • )5.-JNQPSUT
• )5.-5FNQMBUF
γϣοϐϯάαΠτͷྫ !15 • NJDSPGSPOUFOETPSHͷαϯϓϧΛྫʹ • γϣοϐϯάαΠτͷػೳ • બ • ߪೖϘλϯ
• Ϩίϝϯυ
γϣοϐϯάαΠτͷྫ !16 • ػೳ͝ͱʹνʔϜ͕ಠཱ • ͋ͳͨߪೖνʔϜʢ੨νʔϜʣʹଐ͍ͯ͠·͢ • ͜ΕΛ8FC$PNQPOFOUTͰ.JDSP'SPOUFOETͯ͠ΈΔ
$VTUPN&MFNFOUTͷྫ !17 • ·ͣϘλϯΛදࣔͤ͞Δ • 6*ίϯϙʔωϯτͷఏڙ 8FC$PNQPOFOUTΛར༻ • ͱ͘ʹ$VTUPN&MFNFOUTΛར༻
$VTUPN&MFNFOUTͷྫ !18 • $VTUPN&MFNFOUTͷఆٛͱݺͼग़͠ – λά໊͕িಥ͠ͳ͍Α͏ʹҙʢQSFGJYͳͲʣ class BlueBuy extends HTMLElement
{ constructor() { super(); this.innerHTML = `<button type="button">buy for 66,00 €</button>`; } disconnectedCallback() { ... } } window.customElements.define('blue-buy', BlueBuy); <blue-buy></blue-buy>
͔Βࢠͷ௨৴%0.ͷमਖ਼ͷํ๏ !19 • ࣍ʹͷը૾Λબͨ͠ΒɺߪೖϘλϯͷֹۚදࣔΛ ม͑Δํ๏Λߟ͑Δ • $VTUPN&MFNFOUTͷଐੑͰදࣔΛม͑Δ • PCTFSWFE"UUSJCVUFTʹ؍ଌଐੑΛઃఆ •
BUUSJCVUF$IBOHFE$BMMCBDLͰ࠶SFOEFSΛ࣮ߦ • 3FBDUͰ͍͏ͱ͜ΖͷQSPQTͷมߋ ʢ$PNQPOFOU8JMM3FDFJWF1SPQTΈ͍ͨͳʣ
͔Βࢠͷ௨৴%0.ͷमਖ਼ͷํ๏ !20 • BUUSJCVUFTΛड͚औΕΔ༻ʹઃఆ • 3FBDUQSPQTΈ͍ͨͳ • )5.-EBUBଐੑ <blue-buy sku="t_fendt"></blue-buy>
͔Βࢠͷ௨৴%0.ͷमਖ਼ͷํ๏ !21 const prices = { t_porsche: '66,00 €', t_eicher:
'58,00 €’, … }; class BlueBuy extends HTMLElement { static get observedAttributes() { return ['sku']; } constructor() { super(); this.render(); } render() { const sku = this.getAttribute('sku'); const price = prices[sku]; this.innerHTML = `<button type="button">buy for ${price}</button>`; } attributeChangedCallback(attr, oldValue, newValue) { this.render(); } disconnectedCallback() {...} } window.customElements.define('blue-buy', BlueBuy);
ࢠ͔ΒPSܑఋཁૉಉ࢜ͷ௨৴%0.&WFOUT !22 • ߪೖϘλϯΛΫϦοΫ͢ΔͱΧʔτͷࣈ͕มߋ͞Εͯ ཉ͍͠ • &WFOUϞσϧΛ༻ 1VC4VC •
ૄ݁߹ • $VTUPN&WFOUTʹΑΓಠࣗͷ&WFOUఆ͕ٛՄೳ
ࢠ͔ΒPSܑఋཁૉಉ࢜ͷ௨৴%0.&WFOUT !23 class BlueBuy extends HTMLElement { [...] connectedCallback() {
[...] this.render(); this.firstChild.addEventListener('click', this.addToCart); } addToCart() { // maybe talk to an api this.dispatchEvent(new CustomEvent('blue:basket:changed', { bubbles: true, })); } render() { this.innerHTML = `<button type="button">buy</button>`; } disconnectedCallback() { this.firstChild.removeEventListener('click', this.addToCart); } } • ߪೖϘλϯଆ QVCMJTI
ࢠ͔Βͷ௨৴PSܑఋཁૉಉ࢜ͷ௨৴%0.&WFOUT !24 class BlueBasket extends HTMLElement { connectedCallback() { [...]
window.addEventListener('blue:basket:changed', this.refresh); } refresh() { // fetch new data and render it } disconnectedCallback() { window.removeEventListener('blue:basket:changed', this.refresh); } } • ΧʔτଆʢTVCTDSJCF
ͦͷଞͷ !25 • ಈ࡞͢Δ͜ͱʹޭ͕ͨ͠ଞʹߟྀ͖͢͜ͱ͕ͨ͘ ͞Μɻ • ྫͱͯ͠ҎԼΛߟ͢Δɻ • 6*ͷ౷Ұ •
3PVUJOH
6*ͷ౷Ұ !26 • HMPCBMͳ$44Λఏڙ͢Δ • ϥΠϒϥϦΛఏڙ͢Δ • OQN • CPPUTUSBQͳͲ
• 8FC$PNQPOFOUT • ϘλϯͷΑ͏ͳ6*ύʔπͳͲ
6*ͷ౷Ұ !27 • HMPCBMͳ$44 • ϝϦοτಋೖ͕؆୯ɺҰ؏ੑͷ୲อ͕༰қ • σϝϦοτංେԽ͍͢͠ɺϦϑΝΫλϦϯά͕ࠔ • MJCSBSZ
• ϝϦοτಠཱͯ͠मਖ਼Մೳ • σϝϦοτCVJMEπʔϧʹґଘ͢Δ߹͕͋Δɺόʔδϣ ϯࠩʹΑΔ6*ͷෆҰக
3PVUJOH !28 • ભҠ͍Ζ͍Ζ • νʔϜ෦ͷϧʔςΟϯάͷભҠWTνʔϜؒΛ·͙ͨભҠ • ϑϧϨϯμϦϯάWTύʔγϟϧϨϯμϦϯά IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOETUIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE
3PVUJOH !29 • νʔϜ෦͚ͩεϜʔζʹҠಈͰ͖Δྫ • ࣮ൺֱత୯७ • νʔϜΛ·͙ͨͱ͖ʹ69͕Լ͢Δ IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOETUIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE
3PVUJOH !30 • νʔϜؒΛ·͙ͨભҠΛύʔγϟϧϨϯμϦϯάͰΔ ྫ • ϧʔςΟϯάͱͦΕʹରԠ͢ΔGSBHNFOUͷϚοϐϯάΛ ࣮࣋ͬͯݱ͢Δ IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOETUIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE
ύωϧσΟεΧογϣϯͷఏى !31 • .JDSP'SPOUFOETΛΊ͙Δ • νʔϜׂ • 8FC$PNQPOFOUTͷຊ൪ೖ • 6*ϥΠϒϥϦͷఏڙ
• ೝূͲ͏͢Δ͔ • 'SBNFXPSLDPNQBUJCJMJUZ • ύϑΥʔϚϯε • ΞʔΩςΫνϟ • ͳͲ • ϑϩϯτΤϯυͷະདྷͱະདྷʹ͚ͯԿ͕Ͱ͖Δͷ͔Λ ͍ٞͨ͠ͱࢥ͍·͢ɻ
ࢀߟࢿྉ !32 • IUUQTNJDSPGSPOUFOETPSH • IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOET UIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠