Roppongi.rb #3 Rails x Frontend-Tech
Universal JavaScript - ࠓޙ10Λੜ͖ൈͨ͘Ίʹ@mizchiRoppongi.rb #3 Rails x Frontend-Tech
View Slide
About Me• ϑϩϯτΤϯυ/SPA/Node.js ΤϯδχΞ• ήʔϜܥ => ڭҭܥ => Increments(Qiita)• 4݄͔ΒϑϦʔϥϯεͰ Redux Express middleware• ࠷ۙͷڵຯ: ReactNative / AMP / ےτϨ
Podcast ͡Ί·ͨ͠https://genba.fm/• #1 Awesome Vue• #0 React vs Angular - ͋Δ͍ FunctionalJavaScript
͓ॻ͖• Sprockets ͷࡴ͠ํ• ͓લͷ Webpack ࢮ͵• ͜ͷઌ10ੜ͖ΔͨΊʹ
!!!!CAUTION!!!!!!!!!!!!!!!!ຊࢿྉͷະདྷ༧ଌࣗͷצͰ͋ΓΛऔΕΔͷͰ͋Γ·ͤΜ!!!!!!!!!!!!
ୈҰ෦: Sprockets ͷࡴ͠ํ
ࠓͷจ຺toshimaru_eʮQiitaͷSprockesΛࡴͨ࣌͠ͷΛ͓ئ͍Ͱ͖·͔͢ʯmizchiʮ͍ʯ
SprocketsΛࡴͨ͠هࣄ• Qiita - app/assets/javascriptsҎԼͷJSΛશͯcommonjsͷrequireʹॻ͖͑Δ• Qiita - decafͰcoffeeͷίʔυΛES.next ʹॻ͖͑Δҙ: 2͙Β͍લ
લఏ: ͳͥ Sprockets ࢮ͵͖͔• Ϟδϡʔϧղܾʹ ES Modules ͱ͍͏ඪ४ ͕͋Δ• JSͰϑΝΠϧείʔϓΛ࣋ͯͣ ࢀর͕άϩʔόϧ͠ ʹͳΔ• ධՁॱͷ੍ޚ͕͍͠• RailsଆʹӅṭ͞Εͯͯ node πʔϧνΣΠϯΛ͍ʹ͍͘• ͍ (ExecJS)
(2015࣌ͷ) Sprockets ͷࡴ͠ํ• browserify-rails ͷಋೖ, ޙʹ webpack• εΫϦϓτॻ͍ͯ sprockets/require Λ commonjs ʹ• άϩʔόϧมͷࢀরΛ module.exports = ... ʹೖ• ࢀরղܾΛάϩʔόϧม͔Β require('...') ʹ
before// definewindow.App.View.render = function () {/* render */}// useApp.View.render()
after: commonjs// define on render.jsmodule.exports = () => {/* render */}// useconst render = require('./render')render()
࣌ͷ੍• ES Modules Ͱͳ͘ commonjs ͳͷɺ coffee ͕΄ͱΜͲͩͬͨͨΊ• ࠓͳΒ ES Modules
େࣄͳ͜ͱ: ߟ͑ํͷస• ׂ୯ҐΛ ࣮ߦίʔυ ͔Β ؔϞδϡʔϧ • Ϟδϡʔϧఆٛͱͦͷ࣮ߦΛڧ۠͘ผ͢Δ• େࣄͳͷɺ ࣮ߦ࣌ͷ෭࡞༻ͷநग़ ͱɺ༧ଌ͢͠͞
ʮ࣮ߦίʔυʯ͔ΒʮؔϞδϡʔϧʯ// Baddocument.title = 'foo'// Good// setTitle.jsexport default function setTitle(title) {document.title = title}// runner.jssetTitle('foo')
͍͍͍ͨ͜ͱ• ଞͷݴޠ/ڥͰʮධՁɺଈɺ࣮ߦɺ෭࡞༻์Γ͛ʯΈ͍ͨͳίʔυ͋·Γॻ͔ͳ͍ͣ• ͨΓલͷ͜ͱΛͨΓલʹ Γ·͠ΐ͏
ୈೋ෦: ͓લͷ Webpack ࢮ͵
Webpack ͷׂ• ES Modules ͷόϯυϧ• ֦ுࢠ͝ͱͷ transform• ։ൃ࣌ͷ Hot Reload• ࢀরղܾͷ Alias• etc...
ҙࣝ: ػೳ͕͋Γׂ͗ͯ͢Ε૭• JSόϯυϥͷൣᙝΛӽ͍͑ͯͯ node.js Ͱ࠶ݱͰ͖ͳ͍• ઃఆϑΝΠϧ͕Ͱ͔͍ & Α͘Θ͔ΒΜ• css-modules ಋೖ͕ࠇຐज़Ͱਏ͍• ίϐϖͰಈ͍ͨޙɺಈ͔ͳ͘ͳͬͨͱ͖ͷௐ͕ࠪେม
Universal JavaScript• Universal: ECMAScript ͷ Spec ΛຬͨͤɺͲΜͳڥͰಈ͘JS• Isomorphic : ڱٛͷUniversalɻBrowser/Node͕ରɻ=> Webpack Universal ੑΛഁյ͢Δ(͍͢͠)͔ΒϞδϡϥϦςΟ͕Լ͢ΔΑͱ͍͏
Babel Universal ͔ʁ• DOM Λ৮Βͣɺbabel-preset-es201* ΛͬͯΔ͏ͪYes• ͨͩ͠ ES Modules ͷύεղܾ commonjs + α• lib/index ͱ͔ node_modules ͱ͔• stage0~3, jsx, flow ඪ४֎
Native ES Modules ͷԻ
Native ES Modules• Safari 10.1• Chrome M60(Canary) ϑϥάͰ• Edge ϑϥάͰ
ES Moduls in Browser<br/>import {addTextToBody} from './utils.js';<br/>addTextToBody('Modules are pretty cool.');<br/>https://jakearchibald.com/2017/es-modules-in-browsers/
ES Modules ͕͋ͬͨΒ͑Δ͔ʁ• ༷తʹYES• ͨͩ͠HTTP/2Ͱͳ͍ͱύϑΥʔϚϯε͕େ෯ʹྼԽ͢ΔՄೳੑ• ES ModulesHTTP/2Ͱ෦ߋ৽ͷເΛݟΔ͔ʁ• Cache aware server push - kazuho
ES Modules: ࠓޙͷ༧• དྷʹ࣮͕ग़ἧ͏• ࠷ॳ Fastly ͷΑ͏ͳ CDN Ͱղܾ͞ΕΔͷͰ• কདྷతʹ nginx/h2o ͷϞδϡʔϧԽ͞Εͯ͑ΔΑ͏ʹͳͬͯΔͣ• ES Modules ͷ੩తղੳεςοϓඞཁϓϩμΫγϣϯͰ͑Δͷɺ͓ͦΒ͘ 2~3ޙ
Webpack ͷͱࢮ͵ཧ༝: ·ͱΊ• ศརͳׂΕ૭• Universal ੑΛഁյ͠ίʔυͷϞδϡϥϦςΟ͕Լ• ωΠςΟϒͷ ES Modules Ͱ૬ରతʹॏཁੑ͕ԼδϯΫεతʹɺDHH͕બΜͩϑϩϯτͷπʔϧࢮ͵
ଈࢮ͠ͳ͍ Webpack ͷ͍ํ• ES Modules ͷܨ͗ͱׂΓͬͯ͏• ಠࣗͳtransformΛՄೳͳݶΓ babelଆಀ͕͢• css-modules => styled-jsx• resolve.alias => babel-plugin-module-resolver
ୈࡾ෦: ͜ͷઌ10ੜ͖ΔͨΊ
JavaScriptքϢʔβʔ: ΊͬͪΌଟ͍ϢʔβʔͷόοΫΤϯυ: ଟ༷JSͷฏۉ࿅: ͍ (ยखؒ)
ίϯηϯαεͱΔͷϚδͰແཧ
Easy > Simple Ͱ࠷ѱ
ϥΠϒϥϦઃܭऀͷؾ࣋ͪ• Easy ͰϢʔβʔΛὃͯ͠ɺSimple • npmքͰɺྲྀߦͬͨػೳ୯ػೳʹϒϨʔΫμϯ͞ΕΔ
Webpacker ͷ scaffold ͕Ϡόͦ͏• ίϯηϯαεऔΕͳ͍ڥͰ, ୭͕ೲಘͰ͖ΔϘΠϥʔϓϨʔτΛߏங͢Δͷແཧ• ԼճΓΛࢧ͑ΔͷʹΑͦ͞͏͕ͩɺׂΕ૭…
ຊ࣭͚ͩݟ͍͍ͯͨ…• Agnostic ʹ Universal ͰϏδωεϩδοΫΛॻ͘• Domain => UI State => View => Event Handler ...
ϑϨʔϜϫʔΫͷׂ• ͳΜ͔Ͱ͔͍JSONΛ࡞Δ• ͳΜ͔Ͱ͔͍JSONΛViewʹΔ• ͳΜ͔Ͱ͔͍JSONΛ࡞ΔͭʹΠϕϯτΛૹΔ
ͦͦແݶͷύϑΥʔϚϯε͕͋Ε…const mainloop = () => {requestAnimationFrame(mainloop)document.body.innerHTML = render(getState())}mainloop()
UIϥΠϒϥϦࢮ͵ͷ͔• Ϩϯμϥͷ WebComponents • ঢ়ଶͷཧΔ
ϑϩϯτͷྑ͍ઃܭͱ• x ίʔυ͕Βͳ͍• ○ ϞδϡʔϧΛँͰ͖ΔGUIͷਏ͞ɺઃܭ༷͕ίʔυʹΓʹ͍͘ͱ͜Ζࢦ͖͢ɺݎ࿚ͳઃܭΑΓɺࣜભٶͰʁͱ͍͏ఏҊ
͓ΘΓ