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
10
4k
pixiv SketchのSSRの話
pixiv SketchでSSRしている感じの話です
geta6
April 11, 2017
Tweet
Share
More Decks by geta6
See All by geta6
mastodonのnodeのはなし
geta6
0
3k
ReactとFluxのこと
geta6
166
63k
What is CoffeeScript
geta6
8
840
Other Decks in Technology
See All in Technology
MicrosoftのOSSだけでAIによるブラウザテストを構成する
ymd65536
1
240
信頼性を支えるテレメトリーパイプラインの構築 / Building Telemetry Pipeline with OpenTelemetry
ymotongpoo
9
4.4k
TSのコードをRustで書き直した話
askua
4
990
企業テックブログにおける執筆ネタの考え方・見つけ方・広げ方 / How to Think of, Find, and Expand Writing Topics for Corporate Tech Blogs
honyanya
0
710
HCP TerraformとAzure:イオンスマートテクノロジーのインフラ革新 / HCP Terraform and Azure AEON Smart Technology's Infrastructure Innovation
aeonpeople
3
880
一人から始めたSREチーム3年の歩み - 求められるスキルの変化とチームのあり方 - / The three-year journey of the SRE team, which started all by myself
vtryo
7
5.1k
SREとしてスタッフエンジニアを目指す / SRE Kaigi 2025
tjun
15
5.4k
第27回クラウド女子会 ~re:Invent 振り返りLT会~ 私の周辺で反響のあった re:Invent 2024 アップデートつれづれ/reinvent-2024-update-reverberated-around-me
emiki
1
570
CNAPPから考えるAWSガバナンスの実践と最適化
nrinetcom
PRO
1
290
Zenn のウラガワ ~エンジニアのアウトプットを支える環境で Google Cloud が採用されているワケ~ #burikaigi #burikaigi_h
kongmingstrap
2
200
アクセシブルなマークアップの上に成り立つユーザーファーストなドロップダウンメニューの実装 / 20250127_cloudsign_User1st_FE
bengo4com
2
1.1k
Enhancing SRE Using AI
yoshiiryo1
1
190
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
3
370
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
GitHub's CSS Performance
jonrohan
1030
460k
How to Ace a Technical Interview
jacobian
276
23k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
11
900
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.2k
Producing Creativity
orderedlist
PRO
343
39k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.2k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.6k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
260
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͍͍ͧ
Ҏ্