Frontend Meetup vol.1 LT http://connpass.com/event/38112/ react + flux + floetypw
ֵ໋ͱடংͱSPA@joe_re
View Slide
Who am I?• twitter: @joe_re• github: @joe-re• freeeͱ͍͏ޒాͷ ձࣾͰಇ͍͍ͯ·͢• ΫϥυձܭιϑτΛ ࡞͍ͬͯ·͢
͢͜ͱ• ϑϩϯτΤϯυͷύϥμΠϜγϑτͱ freeeͷؔΘΓํ• React + Fluxͷߏங• flowtypeʹΑΔtype-safe flux
ͬ͘͟ΓϑϩϯτΤϯυͷྺ࢙ΛৼΓฦΔhttp://qiita.com/joe-re/items/3b6730eb90dbeb2f8272
ͬ͘͟ΓϑϩϯτΤϯυͷྺ࢙ΛৼΓฦΔ"KBYͷൃݟ 1SPUPUZQFKTɺK2VFSZͷ੮ר#BDLCPOFKTͷొ ϑϩϯτΤϯυʹ.7$͕࣋ͪࠐ·ΕΔXBZCJOEJOHͷྲྀߦ .77. "OHVMBSKTɺ7VFKTɺ.BSJOPOFUUFKTFUDʜձܭGSFFFϩʔϯν7JSUVBM%0.ͷొ %FLVɺ3FBDUɺ7VFKT YFUDʜmain topics of fronted history of freee2010200520122014 څ༩ܭࢉGSFFFϩʔϯνձܭGSFFF։ൃ։࢝ձࣾઃཱGSFFFϩʔϯνnow!
ॳظͷձܭfreeeͷϑϩϯτΤϯυ• 2012࣌ΑΖ͘͠ɺϑϩϯτBackbone.js• جຊతʹRailsଆͰϨϯμϦϯά• Backbone.jsಈ͖Λ͚ͭΔఔ• SPAͰͳ͍
͕࣌ܦͭʹͭΕߴ·ΔSPAཉ
ঃʑʹBackboneMVCΛ ϑϧʹ׆͔ͨ͠ ΞʔΩςΫνϟ (ϖʔδ୯ҐͰͷSPA)
ͦͯ͠ߴ·ΔͭΒΈ
ͭΒΈ• Backbone.jsͷviewಉ࢜ͷΠϕϯτϋϯυϦϯάͭΒ͍• ࢠؔʹ͋Δviewͷఆ͕ٛᐆດ• ։ൃऀ͕૿͑Δʹ͕ͨͬͯ͠ɺΠϕϯτͷߪಡղআϛεʹΑΔϝϞϦϦʔΫ͕ى͖ͨΓͯͨ͠• ͦͦDOMૢ࡞ਓؒͷΔ͜ͱ͡Όͳ͍
ֵ໋
freee-mvc-framework ͱ͍͏ࣾϑϨʔϜϫʔΫ͕ ੜ·Εͨ
freee-mvc-frameworkͰ ͍ͬͯΔ͜ͱ• backbone.jsΛϥοϓͯ͠ػೳڧԽ• viewͷΤϯτϦʔϙΠϯτͱͳΔ’page view’ͷՃ• backbone.jsͷϥΠϑαΠΫϧΛڧԽ• renderingͷޙʹɺ1͚ͩΑΕΔϥΠϑαΠΫϧrenderingޙʹݺͿϥΠϑαΠΫϧͷՃͳͲͳͲ• ঢ়ଶཧڧԽͯ͠ɺin-documented͔ͦ͏Ͱͳ͍͔ͳͲΛߟྀͨ͠͏͑Ͱͷ ϋϯυϦϯάՄೳʹͨ͠• ࢠؔͷDOMૢ࡞ɺΠϕϯτϋϯυϦϯάͷڧԽ• ͋ͱదʹศརౕΛಥͬࠐΉ
ͦΕͰDOMૢ࡞ͷͭΒΈܰݮ͞Εͳ͍͠ɺ ΠϕϯτϋϯυϦϯά ଟ͗ͯ͢ෳࡶոحͳͷ มΘΒͣ
ͦͷࠒੈؒͰ 2way-binding͕ྲྀߦ͠ɺ ੈ·͞ʹେϑϩϯτΤϯυϑϨʔϜϫʔΫ࣌ (2013ʙ2014)
࣌Λಉͯ͘͡͠ څ༩ܭࢉfreeeͷϩʔϯν
څ༩ܭࢉfreeeͷελοΫ• freee-js-framework(based on backbone)• Vue.js(MVVM)• શͳSPA
ͱ͜ΖͰMVVMͱ7JFX.PEFM7JFX.PEFMUser 2way bindingapplynotifyinteraction#BDLCPOF7JFX #BDLCPOF.PEFM7VF
MVVMʹΑͬͯಘͨͷ• 2way-bindingʹΑΔDOMૢ࡞͔Βͷ։์• Viewঢ়ଶΛ࣋ͨͳͯ͘ྑ͍(VM)• View͔ΒࡶͳϩδοΫͷআڈ
fin..?
ͦΜͳΘ͚ͳ͘• ෳϞσϧ͕ొ͢ΔViewͰ VMͰؔ࿈Λ੍ޚ͢Δͷ͕ͭΒ͍• ModelͱVMͷঢ়ଶͷ྆ํΛཧ͢ΔͷͭΒ͍• ·ͱΊΔͱঢ়ଶཧͭΒ͍• Object.obseveࢮΜͩ͠…
·͞ʹ͜Ε(͜ͷਤMVC͚ͩͲ)https://www.infoq.com/news/2014/05/facebook-mvc-flux
͋ͱVue.jsɺ0.10.6͔Β0.11.xͷBreaking changesଟ͗͢• https://github.com/vuejs/vue/wiki/0.10-to-0.11-migration-guide
freee-mvc-framework εέʔϧ͠ͳ͍• ෳࡶԽ͍ͯ͘͠ΞϓϦέʔγϣϯʹ ঃʑʹଠଧͪͰ͖ͳ͘ͳ͍ͬͯΔ• ΠϕϯτϋϯυϦϯάViewͷࢠؔΛՄࢹԽ͢Δ͜ͱ͕ୈҰͷతͳͷͰɺDOMૢ࡞ͷͭΒܰ͞ݮ͞Εͳ͍• ύϥμΠϜͷมԽʹରԠ͢Δؾྗͳ͘ɺਰୀ͍ͯ͘͠• ·͊ࣾಠࣗFWͷ࿏ͳΜͯ͜ΜͳͷͰ͢ΑͶ
React + Flux
React͓͞Β͍• FacebookͷViewϥΠϒϥϦ• ঢ়ଶཧΛపఈతʹview͔Βഉআ͢Δ (ঢ়ଶཧfluxʹΑΓStore)• Propsͱͯ͋͠ΔΛ͞ΕΔݶΓɺ ඞͣಉ͡ϨϯμϦϯάΛ͢ΔؔܕతΞϓϩʔν (ReactDOMมثʹͳΔ)• ࠩΛܭࢉͯ͠ө͢ΔɺVirtualDOMͷ࣮
Flux͓͞Β͍• ୯ํσʔλϑϩʔΛ࣮ݱ͢Δ࣮ύλʔϯ• ActionCreator → Dispatcher → Store → View• Component͔Βঢ়ଶΓ͞ΕɺStoreʹ֨ೲ͞ΕΔ• ඳըͷͨΊʹඞཁͳϩδοΫStoreʹͭΊ͜ΈɺViewʹඳըʹඞཁͳใ͕ߏࡁΈ Ͱ௨͞ΕΔͷͰݟ௨͕͠ྑ͘ͳΔ
2015ॳ಄ɺԶ͕࠷ڧͷFlux࣮ͩઓ૪ຄൃ• Alt• Reflux• Fluxxor• Fluxible• nuclear-js• Arda• Material Flux• Delorean• Flummox• Redux• etc...
ଟ͍…
ԿΛબͿ͔ ͋Δ͍બͳ͍͔
Reduxͷ಄(20155݄)• શͯͷঢ়ଶ1ͭͷJSONͰද͢(Single Store)• Data Flowͷొਓ(Action, Reducer) PureͳؔʹͳΔ• state͕ActionΛ௨ͯ͡ߋ৽͞ΕΔࡍʹɺ reducerͱ͍͏PureͳؔΛ௨͢͜ͱͰߋ৽͢Δ
ReduxͷੈքΛͬ͘͟Γ
طଘ࣮͕͋Δͱ͜Ζʹ ಋೖ͢Δ্ͰɺReduxͭΒ͍
ͪͳΈʹ࠷ॳʹಋೖ͞Εͨػೳ͜Ε(on Backbone view)
Single StoreͲ͜ʹ ࣋ͭ…??
flux-utilsΛ͏ͱ͍͏બ• ReduxΛ࢝Ίͱ͢Δflux࣮Ͱఏࣔ͞ΕͨϕετϓϥΫςΟεΛfacebook͕͍͍ͱ͜औΓͨ͠(ओ؍)• ͜Ε·Ͱఏڙ͍ͯͨ͠Dispatcher͚ͩͰͳ͘ Storeͷϕʔε࣮ͱContainerͱ͍͏֓೦͕Ճ͞Εͨ• fluxʹର͢ΔཉΛશͯຬͨ͢ͷͰͳ͍ (ϛχϚϜͳ࣮ͰɺϩοΫΠϯ͕গͳ͍)• ࣌Redux͕όζ͍͚ͬͯͨͲɺ·ͩ·࣮ͩ༻ྫ͕গͳͯ͘ εέʔϧ͢Δ͔Ͳ͏͔֬৴͕ͳ͔ͬͨͱ͍͏ͷ͋Δ
αϙʔτൣғখ͍͞ (ϑϨʔϜϫʔΫͰͳ͍)
Reduxͱͷڞ௨• ContainerComponent → Container• Reducer → Reduce Store
flux-utilsͷ͍͍ͱ͜Ζ• طଘͷflux͔Βဃ͠ͳ͍• αϙʔτൣғ͕খ͍͞ɺϩοΫΠϯ͕গͳ͍(͍͟ͱͳΕࣗͰ࣮Ͱ͖ΔϨϕϧ)• ΞϓϦέʔγϣϯશମʹؔΘΔϞδϡʔϧͳ͍ͷͰɺ෦తʹద༻Մೳ
͍ͦͯͬͯ͘͠ؾ࣋ͪ• ϑϩϯτΤϯυҕһձΛ݁• bowerΛΊͯnpmҠߦ• SprocketsΛࣺͯͯwebpack• ౖ౭ͷґଘղܾྗ(sprockets͔Βͷ٫)• React + FluxΛಋೖͰ͖Δج൫Λ͑ͨ
ͱ͍͏Θ͚ͳ͘• ϩοΫΠϯ͠ͳ͍ɺ࣮ʹࣗ༝͕͋Δ• Actionͷ࣮IFʹ౷Ұੑ͕ͳ͍• Storeͷঢ়ଶ͕ෳࡶʹ͋Γɺ࣌ͱͯ͠Viewʹ ϩδοΫ͕࿙Εग़ͯ͠Δ• StoreΛݟ͚ͨͩͰͲ͏͍͏ঢ়ଶΛཧ͍ͯ͠Δͷ͔͔ΓͮΒ͍
ػೳՃͷࡍʹ֤ͷIFΛ ཧղͤͣʹͨΓతʹ࣮͞ΕΔͷ͕ෳࡶ͞Λ૿͢ҰҼʹͳ͍ͬͯΔ
jsʹܕ͕͋Ε…
ܕ…
டং
flowtype
flowtype͓͞Β͍• FacebookͷJavaScriptͷੈքʹ੩తͳܕνΣοΫΛಋೖͰ͖Δπʔϧ• OCaml• ASTղੳͯ͠ɺґଘؔͷ͋Δͷ͚ͩΛ νΣοΫରʹ͢ΔͷͰ2Ҏ߱ͷίϯύΠϧ͕ര• ڧྗͳܕਪ• ఏڙ͢Δͷܕ͚༻ͷγϯλοΫεͱɺͦͷղੳͱิͷΈ (Not AltJS)• ͢ͰʹbabelΛ͍ͬͯΔ߹ʹpluginΛՃ͢Δ͚ͩͰ͙͑͢Δ
ཱ• jsʹඞͣ͠ܕ͕ඞཁ͔ͱ͍͏ͱͦ͏Ͱͳ͍͚Ͳɺ νʔϜ։ൃͰඞਢͱߟ͍͑ͯΔ• ͕࣮ࣗͨ͠ϞδϡʔϧͷIFΛ໌֬ʹ͢Δ͜ͱͰ յΕʹ͍࣮͘ʹͰ͖Δ (յ͞ΕͨΒΤϥʔʹͳΔ)• νΣοΫ͕Ұ൪ͷత͚ͩͲɺ ิʹΑΔ։ൃޮͷ্ૂͬͯߦ͖͍ͨ
flow-typed componentUZQF1SPQT\UJUMFTUSJOH WJTJUFECPPMFBO PO$MJDL WPJE ^DMBTT#VUUPOFYUFOET3FBDU$PNQPOFOU\QSPQT1SPQTTUBUF\EJTQMBZTUBUJDcIPWFScBDUJWF^ʜ^ΫϥεԼʹ1SPQTɺ4UBUFͷUZQFΛࢦఆ ˞ཁUSBOTGPSNDMBTTQSPQFSUJFT TUBHF
flow-typed componentFYQPSUEFGBVMUDMBTT)PHF$PNQPOFOUFYUFOET3FBDU$PNQPOFOU\SFOEFS \SFUVSO #VUUPOUJUMFIJHFWJTJUFE\GBMTF^^^PO$MJDLϓϩύςΟΛ͠Ε͍ͯΔͷͰ Τϥʔ͕ग़ΔqPX)PHF$PNQPFOUOKTY#VUUPOUJUMFIJHFWJTJUFE\GBMTF^???????????????????????????????????????3FBDUFMFNFOUA#VUUPOAQSPQT1SPQT?????QSPQFSUZAPO$MJDLA1SPQFSUZOPUGPVOEJO4FFCVUUPOKTY#VUUPOUJUMFIJHFWJTJUFE\GBMTF^???????????????????????????????????????QSPQTPG3FBDUFMFNFOUA#VUUPOA
flow-typed actionUZQF'&5$)@"--\[email protected]` IPQFT"SSBZ)PHF^UZQF4"7&\UZQFTBWF IPHF)PHF^UZQF%&-&5&\UZQFEFMFUF JEOVNCFS^FYQPSUUZQF"DUJPO5ZQFT'&5$)@"--c4"7&c%&-&5&GVODUJPOEJBQBUDI QBSBNT"DUJPO5ZQFT\"QQ%JTQBUDIFSEJTQBUDI QBSBNT^FYQPSUEFGBVMU\GFUDI"MM \HFU bIPHF`UIFO EBUBEJBQBUDI \[email protected]` IPHFTEBUBIPHFT^^^TBWF IPHF)PHF\QVU AIPHF\IPHFJE^A \ʜIPHF`TQBSBNT^ UIFO EBUBEJBQBUDI \[email protected]` IPHFEBUBIPHF^^^EFMFUF JEOVNCFS\EFMFUF AIPHF\JE^AUIFO @EBUBEJTQBUDI \UZQFbEFMFUF` JE^^֤"DUJPOͷUZQFΛఆٛ͠ɺ VOJPOUZQFTͱͯ͠·ͱΊΔBDUJPOͰEJTQBUDI͢ΔUZQFΛ ఆٛͨ͠VOJPOUZQFTʹ͢Δ֤EJTQBUDIఆٛͨ͠ VOJPOUZQFTͷ͍ͣΕ͔Λ ຬͨ͢
flow-typed actionFYQPSUEFGBVMU\GFUDI"MM \HFU bIPHF`UIFO EBUBEJBQBUDI \[email protected]` IPHFTEBUBIPHFT^^^TBWF IPHF)PHF\QVU AIPHF\IPHFJE^A \ʜIPHF`TQBSBNT^ UIFO EBUBEJBQBUDI \[email protected]` IPHFEBUBIPHF^^^EFMFUF JEOVNCFS\EFMFUF AIPHF\JE^AUIFO @EBUBEJTQBUDI \UZQFbEFMFUF` JE^^FYQPSUEFGBVMU)PHF$PNQPOFOUFYUFOET3FBDU$PNQPOFOU\IBOEMF$MJDL%FMFUF)PHF F\ "DUJPOEFMFUF \JEUIJTTUBUFTFMFDUFE^^ ʜ^ActionComponent$PNQPOFOU͔Β"DUJPO$SFBUFSΛୟ͘ࡍͷ*'อূ͞ΕΔ
flow-typed stateJNQPSUUZQFT\"DUJPO5ZQFT^GSPN)PHF"DUJPOFYQPSUUZQF4UBUF\IPHFT\
flow-typed storeEFDMBSFNPEVMFqVYVUJMT\EFDMBSFDMBTT3FEVDF4UPSF5\HFU4UBUF 5^^JNQPSU)PHF4UPSFGSPN)PHF4UPSFJNQPSUUZQF\4UBUF^GSPN)PHF4UPSFDMBTT)PHF$POUBJOFSFYUFOET3FBDU$PNQPOFOU\TUBUF4UBUFTUBUJDHFU4UPSFT \SFUVSO)PHF4UPSF>^TUBUJDDBMDVMBUF4UBUF @QSFW4UBUF4UBUF4UBUF\SFUVSO)PHF4UPSFHFU4UBUF ^SFOEFS \ʜDeclare ReduceStoreComponentHFOFSJDTͰ4UPSFʹ༩͑ͨ ܕΛHFU4UBUFͰड͚औΕΔΑ͏ʹ͢Δ3FEVDF4UPSFͷHFU4UBUFΛݺͼग़ͨ࣌͠ʹ 4UPSFͰఆٛͨ͠ܕใΛड͚औΕΔ
We got type-safe flux!
ͱ͍ͬͨͷͷ ͜͜·Ͱग़དྷ͍ͯΔ ͱ͜Ζ͕͋Δ͔ͱ͍͏ͱ ࣮ͷͱ͜Ζ·ͩ͋·Γͳ͍
We are hiring!http://jobs.jobvite.com/freee/jobs
Thank you for your attention!