Slide 1

Slide 1 text

.JDSP'SPOUFOET .JDSPTFSWJDFT.FFUVQ7PM

Slide 2

Slide 2 text

ࣗݾ঺հ !2 • ໊લ: ᖒҪ એ඙
 ʢ͞Θ͍ ͷͿͻ͜ʣ • twitter/github: nobuhikosawai • ΤϯδχΞྺ: 2೥ͪΐ͍ • αʔόʔαΠυ(Rails) • ϑϩϯτΤϯυ(React.js)

Slide 3

Slide 3 text

͍͖ͳΓͷએ఻ !3 IUUQTPUBZCPPUIQNJUFNT ٕज़ॻయ4ͰʮMicroservices architecture ΑΖͣຊʯͱ͍͏ຊΛग़͠·ͨ͠ɻ ୈ5ষͰMicro Frontends΋৮Ε͍ͯ·͢ɻ ΈΜͳങͬͯͶ

Slide 4

Slide 4 text

.JDSP'SPOUFOETʹཉ͍͠΋ͷ !4 • 6*ίϯϙʔωϯτͷఏڙ • 6*ίϯϙʔωϯτؒͷڠௐ • 6*ίϯϙʔωϯτؒͷΠϕϯτϋϯυϦϯά • 6*ɾϢʔβʔମݧͷ౷Ұ

Slide 5

Slide 5 text

.JDSP'SPOUFOETͷύλʔϯ !5 • ن໛ͱ΍Γ͍ͨ͜ͱͰ͍͔ͭ͘ͷύλʔϯ͕͋Δ • ϖʔδભҠΛͯ͠΋ྑ͍ύλʔϯ • ϖʔδʹෳ਺ίϯϙʔωϯτΛද͍ࣔͨ͠ύλʔϯ

Slide 6

Slide 6 text

ϖʔδભҠΛͯ͠΋ྑ͍ύλʔϯ !6 • ैདྷͷϝχϡʔόʔͳͲ͔ΒભҠ͢Δύλʔϯɻ • جຊతʹͭͷαʔϏε͕ͭͷ7JFXΛ࣋ͭɻ • ମݧͷҰ؏ੑΛ୲อ͢ΔͨΊʹҎԼ͕ඞཁ • 4JOHMF4JHO0O • 6*ͷ౷Ұ • ϔομʔͳͲͷϩδοΫΛؚΉΑ͏ͳίϯϙʔωϯτ – ίϐϖ – ϥΠϒϥϦͰఏڙ͢Δ – ͭͷαʔϏε͕ฦ͢ JGSBNFͰදࣔ͢Δʣ • ϘλϯͳͲͷγϯϓϧͳ6*ύʔπ

Slide 7

Slide 7 text

ϖʔδʹෳ਺ίϯϙʔωϯτΛද͍ࣔͨ͠ύλʔϯ !7 ෳ਺ίϯϙʔωϯτͷදࣔํ๏͸େ͖͘෼͚ͯͭ • JGSBNFΛ࢖͏ύλʔϯ • 8FC$PNQPOFOUTΛ࢖͏ύλʔϯ

Slide 8

Slide 8 text

JGSBNFΛ࢖͏ํ๏ !8 • 6*ίϯϙʔωϯτͷఏڙ֤νʔϜ͕)5.-Λఏڙ • 6*ίϯϙʔωϯτؒͷΠϕϯτϋϯυϦϯάJGSBNF ͷQPTU.FTTBHF

Slide 9

Slide 9 text

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);

Slide 10

Slide 10 text

JGSBNFΛ࢖͏৔߹ͷίʔυΠϝʔδ !10 • ਌ίϯϙʔωϯτ class Parent extends React.Component { componentDidMount() { window.addEventListener('message', this.doSomething, false); } componentWillUnmount() { window.removeEventListener('message', this.doSomething, false); } doSomething() { // do something } }

Slide 11

Slide 11 text

8FC$PNQPOFOUTΛ࢖͏ํ๏ !11 • ΋͏ͪΐͬͱϞμϯͳํ๏ͱͯ͠8FC$PNQPOFOUTΛ ࢖༻͢Δ

Slide 12

Slide 12 text

ͪΐͬͱͦΕͯ8FC$PNQPOFOUTͱ͸ͳʹ͔ !12 • ׬શʹཧղͨ͠͹͔Γ ͪΐͬͱυΩϡϝϯτݟͨͩ ͚ʣͳͷͰɺϚαΧϦ͸͓खॊΒ͔ʹ͓ئ͍͠·͢

Slide 13

Slide 13 text

8FCDPNQPOFOUTͱ͸ͳʹ͔ !13 • 8FCDPNQPOFOUTBSFBTFUPGXFCQMBUGPSN"1*T UIBUBMMPXZPVUPDSFBUFOFXDVTUPN SFVTBCMF FODBQTVMBUFE)5.-UBHTUPVTFJOXFCQBHFTBOE XFCBQQT • 8FCDPNQPOFOUTͱ͸ɺ΢Σϒϖʔδ΍΢ΣϒΞϓϦͷ தͰར༻Մೳͳɺಠࣗͷ࠶ར༻ՄೳͰΧϓηϧԽ͞Εͨ )5.-λάΛ࡞ΔͨΊͷXFCϓϥοτϑΥʔϜͷ"1*Ͱ͢ɻ

Slide 14

Slide 14 text

8FCDPNQPOFOUTͱ͸ͳʹ͔ !14 • ҎԼͷओͳ࢓༷͔Β੒Δɻ • $VTUPN&MFNFOUT • 4IBEPX%0. • )5.-JNQPSUT • )5.-5FNQMBUF

Slide 15

Slide 15 text

γϣοϐϯάαΠτͷྫ !15 • NJDSPGSPOUFOETPSHͷαϯϓϧΛྫʹ • γϣοϐϯάαΠτͷػೳ • ঎඼બ୒ • ߪೖϘλϯ • Ϩίϝϯυ

Slide 16

Slide 16 text

γϣοϐϯάαΠτͷྫ !16 • ػೳ͝ͱʹνʔϜ͕ಠཱ • ͋ͳͨ͸ߪೖνʔϜʢ੨νʔϜʣʹଐ͍ͯ͠·͢ • ͜ΕΛ8FC$PNQPOFOUTͰ.JDSP'SPOUFOETͯ͠ΈΔ

Slide 17

Slide 17 text

$VTUPN&MFNFOUTͷྫ !17 • ·ͣ͸ϘλϯΛදࣔͤ͞Δ • 6*ίϯϙʔωϯτͷఏڙ
 8FC$PNQPOFOUTΛར༻ • ͱ͘ʹ$VTUPN&MFNFOUTΛར༻

Slide 18

Slide 18 text

$VTUPN&MFNFOUTͷྫ !18 • $VTUPN&MFNFOUTͷఆٛͱݺͼग़͠ – λά໊͕িಥ͠ͳ͍Α͏ʹ஫ҙʢQSFGJYͳͲʣ class BlueBuy extends HTMLElement { constructor() { super(); this.innerHTML = `buy for 66,00 €`; } disconnectedCallback() { ... } } window.customElements.define('blue-buy', BlueBuy);

Slide 19

Slide 19 text

਌͔Βࢠ΁ͷ௨৴%0.ͷमਖ਼ͷํ๏ !19 • ࣍ʹ঎඼ͷը૾Λબ୒ͨ͠ΒɺߪೖϘλϯͷֹۚදࣔΛ ม͑Δํ๏Λߟ͑Δ • $VTUPN&MFNFOUTͷଐੑ஋ͰදࣔΛม͑Δ • PCTFSWFE"UUSJCVUFTʹ؍ଌଐੑΛઃఆ • BUUSJCVUF$IBOHFE$BMMCBDLͰ࠶SFOEFSΛ࣮ߦ • 3FBDUͰ͍͏ͱ͜ΖͷQSPQTͷมߋ ʢ$PNQPOFOU8JMM3FDFJWF1SPQTΈ͍ͨͳʣ

Slide 20

Slide 20 text

਌͔Βࢠ΁ͷ௨৴%0.ͷमਖ਼ͷํ๏ !20 • BUUSJCVUFTΛड͚औΕΔ༻ʹઃఆ • 3FBDUQSPQTΈ͍ͨͳ • )5.-EBUBଐੑ

Slide 21

Slide 21 text

਌͔Βࢠ΁ͷ௨৴%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 = `buy for ${price}`; } attributeChangedCallback(attr, oldValue, newValue) { this.render(); } disconnectedCallback() {...} } window.customElements.define('blue-buy', BlueBuy);

Slide 22

Slide 22 text

ࢠ͔Β਌PSܑఋཁૉಉ࢜ͷ௨৴%0.&WFOUT !22 • ߪೖϘλϯΛΫϦοΫ͢ΔͱΧʔτͷ਺ࣈ͕มߋ͞Εͯ ཉ͍͠ • &WFOUϞσϧΛ࢖༻ 1VC4VC • ૄ݁߹ • $VTUPN&WFOUTʹΑΓಠࣗͷ&WFOUఆ͕ٛՄೳ

Slide 23

Slide 23 text

ࢠ͔Β਌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 = `buy`; } disconnectedCallback() { this.firstChild.removeEventListener('click', this.addToCart); } } • ߪೖϘλϯଆ QVCMJTI

Slide 24

Slide 24 text

ࢠ͔Β਌΁ͷ௨৴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

Slide 25

Slide 25 text

ͦͷଞͷ࿦఺ !25 • ಈ࡞͢Δ͜ͱʹ੒ޭ͕ͨ͠ଞʹ΋ߟྀ͢΂͖͜ͱ͕ͨ͘ ͞Μɻ • ྫͱͯ͠ҎԼΛߟ࡯͢Δɻ • 6*ͷ౷Ұ • 3PVUJOH

Slide 26

Slide 26 text

6*ͷ౷Ұ !26 • HMPCBMͳ$44Λఏڙ͢Δ • ϥΠϒϥϦΛఏڙ͢Δ • OQN • CPPUTUSBQͳͲ • 8FC$PNQPOFOUT • ϘλϯͷΑ͏ͳ6*ύʔπͳͲ

Slide 27

Slide 27 text

6*ͷ౷Ұ !27 • HMPCBMͳ$44 • ϝϦοτಋೖ͕؆୯ɺҰ؏ੑͷ୲อ͕༰қ • σϝϦοτංେԽ͠΍͍͢ɺϦϑΝΫλϦϯά͕ࠔ೉ • MJCSBSZ • ϝϦοτಠཱͯ͠मਖ਼Մೳ • σϝϦοτCVJMEπʔϧʹґଘ͢Δ৔߹͕͋Δɺόʔδϣ ϯࠩ෼ʹΑΔ6*ͷෆҰக

Slide 28

Slide 28 text

3PVUJOH !28 • ભҠ͍Ζ͍Ζ • νʔϜ಺෦ͷϧʔςΟϯάͷભҠWTνʔϜؒΛ·͙ͨભҠ • ϑϧϨϯμϦϯάWTύʔγϟϧϨϯμϦϯά IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOETUIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE

Slide 29

Slide 29 text

3PVUJOH !29 • νʔϜ಺෦͚ͩεϜʔζʹҠಈͰ͖Δྫ • ࣮૷͸ൺֱత୯७ • νʔϜΛ·͙ͨͱ͖ʹ69͕௿Լ͢Δ IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOETUIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE

Slide 30

Slide 30 text

3PVUJOH !30 • νʔϜؒΛ·͙ͨભҠΛύʔγϟϧϨϯμϦϯάͰ΍Δ ྫ • ϧʔςΟϯάͱͦΕʹରԠ͢ΔGSBHNFOUͷϚοϐϯάΛ ࣮࣋ͬͯݱ͢Δ IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOETUIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE

Slide 31

Slide 31 text

ύωϧσΟεΧογϣϯ΁ͷ໰୊ఏى !31 • .JDSP'SPOUFOETΛΊ͙Δ໰୊ • νʔϜ෼ׂ • 8FC$PNQPOFOUTͷຊ൪౤ೖ • 6*ϥΠϒϥϦͷఏڙ • ೝূͲ͏͢Δ͔ • 'SBNFXPSLDPNQBUJCJMJUZ • ύϑΥʔϚϯε • ΞʔΩςΫνϟ • ͳͲ • ϑϩϯτΤϯυͷະདྷͱະདྷʹ޲͚ͯԿ͕Ͱ͖Δͷ͔Λ ٞ࿦͍ͨ͠ͱࢥ͍·͢ɻ

Slide 32

Slide 32 text

ࢀߟࢿྉ !32 • IUUQTNJDSPGSPOUFOETPSH • IUUQTTQFBLFSEFDLDPNOBMUBUJTNJDSPGSPOUFOET UIJOLTNBMMFSBWPJEUIFNPOPMJUIMPWFUIFCBDLFOE

Slide 33

Slide 33 text

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