Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Έͳ͞Μ

Slide 6

Slide 6 text

ࠢ਒͑ͯ·͢ʁ

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

ୈҰষ Kobito on Atom Shell

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Mac൛

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

σϞ

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

ϥΠϒϥϦͷ࢖༻ײ

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

AtomShellʹ͍ͭͯ

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

໰୊1. JSX

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

ͱ͍͏Θ͚Ͱ…

Slide 54

Slide 54 text

ୈೋষ: Arda - MetaFlux

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

ΫϦοΫͰ਺͕૿͑Δαϯϓϧ 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, {})

Slide 66

Slide 66 text

ΫϦοΫͰ਺͕૿͑Δαϯϓϧ 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 ͸Ұํ௨ߦ

Slide 67

Slide 67 text

ΫϦοΫͰ਺͕૿͑Δαϯϓϧ 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 ͚ͩ

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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'})

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

͍·͙͢ npm install arda --save

Slide 77

Slide 77 text

ୈࡾষ: Isomorphicͷ࣮ફ

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

ετϨʔδͷ IsomorphicԽ

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

React ͷ IsomorphicԽ

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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͸ݺ͹Εͳ͍)

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

ࠓ೔ͷ·ͱΊ

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

׬