$30 off During Our Annual Pro Sale. View Details »

Real World Virtual DOM

Real World Virtual DOM

React, Flux, Isormorphic そして現実

Koutarou Chikuba

February 16, 2015
Tweet

More Decks by Koutarou Chikuba

Other Decks in Technology

Transcript

  1. Real World Virtual DOM
    React, Flux, Isormorphic… ͦͯ͠ݱ࣮
    ɹ
    @mizchi / Increments Inc

    View Slide

  2. ࣗݾ঺հ
    ☞ id:mizchi | ஛അޫଠ࿠
    ☞ Qiitaͷํ͔Βདྷ·ͨ͠
    ☞ ۀ຿ΤϯδχΞྺ3೥
    ☞ ੵΈήʔ͕ऴΘΒΜ

    View Slide

  3. ࠓ·Ͱ࢓ࣄ͖ͯͨ͠؀ڥ
    ৽ଔͰ࠷ॳʹॻ͍ͨݴޠ͸ Haskell ͱ Clojure
    ͱ͋ΔήʔϜͷUnity͔ΒHTML5΁ͷҠ২Λͯ͠Ҏ
    དྷɺSPAͷઃܭΛߟ͑ଓ͚͍ͯΔ

    View Slide

  4. Virtual DOM ʹ͍ͭͯͷ׆ಈ
    ☞ VirtualDOM Advent Calendar 2014 - Qiita ͷओ࠵
    ☞ ͋ͳ͕ͨReactΛ࢖͏΂͖ཧ༝
    ☞ ͳͥԾ૝DOMͱ͍͏֓೦͕ԶୡͷࠢΛ਒͑ͤ͞Δ
    ͷ͔ - Qiita
    ☞ #13 Virtual DOM | mozaic.fm ͷήετ

    View Slide

  5. Έͳ͞Μ

    View Slide

  6. ࠢ਒͑ͯ·͢ʁ

    View Slide

  7. ๻͕Reactʹ͍ͭͯ
    ৘ใൃ৴͍ͯͨ͠ཧ༝

    View Slide

  8. ཧ༝
    ☞ ʮԶ͕ϓϩμΫγϣϯͰ࢖͍͍͔ͨΒʯʹܾ·ͬ
    ͯΜ͡ΌΜʂ
    ☞ Έͳ͞Μ͝ڠྗ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂʂʂʂ

    View Slide

  9. ݁Ռ
    yaottiʮXXX Λ AtomShellͰWindows ޲͚ʹ࡞Εͳ
    ͍ʁʯ
    mizchiʮ͋͊ʈʙ͍͍ͬ͢Ͷʙʯ
    ɹ
    mizchiʮϓϩτͰ React ࢖͚ͬͨͲ͜Μ··͍͖·͠
    ΐ͏ʯ => Go

    View Slide

  10. ʮ࢖ͬͯΈͨʯ
    ☞ ਓபʹͳͬͨ
    ☞ ͱ͍͏Θ͚ͰReactΛݱ৔Ͱ࢖ͬͯΈͨ࿩Λ͠·͢
    (ΈΜͳVirtual DOM ͸༧शࡁΈͩΑͶʁ)

    View Slide

  11. ࠓ೔ͷςʔϚ
    Real World Virtual DOM
    ☞ ୈҰষ: Kobito on AtomShell
    ☞ ୈೋষ: Arda - MetaFlux Framework
    ☞ ୈࡾষ: Isormorphicͷ࣮ફ
    ☞ ࠷ޙʹ: Virtual DOM ΛͱΓ·͘ݱ࣮

    View Slide

  12. ୈҰষ
    Kobito
    on Atom Shell

    View Slide

  13. Kobitoͱ͸
    ☞ Increments͕։ൃ
    ☞ MarkdownͰϝϞΛॻ͚ΔMacΞϓϦ
    ☞ Qiita(·ͨ͸Qiita:Team)΁ͷಉظػೳ͕͋Δ
    ☞ Objective-C

    View Slide

  14. Mac൛

    View Slide

  15. Kobito "on AtomShell"
    ☞ Kobito Λ AtomShell Ͱ࣮૷ͯ͠Windows൛ͩͦ
    ͏͍ͥͬͯ͏ϓϩδΣΫτ
    ☞ ࠓ೔͕ॳެ։

    View Slide

  16. Kobito "on AtomShell"
    ☞ ։ൃಈػ: WindowsͷKobito͕ͳ͍
    ☞ σεΫτοϓΞϓϦ
    ☞ طଘͷKobitoͷΫϩʔϯͰ͸ͳ͘ɺ͍͔ͭ͘ͷ՝
    ୊Λղܾͭͭ͠։ൃ
    ☞ View ͸ React Component + ࣗ࡞Flux Framework

    View Slide

  17. (ը໘͸։ൃதͷ΋ͷͰ͢)

    View Slide

  18. (ը໘͸։ൃதͷ΋ͷͰ͢)

    View Slide

  19. σϞ

    View Slide

  20. ௥Ճཁૉ
    ☞ Qiita / Qiita:Team ͱͷಉظػೳΛڧԽ
    ☞ ϩʔΧϧʹดͨ͡Inboxͷ௥Ճ
    ☞ ୯७ͳϝϞπʔϧͱͯ͠ͷ࢖͍উखΛڧԽ
    ☞ Vim ΩʔόΠϯυϞʔυͷ௥Ճ(։ൃऀͷझຯ)

    View Slide

  21. Kobito for Windows
    ☞ ϦϦʔε༧ఆ: 2015೥ 4݄~5݄
    ☞ => Kobito for Windows Newsletter

    View Slide

  22. ։ൃաఔ
    ☞ اը / ϓϩτ 10݄ޙ൒ ~
    ☞ ઃܭ - 11݄ ~
    ☞ ࣮૷ - 12݄~
    ☞ όάચ͍ग़͠ͱϦϑΝΫλ(͍·͜͜)
    ΤϯδχΞ1ਓ(mizchi)
    1݄͔ΒϚʔΫΞοϓ1ਓ

    View Slide

  23. ϥΠϒϥϦͷ࢖༻ײ

    View Slide

  24. ݁ہReactͱ͸ͳΜͩͬͨͷ͔

    View Slide

  25. Just the UI
    ☞ ୯ͳΔʮσʔλόΠϯυ෇͖ςϯϓϨʔτΤϯδ
    ϯʯͰɺඳըޙ࠶ར༻Մೳͳίϯϙʔωϯτ
    ☞ ඞཁे෼ʹ଎͍(͕͢͞ʹ৬ਓܳతͳDOMνϡʔχ
    ϯάʹ͸ྼΔ)
    ☞ ࠓ·Ͱۤ࿑͍ͯͨ͠ঢ়ଶભҠ͕ࢮ͵΄Ͳ୯७Խ͞
    ΕΔ

    View Slide

  26. Ծ૝DOMͱͯ͠ͷReactબఆཧ༝
    ☞ ৘ใ͕े෼ʹ͋Δ(ͨͩ͠ւ֎த৺)
    ☞ ϔουϨε؀ڥ(node)Ͱͷςετέʔεͷॻ͖΍
    ͢͞ॏࢹ
    ɹ
    ଞͷ؀ڥͳΒ΋ͬͱখ͍͞ϥΠϒϥϦΛ࢖͍ͬͯ
    ͔ͨ΋ɻQiita ʹ΋·ͩೖΕͯͳ͍ɻ

    View Slide

  27. ʮຊ࣭తͳ෦෼ʯʹूதͰ͖Δ
    ☞ ઃܭ͕୯७Խ͞Εͨ݁ՌɺΞϓϦέʔγϣϯυϝ
    Πϯ૚͕໌֬ʹҙࣝͰ͖ΔΑ͏ʹ
    ☞ Pure JavaScript, ͍ΘΏΔʮIsomorphicԽʯՄೳͳ
    Օॴʹ஫ྗͰ͖Δ(͋ͱͰৄ͘͠࿩͢)

    View Slide

  28. Qiita΁ͷϑΟʔυόοΫ(༧ఆ)
    ☞ ։ൃͨ͠ίϯϙʔωϯτ܈Λॱ࣍ϑΟʔυόοΫ
    ͍͖͍ͯͨ͠
    ☞ ͨͱ͑͹…

    View Slide

  29. Markdown ϋΠϥΠτ෇͖ͷΤσΟλ

    View Slide

  30. Atom ͷ Cmt+T తͳΠϯΫϦϝϯλϧαʔν

    View Slide

  31. AtomShellʹ͍ͭͯ

    View Slide

  32. AtomShell
    ☞ Atom Editorͷج൫
    ☞ Multi Platform (Win/Mac/Debian)
    ☞ σεΫτοϓΞϓϦͷҝͷChromium ϥούʔ

    View Slide

  33. AtomShellͰ࡞ΔϝϦοτ
    ☞ nodeͷϞδϡʔϧΛݺ΂Δ
    ☞ ΫϩεΦϦδϯΛ௒͑ΕΔ
    ☞ σεΫτοϓΞϓϦͱͯ͠഑෍Ͱ͖Δ
    ☞ ϒϥ΢βετϨʔδͷ্ݶΛ೚ҙʹ૿΍ͤΔ
    ☞ (BlinkҎ֎ͷಈ࡞֬ೝΛαϘΕΔ)

    View Slide

  34. AtomShellΛબͿ؀ڥཁҼ
    ☞ Webք۾ͩͱWindowsͷ஌ݟΛͨΊͯ΋׆༻͠ʹ
    ͘͘ɺWPFͷ஌ࣝΛ஝͑Δಈػ͕ͳ͍
    ☞ node/HTMLͷϊ΢ϋ΢Λ׆͔ͤΔ
    ☞ HTML/JSͰQiitaͱίϯϙʔωϯτΛڞ༗Ͱ͖Δ

    View Slide

  35. σεΫτοϓΞϓϦέʔγϣϯ
    ʹͳΔͱͲ͏ͳΔ͔

    View Slide

  36. ௓Ͷ্͕Δظ଴஋
    ☞ ΍Δ͜ͱ͸࣮࣭SPA ͕ͩ…
    ☞ ωΠςΟϒΞϓϦͱͯ͠ͷUXΛظ଴͞ΕΔ
    ☞ ͦͷͨΊͷ React

    View Slide

  37. ઃܭ࣌ʹ໰୊ʹͳͬͨ͜
    ͱ

    View Slide

  38. ໰୊1. JSX

    View Slide

  39. JSXͱ͸
    ☞ ReactͷԾ૝DOMʹ࠷దԽ͞ΕͨJavaScript ͷจ๏
    ֦ு
    var div = ;
    Έ͍ͨͳ΍ͭ

    View Slide

  40. JSXͷ໰୊఺. 1
    ☞ JavaScriptͷ஌ࣝΛཁٻ͗͢͠Δ
    ☞ items.map(item => data=item.data/>) ͕Ϧετཁૉ࡞ͬͯΔͷ
    Θ͔Δʁ
    ☞ ඇJSΤϯδχΞͱڠௐ͢Δʹ͸ݫ͍͠

    View Slide

  41. JSXͷ໰୊఺. 2
    ☞ ଞͷAltJSͱ૬ੑ͕Α͘ͳ͍
    ☞ ࠓճ͸CoffeeScriptͱTypeScriptΛ࢖͍ͬͯΔͷͰ
    ࠷ѱ

    View Slide

  42. JSXͷ໰୊఺. 3
    ☞ ςϯϓϨʔτͱີ݁߹͗͢͠Δ
    ☞ ViewModel Λڧ͘ҙࣝͯ͠ςϯϓϨʔτͱϓϩύ
    ςΟΛ෼཭ΛࢼΈͨ

    View Slide

  43. ղܾࡦ: react-jade
    jadejs/react-jade
    ☞ jadeςϯϓϨʔτ͔ΒReactͷVirtual DOM ͕ు͚
    Δ
    ☞ jadeͷ։ൃݩ͕ఏڙ͍ͯ͠ΔͷͰɺϝϯς͞ΕΔ
    ͩΖ͏ͱ͍͏ظ଴͕͋Δ

    View Slide

  44. react-jade ͷྫ
    .container
    h1(onClick=onClickTitle)= This is title

    React.createElement('div', {className: 'container'}, [
    React.createElement('h1', {onClick: onClickTitle}, 'This is title')
    ])
    // ϔομলུ
    ͍ΘΏΔhamlܥςϯϓϨʔτ

    View Slide

  45. react-jade ͷ݁Ռ
    ☞ JSৄ͘͠ͳ͍ਓʮͳΜ͔Α͘Θ͔ΒΜϓϩύςΟ
    ͕͋Δ͕৮ΕΔʯఔ౓ʹམͪண͘
    ☞ (Qiitaຊମ͸slim ͍ͬͯ͏എܠ͕͋Δ͔΋)

    View Slide

  46. ։ൃݴޠ
    ☞ UI૚: React Component / Dispatcher
    ☞ CoffeeScriptͰߴ଎ʹTry & Error Λճ͢
    ☞ ςϯϓϨʔτ͸react-jade
    ☞ Store૚ / Domain૚
    ☞ TypeScript ͷ common.jsϞʔυ
    ☞ CoffeeScript ʹ require ͞ΕΔ(ٯ͸ͳ͍)

    View Slide

  47. ໰୊2.
    ͲͷઃܭΛ࠾༻͢Δ?

    View Slide

  48. Flux
    ☞ ୯ํ޲σʔλϑϩʔ
    ☞ ঢ়ଶ؅ཧίετ͕௿͍VirtualDOMʹ޲͍ͨઃܭΛ
    ࣮ݱ͢Δࢥ૝. (࣮૷Ͱ͸ͳ͍)
    ☞ ৄ͘͠͸୭͔͕࿩ͯ͘͠Ε(Δ/ͨ)Ͱ͠ΐ͏ or ͙͙
    Ε

    View Slide

  49. ཚཱ͢Δ Flux ࣮૷
    ☞ Fluxxor
    ☞ Reflux
    ☞ Alt
    ☞ Fluxible
    ☞ Facebook's flux
    ☞ Deloerean
    ☞ etc...

    View Slide

  50. Flux࣮૷ͷݱ࣮
    ☞ ബ͍
    ☞ Ͳͷ࣮૷΋Idiomatic
    ☞ ͲΕ͕ੜ͖࢒Δ͔Θ͔ΒΜ

    View Slide

  51. ͳΜ͔ͬ͘͠Γ͢Δͷ͕ͳ͍

    View Slide

  52. ʮ΋͏ࣗ࡞͢Δ͔͠ͳ͍ʂʯ

    View Slide

  53. ͱ͍͏Θ͚Ͱ…

    View Slide

  54. ୈೋষ:
    Arda - MetaFlux

    View Slide

  55. Arda
    ☞ mizchi/arda - Github
    ☞ ݩʑ͸ Kobito on Atom Shell ͷঢ়ଶ؅ཧͱը໘ભ
    ҠΛந৅Խͨ͠΋ͷ
    ☞ ͦͦ͜͜ςετॻ͍ͯɺ͍ͩͿυοάϑʔσΟϯ
    ά͍ͯ͠ΔͷͰ࣮༻ʹ଱͑͏Δ͸ͣ

    View Slide

  56. Ardaͷ༝དྷ
    ☞ JɾRɾRɾτʔϧΩϯͷʮࢦྠ෺ޠʯͷੈքͷ໊
    લͰ͋Γ஍ٿͦͷ΋ͷͰ΋͋Δ
    ☞ VirtualDOMͷԾ૝ͳੈքͱݱ࣮͕༥߹͢Δ৔ॴ͙
    Β͍ͷχϡΞϯε
    ☞ ͿͬͪΌ͚୹͚ΓΌͳΜͰ΋Α͔ͬͨ

    View Slide

  57. ։ൃͷಈػ
    ☞ طଘͷFlux࣮૷͸ʮը໘ભҠʯ͕දݱ͠ʹ͔ͬ͘
    ͨ
    ☞ react-router͕࢖͍ʹ͔ͬͨ͘/໨త͕ҧͬͨ
    ☞ Store૚ΛTypeScriptϑϨϯυϦʔʹܕͰอޢͰ͖
    ΔΑ͏ʹ෼཭͔ͨͬͨ͠

    View Slide

  58. ҙࣝͨ͠΋ͷ
    ☞ Store/View/DispatcherͷմΛʮContextʯͱ͍͏୯
    ҐͰ؅ཧ
    ☞ ContextͷελοΫͰঢ়ଶΛදݱ
    ☞ React ͷState/Props ͷ֓೦͸ܧঝ
    ☞ ͢΂ͯͷঢ়ଶભҠΛPromiseԽ

    View Slide

  59. Ґஔ͚ͮ
    ☞ ୯ͳΔFluxͰ͸ͳ͘FluxΛ಺แͨ͠ΑΓ্Ґͷ
    Framework

    View Slide

  60. View Slide

  61. ϞδϡʔϧΛ୯७ʹ
    ☞ View͸୯ͳΔReact.Component
    ☞ Dispatcher͸୯ͳΔEventEmitter
    ☞ Store͸EventΛड͚ͯঢ়ଶΛߋ৽

    View Slide

  62. Context ͷσʔλϑϩʔ
    ➀ Router ͔Βॳظೖྗ(Props)Λड͚ͯॳظԽ͞ΕΔ
    ➁ Props͔ΒॳظState(Context಺ঢ়ଶ)Λ࡞Δ
    ➂ Props ͱ State ͔ΒɺComponentʹ౉͢ϓϩύς
    Ο(ComponentProps)Λੜ੒
    ➃ Component ʹ౉͢
    ➄ ঢ়ଶ͕ߋ৽͞ΕͨΒ3ʹ໭Δ

    View Slide

  63. View Slide

  64. Arda.Router
    ☞ pushContext
    ☞ popContext
    ☞ replaceContext
    ☞ APIͰ࡯ͯ͠
    ☞ Contextͷੜ੒ͱഁغΛ୲౰(SPA͸ͦ͜Β΁Μݫ͠
    ͍)

    View Slide

  65. ΫϦοΫͰ਺͕૿͑Δαϯϓϧ
    class Clicker extends Arda.Component
    render: -> React.createElement 'button', {onClick: @onClick.bind(@)}, @props.cnt
    onClick: -> @dispatch 'clicker:++'
    class ClickerContext extends Arda.Context
    @component: Clicker
    initState: (props) -> cnt: 0
    expandComponentProps: (props, state) -> cnt: state.cnt
    delegate: (subscribe) ->
    super
    subscribe 'clicker:++', =>
    @update((s) => cnt: s.cnt+1)
    router = new Arda.Router(Arda.DefaultLayout, document.body)
    router.pushContext(ClickerContext, {})

    View Slide

  66. ΫϦοΫͰ਺͕૿͑Δαϯϓϧ
    class Clicker extends Arda.Component
    render: -> React.createElement 'button', {onClick: @onClick.bind(@)}, @props.cnt
    onClick: -> @dispatch 'clicker:++' #<= EventEmitter΁ൃՐ
    class ClickerContext extends Arda.Context
    @component: Clicker
    initState: (props) -> cnt: 0
    expandComponentProps: (props, state) -> cnt: state.cnt
    delegate: (subscribe) ->
    super
    subscribe 'clicker:++', => #<= EventEmitterͷEventड৴
    @update((s) => cnt: s.cnt+1)
    router = new Arda.Router(Arda.DefaultLayout, document.body)
    router.pushContext(ClickerContext, {})
    Event ͸Ұํ௨ߦ

    View Slide

  67. ΫϦοΫͰ਺͕૿͑Δαϯϓϧ
    class Clicker extends Arda.Component
    render: -> React.createElement 'button', {onClick: @onClick.bind(@)}, @props.cnt
    onClick: -> @dispatch 'clicker:++'
    class ClickerContext extends Arda.Context
    @component: Clicker
    initState: (props) -> cnt: 0 #<= ॳظঢ়ଶ
    expandComponentProps: (props, state) -> cnt: state.cnt #<= ComponentͷProps
    delegate: (subscribe) ->
    super
    subscribe 'clicker:++', =>
    @update((s) => cnt: s.cnt+1) #<= ঢ়ଶͷߋ৽
    router = new Arda.Router(Arda.DefaultLayout, document.body)
    router.pushContext(ClickerContext, {})
    Mutable ͳͷ͸ State ͚ͩ

    View Slide

  68. Context Λ TypeScript Ͱهड़͢Δ
    ͱԿ͕خ͍͠ʁ
    ☞ ܕʹΑͬͯ࢓༷͕໌֬ʹͳΔ
    ☞ Props ͸ը໘Λ࠶ߏங͢Δͷʹඞཁͳ৘ใ
    ☞ State ͸ͦͷը໘ͷதͰมԽ͢Δঢ়ଶ
    ☞ ComponentProps ͸ ࣮ࡍʹComponent ʹ౉͞Ε
    Δ΋ͷ

    View Slide

  69. ComponentProps ͕ଘࡏ͢Δҙਤ
    ☞ ؔ৺ͷ෼཭
    ☞ Component͕஌Δ΂͖ঢ়ଶ͚ͩʹมܗ͍ͨ͠
    ☞ ܕͰอޢ͠ʹ͍͘Component ʹ௚઀ Props ͱ
    State Λ౉͢ͷ͸خ͘͠ͳ͍

    View Slide

  70. ͨͱ͑͹
    ☞ Stateͱͯ͠Կ͔ͷ id ͚ͩ࣋ͬͯ DB΍ωοτϫʔ
    ΫΛୟ͘ͱɺ݁Ռʹ࠶ݱੑ͕ͳ͘ State ͱͯ࣋͠
    ͪͨ͘ͳ͍
    buildTimelineByGroupId(state.selectedGroupId).then((items) = {
    this.render(items); // ͜͜Λ࣋ͪͨ͘ͳ͍
    });

    View Slide

  71. ࠶ݱՄೳͳϏϡʔ
    ☞ ComponentProps͕ಉ͡ͳΒඞͣಉ͡ϏϡʔΛঢ়
    ଶΛ࠶ݱͰ͖Δ(ͱ͢Δ)
    ☞ Component ͱ Props ͷ૊Έ߹Θͤͷ URL΁ͷγ
    ϦΞϥΠζ/σγϦΞϥΠζ Λ࣮૷͢Ε͹ Browser
    Hisotry ʹରԠՄೳ
    ☞ Agnosticʹ͍ͨ͠ͷͰArdaͰ͸ϒϥ΢βώετϦ
    ʔΛؔ஌͠ͳ͍

    View Slide

  72. ଞɺৄ͍͠API
    ☞ arda.d.ts ͷܕఆٛϑΝΠϧ͕APIυΩϡϝϯτΛ
    ݉ͶͯΔ
    ☞ Ardaࣗ਎͸coffeescriptͰهड़
    ☞ ࠷ॳ͸typescriptͰॻ͍͕ͨɺϝλϓϩͩΒ͚Ͱܕ
    ͕ੜ͖ͣɺ୅ΘΓʹςετΛଟΊʹॻ͍ͨ

    View Slide

  73. Kobito on Atom Shell Ͱͷ Arda
    ☞ Context Λ TypeScript ͰܕͰอޢ͢Δɻ
    ☞ Component ͸ CoffeeScript Ͱࡶʹॻ͍ͯ Event Λ
    dispatch ͢Δ
    ☞ Eventͷߪಡଆ͸TypeScript Ͱॻ͍͍ͯΔ͕ɺड
    ͚औΔҾ਺ʹ͍ͭͯ͸͓໿ଋఔ౓

    View Slide

  74. Arda with TypeScript
    interface Props {firstName: string; lastName: string;}
    interface State {age: number;}
    interface ComponentProps {greeting: string;}
    class MyContext extends Arda.Context {
    initState(props){
    return new Promise(done => {
    setTimeout(done({age:10}), 1000)
    })
    }
    expandComponentProps(props, state) {
    return {greeting: 'Hello, '+props.firstName+', '+state.age+' years old'}
    }
    }
    # தུ
    router.pushContext(MyContext, {firstName: 'Jonh', lastName: 'Doe'})

    View Slide

  75. Arda ͷॻ͖৺஍
    ☞ طଘͷFluxͷऑ͍఺ΛΧόʔͰ͖ͨͱࢥ͏
    ☞ ࣗ෼ʹͱͬͯ͸࠷ߴͳΜͰྲྀߦΒ͍ͤͨ
    ☞ API΋֮͑Δ͜ͱ΋গͳ͍ͷͰ࢖ͬͯ͘Ε!

    View Slide

  76. ͍·͙͢ npm install arda --save

    View Slide

  77. ୈࡾষ:
    Isomorphicͷ࣮ફ

    View Slide

  78. Isomorphicͱ͸
    ☞ ʮಉ͡ϥΠϒϥϦ͕nodeͰ΋ϒϥ΢βͰ΋ಈ͚͹
    ͍͍ΑͶʯͱ͍͏ൃ૝
    ☞ browserify/webpackʹΑ࣮ͬͯݱՄೳʹͳͬͨ

    View Slide

  79. ͳͥIsomorphicΛҙࣝͯ͠։ൃ͢
    Δ͔
    ➀ ͨͱ͑node(iojs)͸࢖Θͳͯ͘΋ɺ୯ମςετ͸
    nodeͰ΍Δͷ͕؆୯Ͱߴ଎
    ➁ ϑϩϯτΤϯυͷ֤छϓϦίϯύΠϥ΍λεΫϥ
    ϯφʔ΋node
    ➂ ىಈίετ͕ߴ͘ෆ҆ఆͳϔουϨεϒϥ΢β
    (phantomjs)ͷ࢖༻Λۃྗආ͚͍ͨ
    ɹ

    View Slide

  80. Qiita ͱ Atom Shell ಛ༗ͷࣄ৘
    ☞ node ͷ global ͱ ϒϥ΢βͷ window ͕ڞଘ͢Δ
    ಛघͳ؀ڥ
    ☞ ੒Ռ෺͸͍ͣΕQiita΁࣋ͪࠐΈ͍ͨ
    ͱ͍͏Θ͚ͰKobito on Atom Shell Ͱ͸ Isomorphic
    Λڧ͘ҙࣝͯ͠ઃܭͨ͠

    View Slide

  81. Isomorphic ͷҝͷந৅Խ
    ☞ ετϨʔδ
    ☞ DOM

    View Slide

  82. ετϨʔδͷ
    IsomorphicԽ

    View Slide

  83. minimongo
    mWater/minimongo
    ☞ mongodb෩ͷAPIΛ࣋ͬͨӬଓετϨʔδ
    ☞ อଘઌΛ੾Γସ࣮͑ͯߦ؀ڥΛબ΂Δ(IndexedDB/
    ΦϯϝϞϦ/MongoDb)
    ☞ ࠾༻ཧ༝: ݩʑ meteor ͷҰ෦ͰΑ͘ςετ͞Εͯ
    ͍Δ

    View Slide

  84. ଞͷީิ
    ☞ PouchDB, the JavaScript Database that Syncs!
    ☞ Lightweight javascript in-memory database:
    LokiJS

    View Slide

  85. Isomorphic తӡ༻
    ☞ ςετ؀ڥԼͰ͸ΦϯϝϞϦϞʔυʹͯ͠ىಈ
    ͠ɺςετέʔε͝ͱʹੜ੒/ഁغ

    View Slide

  86. ଞɺࣗ࡞ϥΠϒϥϦ܈
    ☞ mizchi/minimongo-schema εΩʔϚఆٛͷJSON
    ͔ΒDBॳظԽ
    ☞ mizchi/factory-dog ↑༻ͷεΩʔϚ͔ΒμϛʔΦϒ
    δΣΫτͷੜ੒(ࡶͳfactory-girl࣮૷)
    ☞ mizchi/mz-repository ϦϙδτϦύλʔϯ࣮૷
    ☞ mizchi/noo ES6ProxyΛ༻͍ͨ rspec ͷ null object
    ͬΆ͍΍ͭͷ࣮૷

    View Slide

  87. mochaͰͷ࣮ࡍͷίʔυͷҰ෦
    schema.databases[0].type = 'memoryDb'
    global.stubDatabases = -> # helper
    beforeEach ->
    initDatabasesBySchema(schema).then ([db]) ->
    global.db = new Repository.Database(db)
    global.Item = db.getCollection('items')
    global.Team = db.getCollection('teams')
    afterEach ->
    delete global.db
    delete global.Item
    delete global.Team

    View Slide

  88. React ͷ
    IsomorphicԽ

    View Slide

  89. Headless React
    ☞ ϒϥ΢β؀ڥ͕ͳͯ͘΋ಈ͘(Server Side
    Rendering ͷҝ)
    ☞ jsdom Ͱ΋݁ߏಈ͘

    View Slide

  90. renderToString(...)
    var Component = React.createClass({
    render: function(){return React.createElement('div', {}, 'this is title');}
    });
    var html = React.renderToString(React.createFactory(Component)());
    assert.ok(html.indexOf('this is title') > -1);
    componentWillMount ·Ͱݺ͹ΕΔͷ͕ϙΠϯτ
    (componentDidMount͸ݺ͹Εͳ͍)

    View Slide

  91. JSDOM
    jsdom = require('jsdom').jsdom;
    global.document = jsdom('');
    global.window = document.parentWindow;
    global.navigator = window.navigator;
    React = require('react/addons');
    var el = React.createElement('div');
    component = React.addons.TestUtils.renderIntoDocument(el)
    αʔόʔ(node)ͰΫϦοΫΠϕϯτൃՐ΋ςετͰ͖
    Δɻ
    ࢀߟ: JSDOMͱReact.addons.TestUtilsͰReactΛϔου
    Ϩεʹςετ͢Δ - Qiita

    View Slide

  92. IsomorphicʹΑΔ
    ࣮ߦϞʔυ੾Γସ͑ͷ࣮ݱ

    View Slide

  93. Kobitoͷ Isomorphic ͷ࣮ફ
    ☞ src/(.ts, .jade, .coffee) Λ૬ରύεΛҡ࣋ͨ͠··ί
    ϯύΠϧ͠ lib/(**.js)΁
    ☞ browserifyͰ lib/index.js Λ શ෦ೖΓ
    (node_modulesҎԼͷґଘؚΉ)ͷ bundle.js ͱ͠
    ͯϏϧυ
    (gulpͰ֦ுࢠ͝ͱʹ؂ࢹͯࠩ͠෼Ϗϧυ)

    View Slide

  94. src/
    - main.coffee
    - foo.ts
    - template.jade
    lib/
    - main.js
    - foo.js
    - template.js
    public/
    - bundle.js # lib node_modules ͷґଘશ෦ೖΓ
    - index.html
    node_modules/
    - ...
    test/
    - main-test.coffee

    View Slide

  95. Isomorphic ͕Մೳʹͨ͜͠ͱ
    ☞ ༻్ʹԠ࣮ͨ͡ߦํࣜͷ੾Γସ͑
    ☞ ϞδϡϥϦςΟͷ޲্

    View Slide

  96. ࣮ߦϞʔυ1: AtomShell:production
    ☞ ഑෍༻ʹϏϧυࡁΈͷbundle.jsΛ࢖ͬͯαΠζ࡟
    ݮ(85MB → 1.8MB)
    ɹ
    ݩαΠζ͕େ͖͍ཧ༝͸ɺnode_modules/* ͷґଘ͕
    શ෦ೖ͍ͬͯΔ͍ͤɻ

    View Slide

  97. ࣮ߦϞʔυ2:
    AtomShell:development
    ☞ AtomShell಺ଂͷnodeΛ࢖ͬͯɺlib/index͔Β૬
    ରύεͰղܾɻ
    ☞ ΍΍ֻ͕͔࣌ؒΔbrowserifyΛεΩοϓͰ͖Δ

    View Slide

  98. ࣮ߦϞʔυ3: ϒϥ΢β࣮ߦ
    ☞ ϒϥ΢βͰbundle.jsΛಡΈࠐΉindex.html ͔Βී
    ௨ʹىಈ͢Δ͚ͩ
    ☞ ΫϩεΦϦδϯ੍໿ʹͻ͔͔ͬΒͳ͍΋ͷɺωΠ
    ςΟϒΛݺͿػೳҎ֎͸࣮ߦՄೳ
    ☞ Կ͔ʹ࢖͑ͳ͍͔ߟ͍͑ͯΔ…(ମݧ൛ͱ͔ʁ)

    View Slide

  99. ࣮ߦϞʔυ4: ୯ମςετ
    ☞ lib ҎԼͷϑΝΠϧΛ test/**/* ͔Β૬ରύεͰ
    require࣮ͯ͠ߦ
    ☞ ϔουϨεͳͷͰͱʹ͔͘଎͍҆͠ఆ͢Δ

    View Slide

  100. ࣮ߦϞʔυ5: End to End Test
    ☞ ϒϥ΢βϏϧυͱಉ͡Α͏ʹߏங
    ☞ AtomShell༻ͷSeleniumΞμϓλʔͷઃఆΛαϘ
    Δ͜ͱ͕Ͱ͖ͨ

    View Slide

  101. ͓·͚: browsrify vs webpack
    webpack͸͍ΖΜͳ͜ͱ͕ग़དྷա͗ͯɺnode ʹͳ͍
    ڍಈ͕ՄೳͳͷͰ Isomorphic ੑΛकΔͨΊʹ͋͑ͯ
    browserifyΛ࢖͍ͬͯΔɻ

    View Slide

  102. ୈ࢛ষ
    Virtual DOM ΛͱΓ·͘ݱ࣮

    View Slide

  103. ࣮ࡍReactͲ͏ͳΜ
    ☞ ը໘ʹมԽΛى͜͢/ى͜͠ଓ͚Δͷ͕ѹ౗తʹָ
    ☞ ͱ͸͍͑पลϥΠϒϥϦ͕ރΕͯͳ͍
    ☞ IssueͰόάใࠂ͠·ͬͨ͘Γࣗ෼Ͱforkͯ͠ύο
    ν͋ͯͨΓͯ͠Δ

    View Slide

  104. Reactͷݒ೦఺
    ☞ αΠζ͕΍΍େ͖͍(.min.js Ͱ127k)(jQueryͱಉ͡
    ͙Β͍)
    ☞ ΑΓখ͞ͳ࣮૷ virtual-dom/deku/mithril/
    riot ΋ߟྀʹ͍ΕΔ΂͖͔΋ʁ
    ☞ ͱ͸͍͑Ұ൪ރΕͯΔ

    View Slide

  105. ʮͲ͏͍͏ઃܭ͕͍͍͔Θ͔ΒΜʯ
    ☞ Ardaͷେن໛޲͚ϓϩδΣΫτεέϧτϯஔ͍ͱ
    ͘ΜͰͲ͏ͧ
    ☞ mizchi-sandbox/arda-starter-project
    ☞ ࣮ࡍͷ Kobito on AtomShell ͱ΄΅ಉ༷

    View Slide

  106. React vs jQuery
    ☞ ࢥ૝ͷஈ֊ͰίϯϑϦΫτ͍ͯ͠ΔͷͰڠௐ͕೉
    ͍͠
    ☞ طଘࢿ࢈ͷҎ͔߱ΒͷɺҰ൪ͷϘτϧωοΫͰ͋
    Δ͜ͱ͸൱Ίͳ͍
    ☞ ࢖͑ͳ͍Θ͚Ͱ͸ͳ͘ ϦʔυΦϯϦʔ ͩͱߟ͑Δ
    ͱࣗવ

    View Slide

  107. ͦ΋ͦ΋jQueryඞཁ?
    ☞ ͦͷ50ߦͷεύήςΟίʔυɺReactͩͬͨΒ10ߦ
    ͷComponentʹͳΒͳ͍ʁ
    ☞ ͦ͏͍͏ࢹ఺Λৗʹ࣋ͭ
    ☞ खΛಈ͔ͦ͏ʂ

    View Slide

  108. ʮͳʹ͕ͳΜͰ΋jQuery
    ϓϥάΠϯࣺͯΒΕͳ͍
    Μ͡Όʙʯ
    ☞ ͰϢχʔΫͳkey
    ଐੑΛ࣋ͭԾ૝DOMͳΒফ͑ͳ͍
    ☞ ίϯςφͷதΛjQueryͷྖҬͱ͢Δ

    View Slide

  109. Kobito on AtomShell ͰjQuery Λ࢖
    ͬͨՕॴ
    ☞ εΫϩʔϧྔͷಡΈग़͠ͱߋ৽
    ☞ ٖࣅΫϦοΫΠϕϯτͷൃՐ
    ☞ aλάΛશͯΦʔόʔϥΠυͯ͠AtomShellͷ֎ʹ
    ग़ͯ͠·Θͳ͍Α͏ʹ

    View Slide

  110. ݱ୅తͳJavaScriptΤϯδ
    χΞʹٻΊΒΕΔ΋ͷ

    View Slide

  111. Isomorphicͷൃ૝ͱnodeͷεΩϧ
    ☞ ΑΓαʔόʔαΠυݴޠͷൃ૝ʹۙ͘ͳΔ
    ☞ σβΠφʔʹͱͬͯͷֶशίετ͸্͕ΓɺΤ
    ϯδχΞʹͱͬͯ͸Լ͕Δ
    ☞ ద੾ͳ෼ۀମ੍͕ඞཁ
    ☞ ΍Δ΂͖͜ͱ͸αʔόʔαΠυnodeΤϯδχΞͱ
    શ͘ಉ͡(࣮ߦ؀ڥ͕ҟͳΔ)

    View Slide

  112. େن໛SPAͷઃܭ
    ☞ ը໘ͷߏஙʹඞཁͳൃ૝͸ɺωΠςΟϒͷΞϓϦ
    έʔγϣϯΤϯδχΞͱಉ͡
    ☞ ࣗ෼͸ήʔϜ։ൃͱAndroidͷܦݧ͕ੜ͖ͨ
    ☞ ετϨʔδΛѻ͏ͱσʔλ؅ཧ͕γϏΞʹ
    ☞ υϝΠϯۦಈΛҙࣝ͢Δ
    ☞ RP/FRP

    View Slide

  113. ʮ࠷ۙͷJS͸֮͑Δ͜ͱ͕ଟ͗͢
    ͯΘ͔ΒΜʯ
    ☞ ΋ͬͱ΋Α͘ฉ͘
    ☞ ಉ͡ײ૝͕ͩͦ΋ͦ΋ཁٻ͕ෳࡶԽ͍ͯ͠Δͷ
    Ͱ…
    ☞ ͱ͸͍͑VirtualDOM ͸ઃܭͷ୯७Խํ޲ʹಇ͘
    ͷͰݱ࣮తʹ࠾༻Մೳ

    View Slide

  114. ࠓ೔ͷ·ͱΊ

    View Slide

  115. ☞ ݱ৔Ͱ࢖ͬͯΈ͚ͨͲେৎ෉
    ☞ React͸ઃܭͷ୯७Խʹํ޲ʹಇ͘
    ☞ ϑϩϯτΤϯυ͸IsomorphicԽ͞Ε, node(iojs)ͷ
    εΩϧʹΑͬͯޮ཰Խ͞ΕΔ
    ☞ Arda ʹΑͬͯը໘ભҠΛ؅ཧ͠ɺܕʹΑΔʮߗ
    ͞ʯΛௐઅͰ͖ΔΑ͏ʹͨ͠

    View Slide

  116. Kobito for Windows ΑΖ͓͘͠ئ
    ͍͠·͢ʂ
    ☞ 4݄தʹग़͍ͨ͠
    ☞ => Kobito for Windows Newsletter

    View Slide

  117. Increments Ͱ͸ σβΠφ͕଍Γͳ
    ͍
    ☞ σβΠφͷख͕଍Γͳͯ͘ਏ͍
    ☞ Qiita/Kobito ͷσβΠϯ͍ͨ͠ਓ͖ͯ͘Εʂʂʂ
    Qiita΍Qiita:Teamͷ੒௕ΛՃ଎ͯ͘͠ΕΔσβΠφ
    ʔืूʂ - Increments(Qiita)ͷٻਓ - Wantedly

    View Slide

  118. ׬

    View Slide