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
pixiv SketchのSSRの話
Search
geta6
April 11, 2017
Technology
4.4k
10
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
pixiv SketchのSSRの話
pixiv SketchでSSRしている感じの話です
geta6
April 11, 2017
More Decks by geta6
See All by geta6
mastodonのnodeのはなし
geta6
0
3.2k
ReactとFluxのこと
geta6
166
65k
What is CoffeeScript
geta6
8
940
Other Decks in Technology
See All in Technology
AI時代の開発生産性は、個人技からチーム設計へ
moongift
PRO
2
210
Gen3R: 3D Scene Generation Meets Feed-Forward Reconstruction
spatial_ai_network
0
120
「早く出す」より「事業に効く」 ── 顧客の業務サイクルから逆算するAI時代の二重ループ開発と「変化の設計者」 / devsumi2026
rakus_dev
1
230
キャリアの中で本を作る / Making a Book During Your Career
ak1210
0
140
凡エンジニアがこの先生きのこるためには。〜TypeScript完全に理解したい〜
alchemy1115
2
180
しぶいSRE: サーバから見えない障害にどう向き合うか。ラストワンマイルのデバッグ実践 / Shibui SRE
kanny
13
6.1k
最適な自走を最小限の支援で — M&Aで拡大する組織で少人数SREが挑んだ1年 / SRE NEXT 2026
genda
0
1.1k
ボーイスカウトルールでメモリやスキルを改善しよう
azukiazusa1
1
890
個人開発で育てる「大規模設計の苗床」 - AI時代の1人開発から始める業務への知識接続 / The Seedbed for Large-Scale Design - From AI-Era Solo Projects to Professional Knowledge
bitkey
PRO
0
170
非定型なドキュメントを効率よくリファクタする 〜えぇ!?仕様書27本の移行が1日で終わったって!?〜
subroh0508
1
350
End-to-Endで考える信頼性 —LINEアプリにおけるクライアント開発×SRE連携の実践
maruloop
4
4.1k
「最後に責任を取るのはチーム」— 人間のPRレビューを最小化してアップデートしたメンタルモデル
jnishime_dresscode
0
600
Featured
See All Featured
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
260
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
460
Technical Leadership for Architectural Decision Making
baasie
3
440
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
650
Building Adaptive Systems
keathley
44
3.1k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
410
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
63
55k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
My Coaching Mixtape
mlcsv
0
170
Statistics for Hackers
jakevdp
799
230k
Transcript
None
௮͚͜Μͩ443ͷ αʔόʔαΠυϨϯμϦϯά
w ໊લɿ͛ͨ w ৬ۀɿҰൠϊʔϚϧΤϯδχΞ w QJYJW4LFUDIͰ8FCଆͷ࣮શൠͨ͠Γϔϧϓͯ͠ ͘ΕΔਓͷհޢΛͨ͠Γ͍ͯ͠·͢ HFUB
443ͬͯͳʹΑ w αʔόʔαΠυϨϯμϦϯάͷ͜ͱ w ͬ͘͟Γݴ͏ͱ w 41"ͷॳճϩʔυ͍ͨ͘͠ w KTͰίϯςϯπߏங͠ऴΘͬͨঢ়ଶΛαʔόʔ αΠυͰ࡞ͬͯग़ͪ͠Ό͑͘ͳΔ͡ΌΜʂͦ
ͷ··ಉ͡ίʔυ͍ճͤΔ͠ఱ࠽ʂ w ͱ͍͏ײ͡ͷΞϨ
͢͜ͱϦετ w TLFUDIͷΞʔΩςΫνϟʢ֓આʣ w 443ͬͯ۩ମతʹͲ͏Δͷ w DTTͲ͏ͯ͠Δͷ w ͳΜͰ443ʹͳͬͨͷ w
σϝϦοτͱϝϦοτ w ͦͷͨ
ΞʔΩςΫνϟ
ΞʔΩςΫνϟ Web Browser pixiv Sketch API rails iOS Android iOS
app Android app node.js javascript ࠷ۙͨ·ʹݟ͔͚Δߏ͚ͩͲɺͬͯΔͱ͜গͳͦ͏
ΞʔΩςΫνϟ Web Browser pixiv Sketch API rails iOS Android iOS
app Android app node.js javascript ΅͘ͷ୲
Web Browser pixiv Sketch API rails node.js javascript ΞʔΩςΫνϟ express
React + Fluxible
Web Browser pixiv Sketch API rails node.js javascript ΞʔΩςΫνϟ SSR
React SharedCode XHR HTTP viewͳ͠ɺjson͚ͩ
Web Browser pixiv Sketch API rails node.js javascript ΞʔΩςΫνϟ MCͷೄுΓ
VͷೄுΓ αʔόʔ͖ͷڊେͳSPA
3FOEFSFS w OPEFαʔόʔ SFOEFSFS ϏδωεϩδοΫηο γϣϯػߏΛҰ͍࣋ͬͯͳ͍ w "1*͔Β͞ΕͨσʔλΛݩʹɺϒϥβͱಉ͡ ίʔυͰ)5.-Λߏஙͯ͠ϨϯμϦϯά w
αʔόʔαΠυͰ"1*ϦΫΤετ)551 w $PPLJFϔομΛαʔόʔͷ)551ϦΫΤελʔʹ ηοτͯ͠ೝূঢ়ଶΛදݱ
3FOEFSFS w ؆୯ʹݴ͏ͱ.7$ͷ.$͕SBJMTͰ7͕OPEF w .$ͱ7ͷؒʹΞʔΩςΫνϟͷน͕ଘࡏ͢Δʢݴ ޠɾ'8ɾΠϯελϯε͕ҧ͏ʣͷͰɺޓ͍Λ৵ ൜Ͱ͖ͳ͍
3FOEFSFS w 6*ͷ͜ͱ͚ͩΛߟ͍͑ͯΕ͍͍ɺϩδοΫʹབྷΉ ෳࡶͳॲཧ"1*ʹͿΜ͛ͯɺ͓͔͔ͬͨ͠ΒYY ͔YY͕ฦͬͯ͘ΔͷͰΑ͠ͳʹमਖ਼ w ෦ใಛݖతʹΞΫηε͢Δखஈ͕ଘࡏ͠ͳ͍ ͷͰɺOPEF࣮ͷΤϯόά͕ηΩϡϦςΟϦεΫ ʹܨ͕ΔՄೳੑ͕͍ "1*͕ਖ਼͍͠ͱԾఆͯ͠
3FOEFSFS Web Browser pixiv Sketch API rails node.js javascript ӽ͑ΒΕͳ͍น
SSR͢ΔͱMCͱV ͚͟ΔΛಘ͘ͳΔ
3FOEFSFS w .7$ڲਖ਼Ϊϒε w ͲΕ͚ͩٸ͍Ͱ͍ͯ಄ͷ͓͔͍͠7JFXίʔυ ͕ॻ͚ͳ͍ɺෛ࠴ઈର࡞Βͳ͍Ϛϯ w 443͍͍ͧ
۩ମతʹͲ͏Μͷʁ
443ग़ྗͷΠϝʔδ w %0$5:1&Ҏ֎ͷ)5.-Λશͯ3FBDUͰߏங w BDUJPOΛୟ͍ͯίϯςϯπදࣔʹඞཁͳTUPSF σʔλΛऩू w 3FBDU%0.SFOEFS5P4UBUJD.BSLVQΛར༻ͯ͠ %0.ΛTUSJOHʹ͢Δɺ͍ͭ͜ʹ%0$5:1&Λͬ͘ ͚ͭͯFYQSFTT͔ΒSFTTFOE͢Δ͚ͩ
w ͔ΜͨΜʂʂ
443ग़ྗͷΠϝʔδ const app = new Fluxible({ /* shared app root
component, stores */ }); const srv = express(); srv.use((req, res) => { req.context = app.createContext(); /* ͍Ζ͍Ζ४උ͢Δ (APIΛfetchͨ͠Γͯ͠ɺfluxΛճ͢) */ const react = React.createElement(Html, { context: req.context }); const html = ReactDOM.renderToStaticMarkup(react); res.send(`<!doctype html>${html}`); }); ͜͜Ͱڞ௨ίʔυ Λ͢ html͕ϧʔτͷ component ͔ΜͨΜʂʂ
express (1 request) 443ग़ྗͷΠϝʔδ req Flux Context res React Flux
Context ReactDOM store store css React (html)
express (1 request) 443ग़ྗͷΠϝʔδ req Flux Context res React Flux
Context ReactDOM store store css React (html) shared shared server code
JTPNPSQIJDTUPSF w TUPSFͷσʔλTFSWFS͔ΒDMJFOUҙࣝతʹͯ͠ ͋͛ͳ͍ͱ͍͚ͳ͍ w TUPSFͷঢ়ଶTFSJBMJ[Fͨ͠KTσʔλͱͯ͠ςϯϓ Ϩʔτ )UNM$PNQPOFOU ͔ΒϖʔδʹຒΊࠐΉ w
DMJFOUͷॳظԽ࣌ʹ͜ΕΛೖखͯ͠TUPSFͷঢ়ଶΛ ෮چͤ͞Δ
JTPNPSQIJDTUPSF const app = new Fluxible({ /* shared app root
component, stores */ }); const srv = express(); srv.use((req, res) => { req.context = app.createContext(); /* ͍Ζ͍Ζ४උ͢Δ (APIΛfetchͨ͠Γͯ͠ɺfluxΛճ͢) */ const dehydrated = `window.dehydrated=${serialize(app.dehydrate(req.context))}`; const react = React.createElement(Html, { context, dehydrated }); const html = ReactDOM.renderToStaticMarkup(react); res.send(`<!doctype html>${html}`); }); serializeͯ͢͠
JTPNPSQIJDDTT w XFCQBDLΛ༻ͯ͠DTTΛఏڙ͢ΔGVODUJPOͱͯ͠ USBOTQJMF͓ͯ͘͠ʢLSJBTPGUJTPNPSQIJDTUZMF MPBEFSʣ w $PNQPOFOUϚϯτ࣌ʹ͜ͷϝιουΛݺΜͰɺ ͕ࣗඞཁͱ͢ΔTUZMFΛϒϥβʹఏڙ͢Δ
JTPNPSQIJDDTT w DMJFOUͱTFSWFSͰDTTͷॲཧํ๏Λม͑Δ w TFSWFSͰDTTΛTUSJOHͱͯ͠ಘΔGVODUJPOΛ࣮ߦɺ BSSBZʹTUSJOHΛQVTI͓͍ͯͯ͠ϨϯμϦϯά࣌ʹ TUZMFλάʹల։͢Δ w DMJFOUͰTUZMFΛIFBEʹJOTFSU͢Δ%0.ૢ ࡞͖GVODUJPOΛ࣮ߦ
JTPNPSQIJDDTT const app = new Fluxible({ /* shared app root
component, stores */ }); const srv = express(); srv.use((req, res) => { req.context = app.createContext(); /* ͍Ζ͍Ζ४උ͢Δ (APIΛfetchͨ͠Γͯ͠ɺfluxΛճ͢) */ const context = req.context.getComponentContext(); const styles = []; context.insertCss = (s) => styles.push(s._getCss()); const dehydrated = `window.dehydrated=${serialize(app.dehydrate(req.context))}`; const react = React.createElement(Html, { context, dehydrated, styles }); res.send(`<!doctype html>${html}`); }); ReactContextͰpush ͢ΔϝιουΛ͢
)UNM$PNQPOFOU w EBOHFSPVTMZ4FU*OOFS)5.-Λͬͯ͞ΕͨTUZMF TFSJBMJ[F͞ΕͨTUPSFσʔλΛΨϯΨϯຒΊࠐΉ w DMJFOU༻ͷॳظԽTDSJQUͰςϯϓϨʔτͱͯ͠ຒΊࠐ ·Εͨ͜ΕΒΛೖख͠ɺDMJFOUଆͷΞϓϦέʔγϣ ϯΛαʔόʔͱಉ͡ঢ়ଶʹ෮چ͢Δ
express (1 request) 443ग़ྗͷΠϝʔδ req Flux Context res React Flux
Context ReactDOM store store css React (html) serialize ArrayPush render toStaticMarkup res.send
DTTͷ͜ͱৄ͘͠
˺8FC$PNQPOFOUT w 4LFUDI8FC൛ͷ$PNQPOFOUઓུ w 3FBDU$PNQPOFOUͷKT࣮ɾDTTείʔϓ͕ࣗ ͷ֎ӨڹΛٴ΅͞ͳ͍Α͏ʹ࣮ɾઃܭ͢Δ w DTTXFCQBDLΛ༻ͯ͠KTʹแɺίϯϙʔωϯ τ୯ҐͰهड़͠ίϯϙʔωϯτࣗʹཧͤ͞Δ w
LSJBTPGUJTPNPSQIJDTUZMFMPBEFSࢀর
˺8FC$PNQPOFOUT w DPNQPOFOU8JMM.PVOUͰDTTΛϚϯτ͠ɺ DPNQPOFOU8JMM6ONPVOUͰDTTΛΞϯϚϯτ͢Δ w ϚϯλʔɾΞϯϚϯλʔ෦ʹΧϯλʔ Λ͍࣋ͬͯΔ w Ϛϯλʔʮطʹࣗͱಉ͡$PNQPOFOU͕ଘ ࡏ͍ͯ͠ΕʯϚϯτ͠ͳ͍
w ΞϯϚϯλʔʮ·ͩࣗͱಉ͡$PNQPOFOU ͕ଘࡏ͍ͯ͠ΕʯΞϯϚϯτ͠ͳ͍
ίϯϙʔωϯτߏ - Component/ `- package.json // { "main": "Component.jsx" }
`- Component.jsx // component `- Component.styl // stylesheet for component σΟϨΫτϦΛimportͨ࣌͠ʹ mainͷΛࢀরͯ͘͠ΕΔ
$PNQPOFOUKTY import React, { Component } from 'react'; import {
withStyle } from '../../utils/Decorator'; @withStyle(require('./Component.styl')) export default class Component extends Component { static displayName = 'Component'; componentDidMount = () => { console.log('mounted'); }; render = () => ( <div id='Component'> <div id='ComponentBody'> <span>component content</span> </div> </div> ); } ޙड़ ίϯϙʔωϯτ໊ͱಉ͡ id͔classΛRootʹऔΔ ※ transform-decorators-legacy
$PNQPOFOUTUZM #Component &Body box-sizing border-box margin 0 auto padding 0
20px max-width 600px width 100% ϑΝΠϧ͋ͨΓ Root1ݸͷϧʔϧ
4UZMF%FDPSBUPS import noop from 'lodash/noop'; import React, { Component, PropTypes
} from 'react'; export const withStyleDecorator = (style) => (ComposedComponent) => ( class WithStyle extends Component { static displayName = `withStyle(${ComposedComponent.displayName})`; static contextTypes = { insertCss: PropTypes.func.isRequired, }; constructor(props, context) { super(props, context); this.removeCss = style ? this.context.insertCss(style) : noop; } componentWillUnmount = () => { this.removeCss && setTimeout(this.removeCss, 0); }; render = () => ( <ComposedComponent {...this.props} /> ); } ); isomorphic-style-loader ͔Βఏڙ͞ΕΔϚϯλʔ
4UZMFTIFFU3VMF w ίϯϙʔωϯτ໊ͱϧʔτͷJEDMBTT໊ΛҰகͤ͞ ΔͱɺϑΝΠϧγεςϜͷ੍্͓ͳ໊͡લͷ 3PPU&MFNFOU࡞Ͱ͖ͳ͘ͳΔ w ໊લ͚ͷϧʔϧΛ౷Ұ͢Δ͚ͩͳͷͰDTTNPEVMF Λಋೖ͢ΔΑΓखܰ
443Λબͨ͠ཧ༝
8FCͷେ·͔ͳมભ w ։ൃ։࢝ νʔϜϝϯόʔਓ w ϦϦʔε w
υϩʔػೳWϦϦʔε 4NPPUI-JOF w 8FCϦϑΝΫλϦϯά w υϩʔػೳWϦϦʔε 8FC(-൛
w ϦϦʔε͔Βݱࡏ·ͰΞʔΩςΫνϟʹมߋͳ͠ w αʔϏεϦϦʔε͔ΒҰ؏ͯ͠αʔόछߏɺ ʮػೳՃʯͱʮ࠷దԽʯͷΈΛ࣮ࢪ w ϦϑΝΫλ3FBDUWରԠʹਵ͢Δ$PNQPOFOU ࠷దԽɾTUPSFपΓͷϝϞϦར༻࠷దԽɾ&4 ͷै͕ओͳλʔήοτ w
αʔϏεϦϦʔε࣌ʹཁ݅ʹ߹க͢Δʮਖ਼ղʯͷΞʔ ΩςΫνϟΛબ͢Δ͜ͱ͕Ͱ͖ͨ
443ΛܾΊͨϑϩʔ
443ΛܾΊͨϑϩʔ w Ұ൪࠷ॳOPEFͰϓϩτλΠϐϯάͨ͠ w ࣌3FBDU W ͕ྲྀߦΓΈΛਂΊ͍ͯͯɺϑϩ ϯτ૪͕աظΛܴ͍͑ͯͨ w ৽ن։ൃͷબࢶ͔Β#BDLCPOFͷྶѹ͕ফ͑ɺ
"OHVMBS͔3FBDU͔ͱ͍͏ײ͡ʹͳΓͦ͏ͳࠒ
443ΛܾΊͨϑϩʔ w ͱͱɺ3FOES BJSCOCͷ#BDLCPOFΛαʔόʔ Ͱ͑Δͭ ͬΆ͍࣮ͰKTʹ·ͭΘΔೋॏςϯ ϓϨʔτ࣮Λഁ໓͍ͤͨ͞ئ͕͋ͬͨ w #PPUIͰKTςϯϓϨʔτͷೋॏ࣮ʹർΕ͖͍ͬͯͨ
443ΛܾΊͨϑϩʔ w ϓϩτλΠϓதʹ'MVYJCMFͱ͍͏443ରԠͷ'8Λݟ ͚ͭͨͷͰɺ͍ܰϊϦͰ443Λࢼͨ͠ w ΅͘ʮOPEFͰ͍͍ͬͯʁʯ w 1.ʮ͍͍ͧʯ w ΅͘ʮ3FBDUͬͯͷͱ'MVYJCMFͬͯͷͰ443͕ʔʯ
w 1.ʮ͡ΌΜ͡ΌΜߦ͜͏ʯ
443ΛܾΊͨϑϩʔ w όοΫΤϯυͷෆ͔҆ΒSBJMTΤϯδχΞΛௐୡ w SBJMT͔ΒWJFXΛग़͢ͷઈରʹݏͩͬͨ ޙड़ w 1.ʮJ04൛ઈରಉ࣌ʹϦϦʔε͢Δͧʯ w
αʔϏεϦϦʔεॳ͔Β"1*͕ඞཁ w SBJMTαʔόʔ͔ΒWJFXΛग़ྗ͢Δͱɺ"1*ͱWJFX Ͱೋॏʹ࣮͕ඞཁʹͳͬͯ͠·͏
443ΛܾΊͨϑϩʔ w αʔϏεUVNCMSJOTUBHSBNͷΑ͏ͳʮλΠϜϥ Πϯʯ͕جຊϏϡʔɺϖʔδϯά࣮͕ඞਢ w SVCZͷJUFNUFNQMBUFʹKTͷJUFNUFNQMBUFΛ ॻ͍ͯ9)3ͰKTPOΛೖखͯ͠ΰϦΰϦϖʔδϯ άɺΈ͍ͨͳࠈಘͨ͘ͳ͍ w ͔ͯ͠͠8FCҰͭͷΫϥΠΞϯτͱݟͳͤΑ
͍ͷͰɺOPEFαʔόʔΛʮ8FC#SPXTFS͚ͷ ΞϓϦʯͬͯݴ͍ுΕͳ͍ͩΖ͏͔
443ΛܾΊͨϑϩʔ w ʮ8FCϒϥβ͚ͷΞϓϦʯͱ͍͏ঢ়ଶʹͳΔͱ ωΠςΟϒΞϓϦͱίϯςΩετ͕ڞ༗Ͱ͖Δ w "1*ͷར༻ํ๏ʹؔͯ͠ݟڞ༗͕Մೳɺ࣮ί ετΛݮΒͤΔ w SBJMTͷ࣮KTPO͚ͩΛΕΑ͘ͳΔɺUFNQMBUF ࣮͕ඞཁͳ͍ͷͰ࣮ίετΛݮΒͤΔ
443ΛܾΊͨϑϩʔ w .$ͱ7ͷؒʹΞʔΩςΫνϟͷน͕͋Δ͜ͱͰ ʮUFNQMBUFʹ͔͠ଘࡏ͠ͳ͍มʯ͕ੜଘͰ͖ͳ ͍ɺϝϯςφϯείετ͕ݮΒͤΔ w ΫϥΠΞϯτ͚࣮͕ޓ͍ʹґଘੑΛ࣋ͨͳ͍ w ͋ΔϓϥοτϑΥʔϜ͕ಛఆͷػೳΛαϙʔτ͢Δ ͔Ͳ͏͔ɺ७ਮʹ༏ઌͷʹू͞ΕΔ
443ΛܾΊͨϑϩʔ w KTͰੜ͢Δίϯςϯπ͕4&0తʹΞϨ͕ΞϨ͔ͩ ΒΞϨɺΈ͍ͨͳΛ͠ͳͯ͘Α͘ͳΔ ࣌ w OPEFKTαʔόʔΛSBJMTαʔόʔͱผʹཱͯͯ443 ͠Α͏ͥɺͱ͍͏ྲྀΕʹઆಘྗ͕༩͑ΒΕͨ
443ΛܾΊͨϑϩʔ w 443ཱ͕ͪͦ͏ͳγʔϯ w ΠςϨʔτ͢ΔϦονίϯςϯπΛఏڙ͍ͨ͠ w ςϯϓϨʔτͷೋॏ࣮Λආ͚͍ͨ w ϞόΠϧͱಉ࣌ϦϦʔε "1*͕࠷ॳ͔Βඞཁ
σϝϦοτ
σϝϦοτ w ॏ͍ɺ͍͍ͩͨͷͷ͕ॏ͍ɺͱʹ͔͘ॏ͍
σϝϦοτ w αʔόʔαΠυͰ"1*ϦΫΤετ)551 w Φʔόʔϔου͕େ͖͍ɺϨεϙϯεʹ͔͔Δ͕࣌ؒ Ұ൪ॏ͍ͱ͜ΖͰT͘Β͍͔͔ͬͯ͠·͏ w 3FOEFSFSҰͷಛݖΛ࣋ͨͳ͍ͨΊɺϢʔβʔ͕ϩά Πϯ͍ͯ͠Δ͔Ͳ͏͔Λ"1*ͷGFUDIແ͠ʹΓಘͳ͍ɺ ϧʔςΟϯάޙͷTUPSFͷঢ়ଶΛݟͯఆ͢Δ͔͠ͳ͍
w ͦͷͨΊʮ1SPNJTFBMMͰϦΫΤετΛશฒྻʹͯ͠ζ υϯʯͷΑ͏ʹ୯७ʹ͍͔ͳ͍ɺ4LFUDIͰ443࣌ ʹฒྻϦΫΤετΛճʹ͚ͯૹ͍ͬͯΔ
σϝϦοτ w ৴͢ΔKT͕ංେԽ͕ͪ͠ w XFCQBDLͰશͯΛUSBOTQJMF͢ΔͱKTίʔυʹDTT ؚ·ΕΔ͜ͱʹͳΔ w ݱ࣌ͰϑΝΠϧαΠζ.#ɺϞόΠϧΞϓ Ϧ͕ແ͍αʔϏεͰ͋Εݱ࣮తͳαΠζͰͳ͍ w
XFCQBDLͷMPBEFSઃఆʹґଘ͢ΔͷͰະѹॖՕॴΛ ࡧ͢Δͷ͕ࠔ ͜ͳ͍ͩDTTͷॏෳͱະѹॖͷͱ͜ ݟ͚ͭͯ.#͘Β͍ݮΒͨ͠
σϝϦοτ w ಄ͷ͓͔͍͠ίʔυ͕ॻ͚ͳ͍ w σʔλ"1*͔Β͔͠औͬͯ͜Εͳ͍͠ɺ͍ͬͺ ͍औΔͱͦΕ͚ͩϨεϙϯε͕͘ͳΔ w ͓·͚ʹKT͕མͪΔͱαʔόʔ͕ΤϥʔΛు͘ w खΑΓઃܭʹଟ͘ͷ࣌ؒΛׂ͘͜ͱʹͳΔ
w ʮԿ·Ͱʹ͜Ε࣮͠ͱ͍ͯʂϤϩγΫʂʯͬ ͯͳͬͨ࣌ʹͭΒ͍ɺ֬อ͠ͳ͚Ε͍͚ͳ͍࣌ ͕ؒগ͠ଟ͘ͳΔ
ϝϦοτ
ϝϦοτ w ಄ͷ͓͔͍͠ίʔυ͕ॻ͚ͳ͍ w KT͕ࣗσʔλΛೖखͯ͠දݱ͢ΔͷͰɺ༝དྷͷ ෆ໌ͳσʔλ͕ଘࡏ͠ͳ͍ʢςϯϓϨʔτʹྲྀ͠ ࠐ·Ε͍ͯΔมͳͲʣ w ࣮େม͚ͩͲɺશମ૾ΛѲͨ͠ਓ͕ॻ͘ͱ ͍͍ͩͨಉ͡Α͏ͳίʔυʹͳΔ
ϝϦοτ w ϓϥοτϑΥʔϜͷ֦ுੑ͕ߴ͍ w શͯͷϓϥοτϑΥʔϜ͕ʮ"1*ͱΫϥΠΞϯτ ΞϓϦʯͱ͍͏ಉҰͷϞσϧʹͳΔ w ͑֬͞อͰ͖ΕϦϦʔε͔࣌Βશͯͷϓϥο τϑΥʔϜ͚ʹΞϓϦ͕࡞Ͱ͖Δ
ϝϦοτ w ϓϥοτϑΥʔϜؒͷґଘੑ͕͍ w "1*ΛؚΉϓϥοτϑΥʔϜؒͷґଘੑ͕͍ͷͰɺ ҙͷλΠϛϯάͰΞϓϦػೳͷ։ൃΛ։࢝͠ɺ ҙͷλΠϛϯάͰఀࢭͰ͖Δ w 4LFUDIͰ"1*ʹSBJMTΛ࠾༻͍ͯ͠Δ͕ɺࣾͷݟɾ ϦϦʔε࣌ظɾઃܭϑϩʔͳͲͷ߹Ͱͨ·ͨ·࠾༻
͞Ε͍ͯΔ͚ͩ w ྫ͑ʮKTPO͔͠Βͳ͍͠(Pʹஔ͖͑Α͏ͥʯ ͱ͍͏Ͱ͖Δ
ϝϦοτ w ೋॏ࣮ͷօࡴ͠ w ϒϥβଆͰϖʔδϯάͨ͠ΓQVTI4UBUFΛαϙʔτ ͨ͠Γ͢Δࡍɺॳճग़ྗͱܧ͗͢༻ͷςϯϓϨʔτ Λೋॏʹߟྀ͢Δඞཁ͕ͳ͍ w ίʔυϕʔε͕ಉ͡+BWB4DSJQUͳͷͰͦͷ··͍ ճ͍͍ͤ
w ܧ͗͞ΕΔՕॴͷΈΞʔΩςΫνϟΛ·͍ͨͩڞ༗ ͷςϯϓϨʔτʹ͢Δͱ͔ɺ)5.-Λ"1*3FTQPOTFʹ ຒΊࠐΉͱ͔ɺͦ͏͍͏͜ͱΛ͠ͳ͍͍ͯ͘
w ϝϦοτͱσϝϦοτ͕͋ΔɺશͯͷΞϓϦέʔγϣ ϯͷύλʔϯʹద߹͢ΔສೳༀͰͳ͍ w ԼهͷΑ͏ͳϞνϕʔγϣϯʹରͯ͠༗༻ w ೋॏ࣮Λආ͚͍ͨ w αʔϏεΛϦονͳ41"ͱͯ͠ߏங͍ͨ͠ w
ෳͷϓϥοτϑΥʔϜΛಉ࣌ʹαϙʔτ͍ͨ͠ w ͱʹ͔͘ԿͰ͍͍͔Β443͕͍ͨ͠
ͦͷଞ
SFTQPOTF w )551ϦΫΤετ͕ϘτϧωοΫʹͳΔ w ͳΔ͘͘͢ΔͨΊ1SPNJTFBMMΛͬͯฒྻԽ w BTZODBXBJUͰ1SPNJTFBMMͨͭ͠ΛBXBJU͢Δ w ͜͜֎෦ґଘʹͳΔͨΊɺඞͣλΠϜΞτΛઃ ఆ͢Δ
SFTQPOTF srv.use(async (req, res, next) => { try { await
Promise.all([ request1, request2, request3, ]); next(); } catch (error) { next(error); } }); ͜͏͍͏ײ͡
6OIBOEMFE3FKFDUJPO w ඞͣVOIBOEMFE3FKFDUJPOΛࢹ͢Δ w ์ஔ͢ΔͱɺΤϥʔʹૺ۰ͨ͠ϢʔβʔͷϨεϙ ϯεΛλΠϜΞτͷݶք·Ͱػͯ͠͠·͏ w ͙ͯ͢͠σϓϩΠͰ͖ΔΑ͏ʹࢹ͓ͯ͘͠ w TFSWFS
QSPDFTTPO VOIBOEMFE3FKFDUJPO 'VOD w DMJFOU XJOEPXPOVOIBOEMFESFKFDUJPO'VOD
FYQSFTTFSSPSIBOEMF w FYQSFTTͰBSJUZ͕ͷGVODUJPOΛVTF͓ͯ͘͠ͱΤ ϥʔ࣌ͷGBMMCBDLʹͳΔ w ͍ͭ͜ͰIUNMͳͲΛฦ٫͢ΔΑ͏ʹ͓ͯ͘͠ w ࠷ۙ·ͰΕͯͯੜΤϥʔϖʔδ͕ग़͍ͯͨʢ໓ଟʹΤϯόά͠ͳ͔ͬͨͷ Ͱؾ͔ͳ͔ͬͨʣ
CBCFMMPBEFS w TFSWFSͱDMJFOUͰXFCQBDLͷCBCFMMPBEFSઃఆΛม ͑Δ w OPEFWҎ্Λ༻͍ͯ͠ΕɺBTZODBXBJUΛ αϙʔτ͍ͯ͠ΔͷͰCBCFMͷSFHFOFSBUPSͰ QPMZpMM͢Δඞཁ͕ͳ͍ w CBCFMQSFTFUFOWΛ͍TFSWFSଆΛOPEF
DVSSFOUͱ͢ΕΑ͍ɺQSPDFTTWFSTJPO͔Βద ͳQSFTFUΛબͯ͘͠ΕΔ
$PNQPOFOU࠶ར༻ w ͳΔ͘$PNQPOFOUΛ࠶ར༻͢Δ w ϨϯμϦϯάKTͷ৴αΠζίʔυΛॻ࣌͘ ؒόάͷಛఆɺ͘খ͘͞Ͱ͖Δ w DTTͷϚϯτɾΞϯϚϯτΧϯλʔॲཧ ͰऴΘΔͷͰΫϥΠΞϯτͷύϑΥʔϚϯε☝
$PNQPOFOU࠶ར༻ Button FollowButton ݟͨͷ੍ޚ Click ϑΥϩʔঢ়ଶͷ੍ޚ Button ݟͨͷ͜ͱ͚ͩ ঢ়ଶͷཧ͚ͩ
QBDLBHFKTPO w XFCQBDLͰQBDLBHFKTPOͰNBJOΩʔͷଞʹɺ CSPXTFSͱ͍͏Ωʔ͕ೝࣝͰ͖Δ w ϑΥϧμʹQBDLBHFKTPOΛஔ͍ͱ͍ͯɺͦͷ QBDLBHFKTPOʹCSPXTFSͱ͍͏ΩʔΛઃఆ͢Δ w ϒϥβଆͷϏϧυͰCSPXTFSͷϑΝΠϧΛ ͍ɺαʔόʔଆͷϏϧυͰNBJOΛ͏ɺͱ͍
͏͍͚͕Ͱ͖Δ w )551ͷϦΫΤελʔ͜ΕΛ͚͍ͬͯͯΔ
QBDLBHFKTPO
MPDBM4UPSBHF w MPDBM4UPSBHFΛར༻͢ΔͷΛΊɺ$PPLJFΛ4UPSBHF ͱͯ͠ར༻͢Δ w ͨͱ͑ϞόΠϧ͚ͷΞϓϦ༠ಋϔομʔͷද ࣔɾඇද੍ࣔޚ w 443࣌ʹϨϯμϦϯάͰ͖͍ͯͨํ͕SFQBJOU͕ ൃੜ͠ͳ͍ɺ$PPLJFʹ͍࣋ͬͯͨํ͕ॳظϩʔ
υύϑΥʔϚϯεͷ্ΛݟࠐΊΔ
ΤϯυϙΠϯτ w ͠Β͘ͷؒɺαʔόʔଆͷ෦ϦΫΤετͷΤϯ υϙΠϯτʹIUUQTTLFUDIQJYJWOFUͱ͍͏ϑ ϧͷ63-Λ͍ͬͯͨ w ໊લղܾͰ͍ͬͨΜ֎ʹग़ΔͱɺIUUQTͰड͚Δ DQVফඅΛճආ͢ΔͨΊɺαʔόʔϦΫΤετͰ ϑϩϯταʔόʔͷ*1Λ͏Α͏ઃఆͨ͠
w ςετKFTUͩͱ͔σϓϩΠTIJQJUͩͱ ͔ SFBDU@QFSGͩͱ͔αʔϏεॳظͰγʔυσʔ λͷूΊํ͕Ұ൪େࣄͩͱ͔&4-JOUͩͱ͔BTZOD BXBJUͩͱ͔%0.ͷྔΛ੍͢Δख๏ͩͱ͔).3 ͩͱ͔47(ΞΠίϯͩͱ͔ը૾ͷϋογϡϏϧυͩ ͱ͔Ϧϩʔυͳ͠ͰݴޠΓସ͑ΒΕΔͩͱ͔Ұ൪ ϝϞϦফඅͷগͳ͍TUPSFͷઃܭख๏ͩͱ͔σΟϨ ΫτϦอकํͱ͔Կ͔͍Ζ͍Ζ͋Γ͖͗ͯ͢͠
Εͳ͍ w ͕࣌ؒΓͳ͍ɺؾʹͳͬͨΒฉ͍͍ͯͩ͘͞
·ͱΊ w 443͍͍ͧ
Ҏ্