Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
repost-oss
Hiroki Zenigami
September 28, 2017
Programming
1
800
repost-oss
Hiroki Zenigami
September 28, 2017
Tweet
Share
More Decks by Hiroki Zenigami
See All by Hiroki Zenigami
文章を書く前に決めるべき3つのこと / How to plan document
zenizh
0
120
小さいチームでRailsアプリをつくるならMountable Engineがいいよ、というはなし / Mountable Engine for Small Team
zenizh
0
490
コアバリューをとおしたサービス開発 / Core-Value Driven Development
zenizh
1
300
RailsでOSSのWebアプリケーションを書くための"ことはじめ" / rails-oss-startup-guide
zenizh
2
210
Other Decks in Programming
See All in Programming
Cloudflare WorkersでGoのHTTPサーバーを動かすライブラリを作った話
syumai
0
150
kintoneでランダム取得を作ってみた(imoniCamp 2022-07-27)
shokun1108
0
140
YATA: collaborative documents and how to make them fast
horusiath
1
160
Getting Started With Data Structures
adoranwodo
1
260
回帰分析ではlm()ではなくestimatr::lm_robust()を使おう / TokyoR100
dropout009
0
4.5k
ZOZOTOWNにおけるDatadogの活用と、それを支える全社管理者の取り組み / 2022-07-27
tippy
1
3.2k
WindowsコンテナDojo: 第4回 Red Hat OpenShift Localを使ってみよう
oniak3ibm
PRO
0
180
読みやすいコード クラスメソッド 2022 年度新卒研修
januswel
0
2.9k
Register-based calling convention for Go functions
cjamhe01385
0
400
ベストプラクティス・ドリフト
sssssssssssshhhhhhhhhh
1
210
リーダブルテストコード / #vstat
jnchito
47
35k
Google I/O 2022 Android関連概要 / Google I/O 2022 Android summary
phicdy
0
380
Featured
See All Featured
Build The Right Thing And Hit Your Dates
maggiecrowley
19
1.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
29
4.4k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
119
28k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
237
19k
Streamline your AJAX requests with AmplifyJS and jQuery
dougneiner
127
8.5k
A Philosophy of Restraint
colly
192
15k
Gamification - CAS2011
davidbonilla
75
3.9k
Adopting Sorbet at Scale
ufuk
63
7.6k
A better future with KSS
kneath
226
16k
It's Worth the Effort
3n
172
26k
The Invisible Side of Design
smashingmag
290
48k
YesSQL, Process and Tooling at Scale
rocio
157
12k
Transcript
3BJMTͰใڞ༗ΞϓϦέʔγϣϯΛ 044ͱͯ͠։ൃ͍ͯ͠Δ 3BJMT%FWFMPQFST.FFUVQ મਆ༟ٓʢ!LBNJ@[Iʣ
ൃදΛͱ͓ͯ͠ͷඪ w 3FQPTUͷ։ൃΛͱ͓ͨ͠ݟΛͱʹ 3FEVY 8FCQBDLFS FUD w 3BJMTΞϓϦͷ։ൃܦݧ͋Δ͚Ͳ41"ະܦݧͷํΛରʹ w 3BJMTº41"ͷ։ൃࣄྫʹ৮ΕͯΒ͏͜ͱ
2
ࣗݾհ w મਆ༟ٓʢͥʹ͕ΈͻΖ͖ʣ w !LBNJ[I!LBNJ@[I w גࣜձࣾສ༿ٕज़։ൃ෦ w ۽ຊग़ʢߴઐɾઐ߈Պ·ͰʣେֶӃ͔Βઍ༿ʙ౦ژ w
৽ଔ͔Βؒ8FCαʔϏεͷ6*ઃܭاըͳͲΛ୲ w ʙલ͔ΒΤϯδχΞʹΫϥενΣϯδ 3
None
͞·͟·ͳऔΓΈʢൈਮʣ w 3VCZίϛϡχςΟͷεϙϯαʔυ 3VCZ,BJHJ 38$ 3BJMT(JSMT FUD w ΧϯϑΝϨϯεͷࢀՃඅࢧԉ 3VCZ,BJHJ!ౡෛ୲ͳ͘ࢀՃͰ͖ͨ
w ։ൃίϯςετ ۀ࣌ؒࣾϦιʔεΛ͔ͭͬͯ։ൃͰ͖ͨ 5
࣍ 3FQPTUͱ 3FQPTUͷσʔλϑϩʔ 3BJMT ͱ3FQPTU ͨ͜͠ͱ
ল 6
όʔδϣϯใʢݱࡏʣ w 3FQPTUW w 3VCZW w 3VCZPO3BJMTW
w 8FCQBDLFSW w 3FEVYW 7
3FQPTUͱ
3FQPTU IUUQTHJUIVCDPNLBNJ[ISFQPTU
3FQPTUͱ w Φʔϓϯιʔεͷใڞ༗ΞϓϦέʔγϣϯʢWʣ w .BSLEPXOͰॻ͚ΔʢϦΞϧλΠϜϓϨϏϡʔʣ w ֆจࣈʹΑΔϦΞΫγϣϯػೳ w νϟϯωϧػೳ ͱ͋ΔνʔϜͷϝϯόʔ͚ͩͷߘΛදࣔͰ͖Δ
w Α͋͘Δػೳ هࣄͷετοΫ 4MBDL࿈ܞ ݖݶཧ FUD 10
None
None
None
࣮͍ͨ͠ػೳҰཡ w ίϝϯτػೳ w ௨ػೳ w هࣄதͷֆจࣈϦϓϥΠɺը૾ʹରԠ %SBGU+41MVHJOT w ଟݴޠରԠ
w ݕࡧػೳ w %FQMPZUP)FSPLV 14
3FQPTUͷσʔλϑϩʔ 3FEVY 3BJMTͰ41"Λઃܭ͢ΔࡍͷࢀߟʹMMMMMMMM
ᶃ 7JFX͕มԽ͢Δ"DUJPO͕࣮ߦ͞ΕΔ ᶄ ඞཁʹԠͯ͡"1*ʹϦΫΤετΛૹΔ ᶅ 3FEVDFSͷఆٛʹ͕ͨͬͯ͠4UPSFͷ4UBUF͕มԽ͢Δ ᶆ ͜ͷ4UBUFΛߪಡ͍ͯ͠Δ7JFX͕ߋ৽͞ΕΔ 16 7JFX
"DUJPOT %JTQBUDIFS .JEEMFXBSFT "1* 4UPSF 3FEVDFST 3VCZPO3BJMT 3FEVY ᶃ ᶄ ᶅ ᶆ
۩ମྫ w ྫɿ֎෦αʔϏε࿈ܞʢ࣮͕࠷γϯϓϧͩͬͨʣ w આ໌͍͢͠Α͏࣮ࡍͷίʔυΛมߋɾলུ͍ͯ͠·͢ 17 app/ controllers/ api/ └─
services_controller.rb javascript/ actions/ └─ servicesActions.js features/ └─ Services.jsx reducers/ └─ services.js
None
7JFX "DUJPOT %JTQBUDIFS .JEEMFXBSFT "1* 4UPSF 3FEVDFST 3VCZPO3BJMT
3FEVY
w ࿈ܞதͷ֎෦αʔϏεҰཡΛදࣔ͢Δ$POUBJOFS$PNQPOFOU هࣄߘ࣌ͷ௨ઌ4MBDLͳͲ w componentDidMount()͔ΒΞΫγϣϯΛ࣮ߦ͍ͯ͠Δ 3FBDUͷϥΠϑαΠΫϧ 20 import * as
servicesActions from '../actions/servicesActions' class Services extends Component { componentDidMount() { this.props.fetchServices() } } function mapDispatchToProps(dispatch) { return bindActionCreators(servicesActions, dispatch) } BQQKBWBTDSJQUGFBUVSFT4FSWJDFTKTY
7JFX "DUJPOT %JTQBUDIFS .JEEMFXBSFT "1* 4UPSF 3FEVDFST 3VCZPO3BJMT
3FEVY
w 7JFX͔ΒݺΕΔ"DUJPO w ࣍ͷΑ͏ͳܗͰ"1*ʹର͢ΔϦΫΤετΛఆٛ w )551ΫϥΠΞϯτ༻ͷϛυϧΣΞΛಋೖ͍ͯ͠Δ SFEVYBYJPTNJEEMFXBSF 22 export function
fetchServices() { return { type: 'FETCH_SERVICES', payload: { request: { url: '/api/services.json' } } } } BQQKBWBTDSJQUBDUJPOTTFSWJDFT"DUJPOTKT
7JFX "DUJPOT %JTQBUDIFS .JEEMFXBSFT "1* 4UPSF 3FEVDFST 3VCZPO3BJMT
3FEVY
w "1*3BJMTͰ࣮͢Δ w ϞσϧΛͱ͓ͯ͠࿈ܞதͷ֎෦αʔϏεҰཡΛऔಘ ࿈ܞଟ͘ͳΒͳ͍͜ͱΛఆͯ͠.allͰऔಘ w +CVJMEFSʹΑΓ7JFX͕ඞཁͱ͢ΔใΛ+40/ܗࣜͰฦ͢ 24 class Api::ServicesController
< Api::ApplicationController def index @services = Service.all # JbuilderͰJSONΛฦ͢ end end BQQDPOUSPMMFSTBQJTFSWJDFT@DPOUSPMMFSSC
7JFX "DUJPOT %JTQBUDIFS .JEEMFXBSFT "1* 4UPSF 3FEVDFST 3VCZPO3BJMT
3FEVY
w 3FEVDFS4UPSFͷ4UBUFͷมԽΛఆٛͨؔ͠ w ϦΫΤετ͕ޭͨ͠߹_SUCCESSͱ͍͏ඌ͕͍ࣙͭͨ λΠϓ͕ฦ٫͞ΕΔ SFEVYBYJPTNJEEMFXBSFͷ;Δ·͍ w "1*ͷϨεϙϯε͕4UBUFʹอ࣋͞ΕΔ ͜ͷ߹࿈ܞதͷ֎෦αʔϏεҰཡ 26
function services(state = initialState, action) { switch (action.type) { case 'FETCH_SERVICES_SUCCESS': return action.payload.data // ࿈ܞதͷαʔϏεҰཡ default: return state } } BQQKBWBTDSJQUSFEVDFSTTFSWJDFTKT
7JFX "DUJPOT %JTQBUDIFS .JEEMFXBSFT "1* 4UPSF 3FEVDFST 3VCZPO3BJMT
3FEVY
w 4UBUFΛ1SPQTʹϚοϓ w 4UBUF͕มԽ͢Δͱίϯϙʔωϯτʹ͢ύϥϝʔλมԽ͢Δ 7JFX͕ߋ৽͞ΕΔ 28 class Services extends Component
{ render() { return ( <div> <ServiceList services={this.props.services} /> </div> ) } } function mapStateToProps(state) { return { services: state.services } } BQQKBWBTDSJQUGFBUVSFT4FSWJDFTKTY
͜͜·Ͱͷ·ͱΊ w 7JFX"DUJPO"1*3FEVDFS7JFX w 'MVYΞʔΩςΫνϟͷ֓೦Λཧղ͢Δඞཁ͕͋Δ 3FQPTUͰ͍͏ͱ3FEVYͷΈ w σʔλϑϩʔ͕୯ํͳͷͰઃܭ͍͢͠ w "1*3BJMTͷࢿ࢈Λ͑Δ
29
ʢࢀߟʣ.BTUPEPO IUUQTHJUIVCDPNUPPUTVJUFNBTUPEPO w 3BJMTΞϓϦͰ3FEVY 3FBDUΛ࠾༻ w app/javascriptԼͷߏpackage.json͕ࢀߟʹͳΔ ˞ 41"Ͱͳ͍ 30
3BJMT ͱ3FQPTU
8FCQBDLFS w +BWB4DSJQUΞϓϦέʔγϣϯΛ3BJMTͰཧ͢ΔͨΊͷ 8FCQBDLΛ༻͍ͨπʔϧ w 3FQPTU"1*Λ3BJMTɺϑϩϯτΤϯυΛ3FEVY 3FBDU w Ͳ͏ͬͯ͜ͷڥΛߏங͢Δ͔ 3BJMTͰಋೖ͞Εͨ8FCQBDLFS:BSOʹΑΓγϯϓϧʹ࿈ܞͰ͖Δ
32
w rails new͢Δͱ͖ʹ--webpack=reactΦϓγϣϯΛ͚ͭΔ webpacker:installyarn install͕Δ w ͜ͷ࣌Ͱ3FBDUͷͻͳܗ͕Ͱ͖͍ͯΔ w ඞཁʹԠͯ͡reduxͳͲͷϥΠϒϥϦΛΠϯετʔϧ͢Δ yarn
addͰΠϯετʔϧ w ։ൃ࣌webpack-dev-serverΛ࣮ߦ͢Δ ίʔυมߋ࣌ʹ)PU.PEVMF3FQMBDFNFOUͯ͘͠ΕΔ 33 $ rails new foo --webpack=react $ bin/yarn add redux react-redux react-router-redux ... $ bin/webpack-dev-server
w &4ΛτϥϯεύΠϧ͢ΔͨΊͷ#BCFMͷઃఆ͋Δ w ܥଟ͘ͷઃఆ͕ϥΠϒϥϦଆʹٵऩ͞Εͨ ΞϓϦέʔγϣϯଆͷઃఆΛγϯϓϧʹอͯΔ w 3FQPTUͷ8FCQBDLFS·ͩܥ ΧελϚΠζΛ͍ͯ͠Δ͜ͱ͋ΓઃఆϑΝΠϧ͕ଟ͍ 34
w 8FCQBDLFSͰϏϧυͨ͠ϑΝΠϧΛ 8FCQBDLFSͷjavascript_pack_tagΛͱ͓ͯ͠ಡΉ w ݟͨͯ͢+BWB4DSJQU 35 <!DOCTYPE html> <html> <head>
<title>Repost</title> <%= stylesheet_pack_tag 'application' %> </head> <body> <%= javascript_pack_tag 'application' %> </body> </html> BQQWJFXTMBZPVUTBQQMJDBUJPOIUNMFSC
:BSO w +BWB4DSJQUͷύοέʔδཧπʔϧ w 3BJMT͔Β:BSOΛαϙʔτ w ύοέʔδͷґଘཧɺΠϯετʔϧͷߴԽɺηΩϡΞԽͳͲ OQNͱͷൺֱ w ؔΘΔΠϯλϑΣʔεinstalladdremove͘Β͍
8FCQBDLFSͱ:BSOʹΑΓ+BWB4DSJQUͷΤίγεςϜΛ ಋೖ͢Δͷ͕ͱͯ؆୯ʹͳͬͨʢ3FEVYͳͲʣ 36
"DUJPO%JTQBUDI4ZTUFN5FTU$BTF w 3BJMT͔Βఏڙ͞Εͨɺ&&ςετΛ࣮ߦ͢ΔͨΊͷΫϥε w ෦Ͱ$BQZCBSB%4-ͳͲΛΠϯΫϧʔυ w τϥϯβΫγϣϯཧΛͯ͘͠ΕΔ σʔλϕʔεͷΫϦΞͳͲͷઃఆ͕ෆཁ w 3BJMTͷϨʔϧʹͬͨ··
+BWB4DSJQUΛؚΜͩϖʔδͷ&&ςετ·Ͱॻ͚Δ 3BJMTͰͷ41"։ൃ͕ΑΓεϜʔζʹ 37
ʢࢀߟʣ.JOJUFTU3FUSZ IUUQTHJUIVCDPNZZBHJNJOJUFTUSFUSZ w &&ςετ͕$*্Ͱͨ·ʹམͪΔʢ3FCVJME͢Δͱύε͢Δʜʜʣ ೝূʹ༻͍ΔใΛϩʔΧϧετϨʔδʹ֨ೲ͍ͯ͠Δ w ςετέʔε͕ࣦഊͨ͠ͱ͖ʹࢦఆճϦτϥΠͯ͘͠ΕΔ w 3FQPTUͷςετ.JOJUFTU w
͜ͷϥΠϒϥϦͷ͓͔͛Ͱ҆ఆͨ͠ ࠜຊతͳղܾΛ͍ͨ͠ 38
ͨ͜͠ͱ
ςετΛॻ͘ର w ࣍ͷςετΛ͔ͬ͠Γॻ͍ͨ w 3BJMTͷϢχοτςετʢϞσϧ"1*ʣ w &&ςετ w +BWB4DSJQUͷϢχοτςετॻ͔ͳ͔ͬͨ 3FEVY4UBUFΛཧ͢ΔίϯςφҎ֎७ؔςετ͍͢͠
Ћ൛ͳͷͰ6*Λࢼߦࡨޡ͍ͨ͠&&ςετͰཏ 40
w ςετΛॻ͘ͱେ෯ͳϦϑΝΫλϦϯάΛ҆৺ͯ͠Ͱ͖Δ +BWB4DSJQUͷߏɺ3FEVDFSͷઃܭͳͲͷݟ͕ͳ͔ͬͨ ࢼߦࡨޡ͕ඞཁͳͱ͜ΖϦϑΝΫλϦϯά͕ଟ͘ͳΔ ςετΛ͔ͬ͠Γॻ͍͓ͯ͘ͱΑͦ͞͏ʁͱߟ͑ͨ w ͨͱ͑͜ΜͳϦϑΝΫλϦϯάΛͯ͠;Δ·͍͕อূ͞ΕΔ
41
4QSPDLFUTআͨ͠ w ͦΕͧΕͷ୲ൣғ w 8FCQBDLFS+BWB4DSJQUΞϓϦέʔγϣϯΛཧ w 4QSPDLFUT3BJMTͷίϯτϩʔϥϏϡʔ͝ͱͷΞηοτΛཧ "TTFU1JQFMJOFͰ࿈݁ w 3FQPTU41"ͳͷͰ4QSPDLFUTඞཁͳ͔ͬͨ
w ΞϓϦέʔγϣϯͷੑ࣭ʹԠͯ͡બ͋Δ͍Έ߹ΘͤΔ ྫɿ3FEVYͱ3BJMTͷϏϡʔ͕ڞଘ͢ΔՄೳੑ͋Δ 42
ηοτΞοϓΛָʹ͢Δ w bin/setup bin/updateΛϝϯςφϯε͢Δ w େ͞Μʢ!POLʣͷεϥΠυͰͬͨ w ;ͭ͏ͷ3BJMTΞϓϦέʔγϣϯ։ൃ IUUQTXXXTMJEFTIBSFOFUUBLBGVNJPOBLBSBJMT w
git clone/pullͨ͠ޙʹ͜ΕΛୟ͚ͩ͘Ͱͯ͢ͷ४උ͕͏ 43
w 3FQPTU044 w ίϯτϦϏϡʔτͷҙࢥΛͬͨਓ͕͙͢ʹ։ൃΛ͡ΊΒΕΔ ڥΛఏڙ͢Δ͜ͱ͕ॏཁͩͱߟ͑ͨ 44
w ؔ࿈͢Δ13Λཱͯͨ IUUQTHJUIVCDPNSBJMTSBJMTQVMM w BTTJHOFF͕!EIIͳͷͰݫͦ͠͏ʜʜ
45
ল
Ϟʔμϧ৻ॏʹಋೖ͢Δ w 4UBUFͷཧͰ࣮͕ෳࡶʹͳΔ ྫɿϑΥʔϜɺλϒ w &&ςετ͕ॻ͖ͮΒ͍ɾ͘ͳΔ ྫɿϞʔμϧΛ։͘ɺͱ͍͏ΞΫγϣϯ͕ඞཁʹͳΔ w Ϟʔμϧͩͱ͍ͮΒ͍έʔε͋Δ ྫɿด͡Δɺͱ͍͏ΞΫγϣϯ͕ඞཁ
47
w ࠷ॳઃఆؔ࿈Λͯ͢ϞʔμϧͰ࣮͍ͯͨ͠ ్தͰͯ͢ॻ͖ͨ͠ ςετΛ͔ͬ͠Γॻ͍͓ͯ͘ͱॻ͖҆͠৺ͯ͠Ͱ͖Δ w ͦͷػೳ͕ຊʹϞʔμϧͰͳ͚ΕͳΒͳ͍͔ߟ͑Δ 48
3BJMTͷࢿ࢈Λ׆༻͢Δ w ࢿ࢈ɿ5VSCPMJOLT'PSN)FMQFSͳͲ w 3FQPTUͷߏ3FEVY 3FBDUͰ41"ʢษڧͷͨΊʣ w ઃఆը໘ͳͲɺ࣮͔͔Δ͕༻ස͕͍ػೳଟ͍ ͪΖΜ։ൃऀͷεΩϧʹΑΔ 49
w 5VSCPMJOLT'PSN)FMQFSͳͲͷ׆༻Λݕ౼͢Δ هࣄͷҰཡදࣔɺߘίϯϙʔωϯτ3FEVYͰΑͦ͞͏ .BTUPEPOϋΠϒϦουܕʢઃఆͳͲΛ3BJMTଆͰ͍ͬͯΔʣ 50
༨ஊ
Ϟνϕʔγϣϯͷอͪํ
w தଜ͞Μʢ!SLBNVSBʣͷεϥΠυ w ݸਓ։ൃͷ͍͖ͬͯํ IUUQTTQFBLFSEFDLDPNSLBNVSBHFSFOLBJGBGBMTFZBUVUFJLJGBOH w ΤλΒͳ͍ͨΊʹ ΤλΒͳ͍ϞνϕʔγϣϯΛอͪଓ͚Δ w ࣗʹͱͬͯͳʹ͕։ൃͷϞνϕʔγϣϯͳͷ͔Λ
ݟग़͢͜ͱ͕ॏཁ 53
w ࠷৽ͷ3BJMTͷػೳΛࢼ͢ͱͯ͠͏ w స৬׆ಈͷͱ͖ʹ໊ΘΓʹ͏ 54
w ࢲͷ߹తཉٻۦಈ։ൃ w ֶ͕ࣗͼ͍ٕͨज़Λ࠾༻͢Δ͍Βͳ͘ͳͬͨΒফ͢ w ීٴͨ͠ΒελοΫΛબఆ͢Δඞཁ͕͋Δ͕ɺͦΕ·Ͱ ͭ͘Γ͍ͨΑ͏ʹͭ͘Δ 55
None
w 8FCαʔϏεͱͯ͠ެ։ͨ͠ͷ͍͔ͭ͋͘Δ w ๏ܦཧͳͲ͕໘ٛײ͕ੜ·Εͨ w 044ͩͱ͕͠ΒΈ͕ͳ͍ 57
w ϞνϕʔγϣϯਓͦΕͧΕҧ͏ w ࣗͷϞνϕʔγϣϯ͕ͳʹ͔Λߟ͑ɺͦΕΛ࣠ʹ ։ൃ͢ΔͱΑͦ͞͏ w ࠓΓ͍ͨͷ5ZQF4DSJQUɺ"DUJWF4UPSBHFͳͲ 58
·ͱΊ
w 3BJMTͰͷ41"3BJMT Ͱ։ൃ͘͢͠ͳͬͨ 8FCQBDLFS :BSO w "DUJPO%JTQBUDI4ZTUFN5FTU$BTFʹΑΓ41"ͷςετ Ϩʔϧʹͬͨ··ॻ͚Δ w +BWB4DSJQUͰॻ͔͘ɺ3BJMTͷࢿ࢈Λ׆༻͢Δ͔
͔ͬ͠Γͱݕ౼͢Δ 60
3FQPTU IUUQTHJUIVCDPNLBNJ[ISFQPTU