Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
実践Isomorphic(+ Electron)
Search
Koutarou Chikuba
April 30, 2015
Programming
14
23k
実践Isomorphic(+ Electron)
isormorphic meetupの資料です
Koutarou Chikuba
April 30, 2015
Tweet
Share
More Decks by Koutarou Chikuba
See All by Koutarou Chikuba
極限環境で最終ビルドを絞るためのフロントエンド設計
mizchi
15
5k
Server Side JavaScript のためのバンドル最適化
mizchi
5
6.7k
V8 as a container on CDN Edge worker
mizchi
6
2k
Edge Side Frontend という新領域
mizchi
34
14k
バンドル最適化マニアクス at tfconf
mizchi
7
4.2k
「たかがJavaScript」のその先 #TECHPLAY
mizchi
47
20k
Deno Node 両刀
mizchi
6
2.4k
「フロントエンド領域」を再定義する
mizchi
50
36k
光を超えるためのフロントエンドアーキテクチャ
mizchi
91
23k
Other Decks in Programming
See All in Programming
fs2-io を試してたらバグを見つけて直した話
chencmd
0
280
「とりあえず動く」コードはよい、「読みやすい」コードはもっとよい / Code that 'just works' is good, but code that is 'readable' is even better.
mkmk884
6
1.3k
Effective Signals in Angular 19+: Rules and Helpers
manfredsteyer
PRO
0
310
Spatial Rendering for Apple Vision Pro
warrenm
0
340
ある日突然あなたが管理しているサーバーにDDoSが来たらどうなるでしょう?知ってるようで何も知らなかったDDoS攻撃と対策 #phpcon.2024
akase244
2
7.6k
今年一番支援させていただいたのは認証系サービスでした
satoshi256kbyte
1
280
php-conference-japan-2024
tasuku43
0
400
為你自己學 Python
eddie
0
490
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
630
DevFest - Serverless 101 with Google Cloud Functions
tunmise
0
130
技術的負債と向き合うカイゼン活動を1年続けて分かった "持続可能" なプロダクト開発
yuichiro_serita
0
240
バグを見つけた?それAppleに直してもらおう!
uetyo
0
210
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
18
2.3k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.7k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
Visualization
eitanlees
146
15k
Code Reviewing Like a Champion
maltzj
521
39k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
171
50k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Why Our Code Smells
bkeepers
PRO
335
57k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Optimizing for Happiness
mojombo
376
70k
Transcript
࣮ફisomorphic (+ Electron) mizchi / Increments, Inc Ismorphic Meetup
ismorphicͱ ڥΛબͳ͍JavaScript
ࠓ͞ͳ͍͜ͱ ☞ αʔόʔαΠυϨϯμϦϯά
(ࣗͷ)isormorphicͷత ➀ Ͳ͜Ͱಈ͘୯ػೳͳϞδϡʔϧΛఏڙ͍ͨ͠ ➁ node.jsͷϞδϡʔϧγεςϜΛ׆༻ͯ͠։ൃ͍ͨ͠ ➂ MVCڲਖ਼Ϊϓε
1. Ͳ͜Ͱಈ͍ͯ΄͍͠ ☞ ϒϥβڥ ☞ DOM͔Βಠཱͨ͠Workerڥ ☞ nodeڥ ☞ ϔουϨεςεςΟϯά
2. node.jsͷϞδϡʔϧγεςϜΛ׆༻ͯ͠։ ൃ͍ͨ͠ ☞ ʮnodeϞδϡʔϧnodeඇґଘͳΒಈͣ͘ʯͱ͍͏ߟ͑ํ ☞ ϥΠϒϥϦఏڙ࣌ڥґଘ͔Ͳ͏͔Λৗʹҙࣝ͢Δ
3. MVCڲਖ਼Ϊϓε ☞ pure javascript + ڥͷࠩΛٵऩͰ͖Δ+α ʹ੍ݶ͞ΕΔ ☞ MVCͰ͍͏Ϗϡʔ͕ࣗવͱ৮Γਏ͘ͳΔ
☞ => υϝΠϯʹྗ
ҰੲલͷJSͱ͍͑… jQueryͱDOMͱJavaScriptͷ۠ผ͕͞Ε͍ͯͳ͍αϯϓϧίʔυ͕ ͨ͘͞Μ͋ͬͯਏ͔ͬͨ
ͨͱ͑… markdownίϯύΠϥͷmarkedͲͷڥͰಈ͘ ☞ nodeͰίϯύΠϧͰ͖Δ ☞ ϒϥβίϯύΠϧͰ͖Δ ☞ webworkerͰ1/4ͣͭઍͬͯฒྻϏϧυͰ͖Δ ☞ ϒϥβΛ্ཱͪ͛ͣʹnodeͰ୯ମςετͰ͖Δ
ͦͷଞɺڧ͍ಈػ ͱʹ͔͘ෆ҆ఆͰॏ͍Phantom.jsͰςετͨ͘͠ͳ͍
֤ڥͷࠩ
άϩʔόϧۭؒ window: DOM͕ଘࡏ͢Δڥ global: nodeڥ self: WebWorker / ServiceWorkerڥ
ڥґଘAPI ☞ document / navigator ☞ setImmediate / requestAnimationFrame ☞
ϙϦϑΟϧ͕ͳ͍ωΠςΟϒϞδϡʔϧͷrequire(httpvm) ☞ etc...
࣮ࡍʹ… ☞ ECMAScriptͷൣғ͚ͩͰ࣮͢Δͷ͕(ཧతʹ)ਖ਼͍͠ ☞ ͱ͍͑nodeͱϒϥβΛαϙʔτͯͨ͠Βे ☞ workerڥΕΒΕ͕ͪ
ωΠςΟϒϞδϡʔϧ ☞ preinstallͰgypͰωΠςΟϒϏϧυ͢Δͷݺͳ͍ ☞ ωΠςΟϒͰબͳ͍ ☞ sundown ΑΓ marked
Ͳ͏ͯ͠ωΠςΟϒϞδϡʔϧΛݺͼͨ ͍ ☞ emscriptenͰϏϧυ͢Δ ☞ zlib.jsͱ͔ ☞ llvm.jsͱ͔ ☞ Ϗϧυ͕ߴίετ/όΠφϦαΠζ͕ڊେԽ͢ΔͷͰਪ͠ͳ͍
commonjs require
commonjs/require ͱ ☞ node.jsͷϞδϡʔϧղܾγεςϜ ☞ requireؔͱͦͷϑΝΠϧΛؚΉpackage.jsonͷmain͔Βղܾ ͞ΕΔ
࠷খͷϞδϡʔϧ - package.json - foo.js module.exports = function(){console.log('foo')}; {"name":"foo", "main":
"foo.js"}
commonjsͷϒϥβ͚ϓϦϓϩηοα ☞ substack/node-browserify ☞ webpack ☞ require1k — CommonJS require
for the browser in 1k ☞ Duo ͦΕͧΕඍົʹڍಈ͕ҟͳΔׂ͕Ѫ
جຊతͳΈ ☞ requireؔͷϙϦϑΟϧΛૠೖ͢Δ ☞ AST͔Βrequire('./hoge')Λ૬ରύε./hogeͷࢀরஔ͖͑Δ ☞ ./hoge ͷࢀরಉ͡ϞδϡʔϧͰڞ༗͞ΕΔ
browserify/webpackͷ੍ݶ ☞ requireઌ͕จࣈྻҎ֎ͩͱࢀরͷΛߦ͑ͳ͍ ☞ requireؔͷࢀরΛίʔϧͨ͠ͱ͖͠ͳ͍
μϝͳྫ var x = './foo'; require(x);
μϝͳྫ req = require; req('./foo');
μϝͳྫ global.require('foo'); ※͜Ε͋ͱͰ͏
࣮ફ
altjsjsxͷมܗ ͍ΖΜͳํ๏͕͋Δ ☞ browserify transform ☞ webpack plugin ☞ gulp/gruntͰϓϦϓϩηε
☞ require.extensionsͰϑοΫ(node/electronͰͷΈ༗ޮ)
mizchiͷͨͲΓண͍ͨϕετϓϥΫςΟε ☞ gulpͰsrcҎԼΛlibʹు͖ग़͢ ☞ libΛ .gitignore Ͱࢦఆͯ͠git͔Βແࢹ ☞ watchifyͰlibҎԼΛࢹͯࠩ͠build
☞ ςετmochaͱcoffeeͰࡶʹॻ͘(ΈͰબͿ) ☞ power-assertͰมܗ ☞ ςετ࣌libଆΛݺͿ mocha --require espower-coffee/guess test/*.coffee
src/ foo.coffee bar.ts template.jade lib/ <-- .gitignore foo.js bar.js template.js
test/ foo-test.coffee
͜ͷํࣜͷཧ༝ ☞ browseirfyͰҰׅͰղܾ͢Δͱɺ୯ମςετ࣌ʹҰՕॴॻ͖ ͚͑ͨͩͰશ෦ͷϞδϡʔϧΛϏϧυ͢Δඞཁ͕͋Δ ☞ ୯ମςετͰ͖Δ͜ͱͰϞδϡʔϧͷಠཱੑΛอূͰ͖Δ
watchify ☞ browserify ΤϯτϦϙΠϯτ͔Βશͯθϩ͔ΒϏϧυ͠Α͏ ͱ͢Δ ☞ watchifyࠩࢹͯ͠ు͖ग़͢ ࣗͷϓϩδΣΫτͰ 8.3s →
0.02s React͍Δ͚ͩͰݦஶʹมΘΔ
ES6 moduleͲ͏͢Δʁ ☞ import / export ☞ কདྷతʹͬͪ͜?(node͕node_modulesΛͲ͏ѻ͏͔ܾ·ͬͯͳ ͍) ☞
babelrequireܗࣜʹม͢Δ ☞ typescriptͷ --target commonjs export default ະରԠ
Electron (چ atom-shell)
Electron ☞ Atomͷϕʔε ☞ window ͱ global ͕ڞଘ͢Δڥ ☞ τοϓϨϕϧthis
window
ElectronڥͷಛघͳϥΠϒϥϦ require('app'), require('browser-window') ଞɺmenu, clipboard, crash-reporter,
ElectronڥͰͷbrowserify ☞ node_modulesԼͷෆཁͳϑΝΠϧΛআͯ͠αΠζॖখ ☞ ؆қͳಡԽ ࣗͷϓϩδΣΫτͰ(250MB → 2.2MB) Θͳͯ͘ಈ͘ͷ͕ڧΈͰ͋Δ
Ұ෦browserifyͰ͖ͳ͍ͷͰͲ͏ʹ͔͔ͯ͠Θ͢ var marked = require('marked'); // browserifyͰมܗ var app =
global.require('app'); // ͦͷ··௨͢ ※ Oops
Node.js / ElectronઢͰͷϒϥβڥ
݁ہDOMͱͳΜͩͬͨͷ͔ ☞ ͬͱීٴͨ͠؆қͳGUIπʔϧΩοτ ☞ nodeͰ࣮ͨ͠ϞδϡʔϧΛͬ͘͞ΓGUIΞϓϦʹࡌͤΒΕͯ αΠίʔ ☞ ͨͩ͠EmbededͳChromeؚΉͷͰόΠφϦେ͖͍(40MBఔ )
ElectronͷՌׂͨ͢ ☞ มԽͷૣ͍ϒϥβڥΛݻఆ͢ΔΞϓϩʔνͷҰͭ ☞ Chromeͷ࠷৽APIΛ੯͠Έͳ͑͘Δݱ࣮తͳϓϥοτϑΥʔ Ϝ
ଞɺڥ͝ͱͷIsomorphic
View Isormorphic
Reactͷ߹ ☞ React.renderToString(...) ☞ React.renderToStaticMarkup(...) jsdom͑ React.renderToString(...) ·Ͱ͍͚Δ ࢀߟ: JSDOMͱReact.addons.TestUtilsͰReactΛϔουϨεʹςετ
͢Δ - Qiita
Isomorphic for V8 ctx = V8::Context.new ctx.eval """ var global
= {}; """ ctx.eval $react_source ctx.eval """ var React = global.React; """ V8 binding͋ΕଞͷݴޠͰ͍͚Δ
Network Isomorphic
ServiceWorkerͰIsomorphic ☞ ωοτϫʔΫϓϩΩγ ☞ ΞϓϦέʔγϣϯΩϟογϡ ☞ ϓογϡ௨(͜ΕࠓճͲ͏Ͱ͍͍)
Express͍ͨ͘ͳ͍? ☞ ωοτϫʔΫϦΫΤετ͕ϞοΫͰ͖ΕIn/Out੍ޚͰ͖Δͷ Ͱ ☞ => ServiceWorker্Ͱexpress࣮ͨ͠Β͍͍Μ͡ΌͶʁ
Sabizan ☞ mizchi/sabizan ☞ ServiceWorker্Ͱexpress෩ͷAPI͕ॻ͚Δ ☞ ·ͩ·ͩPoC mizchi-sandbox/scala-js-in-service-worker
ࠓಈ͍ͨίʔυ # it will respond to https://localhost:3000/api/user/fuga?foo=bar proxy.get '/user/:id', ({id},
{foo}, req) -> {id, foo} # Return with promise proxy.post '/post', ({}, body) -> new Promise (done) -> setTimeout -> done {type: 'this is post:'+params.prop} , 300
·ͱΊ
(ࣗͷ)Isomorphicੈք؍ ☞ View(React) ☞ ωοτϫʔΫ(ServiceWorker) ☞ Ϟδϡʔϧ(Browserify) શ෦ϔουϨε
͓ΘΓ