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
Stimulus × Jest × Direct Upload × Image Fluxで カ...
Search
Masayoshi Tokumoto
June 29, 2019
Technology
1
350
Stimulus × Jest × Direct Upload × Image Fluxで カオスなJS環境と画像アップロード機能を改善しつつユーザーの投稿率を上げた話
沖縄で開催されたハッカーズチャンプルー2019でLTをした時の資料です
Masayoshi Tokumoto
June 29, 2019
Tweet
Share
More Decks by Masayoshi Tokumoto
See All by Masayoshi Tokumoto
プロダクト・人・チームをいい感じにするためのシステム思考
sasumasa
0
44
RxJS と Netflix から学ぶリアクティブプログラミング
sasumasa
0
24
GraphQL を完全に理解する
sasumasa
0
26
キャパを超えた大型プロジェクトから学んだこと
sasumasa
0
1.3k
RailsエンジニアがStimulus + 生JSだけで約半年のプロジェクトを終えた今思うこと
sasumasa
0
330
IKUSEI on Rails
sasumasa
2
1.9k
文系から半年でRuby(Sinatra, Rails)を学んだら人生変わった@沖縄Ruby会議02
sasumasa
9
19k
Other Decks in Technology
See All in Technology
社外コミュニティで学び社内に活かす共に学ぶプロジェクトの実践/backlogworld2024
nishiuma
0
260
開発生産性向上! 育成を「改善」と捉えるエンジニア育成戦略
shoota
2
330
ハイテク休憩
sat
PRO
2
140
C++26 エラー性動作
faithandbrave
2
730
生成AIのガバナンスの全体像と現実解
fnifni
1
180
10分で学ぶKubernetesコンテナセキュリティ/10min-k8s-container-sec
mochizuki875
3
330
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
150
5分でわかるDuckDB
chanyou0311
10
3.2k
組織に自動テストを書く文化を根付かせる戦略(2024冬版) / Building Automated Test Culture 2024 Winter Edition
twada
PRO
13
3.7k
マルチプロダクト開発の現場でAWS Security Hubを1年以上運用して得た教訓
muziyoshiz
2
2.2k
NW-JAWS #14 re:Invent 2024(予選落ち含)で 発表された推しアップデートについて
nagisa53
0
260
Qiita埋め込み用スライド
naoki_0531
0
4.7k
Featured
See All Featured
Statistics for Hackers
jakevdp
796
220k
Embracing the Ebb and Flow
colly
84
4.5k
Practical Orchestrator
shlominoach
186
10k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
YesSQL, Process and Tooling at Scale
rocio
169
14k
4 Signs Your Business is Dying
shpigford
181
21k
Building Your Own Lightsaber
phodgson
103
6.1k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Transcript
Stimulus × Jest × Direct Upload × Image FluxͰ ΧΦεͳJSڥͱը૾ΞοϓϩʔυػೳΛ
վળͭͭ͠ϢʔβʔͷߘΛ্͛ͨ ·͞ʢ@Masah201707ʣ
ࣗݾհ • ·͞ʢ@Masah201707ʣ • גࣜձࣾΈΜͳͷΣσΟϯάʢ18ଔʣ • ͪΐͬͱॻ͚Δ • Ruby/Rails/JavaScript/Stimulus •
͜Ε͔Βͪΐͬͱॻ͚Δ • React/Go • ͓ञͱ͓ण࢘ͱֶͼʹͳΔٕज़ͷ͕͋Ε͍͍ͩͨͤ
ΈΜͳͷΣσΟϯάͱ • ʮ݁ࠗࣜͷຊΛ͑ΔʯͨΊͷαʔϏε • ϝΠϯίϯςϯπʹ݁ࠗࣜʹؔ͢Δޱίϛɾ࣮ࡍͷඅ༻໌ࡉͳͲ͕͋Δ
ͬͨ͜ͱ Ϣʔβʔߘը૾ͷ ΞοϓϩʔυͷΈΛม͑Δ
Γ͍ͨ͜ͱ • jQueryΛ٫͍ͨ͠ʢͻͲ͍ίʔυͷւ͕͕͓ͬͯ Γɺςετͮ͠Β͍ʣ • ϢʔβʔΛ͍ؒͨͤΔ͜ͱͳ͘࠷େ10ຕͷը૾ ΞοϓϩʔυΛ࣮ݱ͍ͤͨ͞ • Ϣʔβʔ͕Ξοϓϩʔυͨ͠ը૾Λ৭ʑͳίϯςϯπ Ͱ͏ͨΊʹ৭ʑͳαΠζʹม͍ͨ͠
Γ͍ͨ͜ͱ • jQueryΛ٫͍ͨ͠ʢͻͲ͍ίʔυͷւ͕͕͓ͬͯ Γɺςετͮ͠Β͍ʣ • ϢʔβʔΛ͍ؒͨͤΔ͜ͱͳ͘࠷େ10ຕͷը૾ ΞοϓϩʔυΛ࣮ݱ͍ͤͨ͞ • Ϣʔβʔ͕Ξοϓϩʔυͨ͠ը૾Λ৭ʑͳίϯςϯπ Ͱ͏ͨΊʹ৭ʑͳαΠζʹม͍ͨ͠
ղܾࡦ Stimulus + Jest
Stimulus • Basecamp͕ࣾग़͍ͯ͠Δʮ߇͑Ίͳ৺ʯΛ࣋ͬͨϑ ϨʔϜϫʔΫ • HTMLͱJavaScriptΛdataଐੑͰܨ͙ • HTMLΛݟΔ͚ͩͰͲͷΑ͏ͳৼΔ͍Λ͢Δͷ͔͕Θ͔Δ • ಉ͡తͷίʔυΛάϧʔϓԽͤ͞ΔͷͰɺࣗͷίʔυ͕
ʮJavaScriptͷւʯʹຒΕΔͷΛ͙ • DOMͷϥΠϑαΠΫϧΛཧ͢Δ
Jest • FacebookJavaScriptςετπʔϧ • Reactͱͷੑߴͦ͏ • ಋೖָ͕ͦ͏ʢZero Configurationʣ • RSpecΈ͍ͨͰॻ͖ํʹ͠Έ͕͋Δ
const sum = require('./sum'); test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); });
Γ͍ͨ͜ͱ • jQueryΛ٫͍ͨ͠ʢͻͲ͍ίʔυͷւ͕͕͓ͬͯ Γɺςετͮ͠Β͍ʣ • ϢʔβʔΛ͍ؒͨͤΔ͜ͱͳ͘࠷େ10ຕͷը૾ ΞοϓϩʔυΛ࣮ݱ͍ͤͨ͞ • Ϣʔβʔ͕Ξοϓϩʔυͨ͠ը૾Λ৭ʑͳίϯςϯπ Ͱ͏ͨΊʹ৭ʑͳαΠζʹม͍ͨ͠
͜Ε·Ͱͷը૾Ξοϓϩʔυ ΦϦδφϧը૾ͱ αϜωΠϧΛΞοϓϩʔυ • αϜωΠϧը૾ͷ࡞ • EXIFใͷमਖ਼ 1ຕͣͭը૾ΛΞοϓϩʔυ Amazon EC2
Amazon S3
S3ͷDirect Upload ॺ໊͖ͭURLΛ dataଐੑͱͯ͠ηοτ ෳͷը૾Λ ඇಉظͰΞοϓϩʔυ access_key_idͱ secret_access_keyΛऔಘ ̍ ̎
̏ Amazon EC2 Amazon S3 IAM
Γ͍ͨ͜ͱ • jQueryΛ٫͍ͨ͠ʢͻͲ͍ίʔυͷւ͕͕͓ͬͯ Γɺςετͮ͠Β͍ʣ • ϢʔβʔΛ͍ؒͨͤΔ͜ͱͳ͘࠷େ10ຕͷը૾ ΞοϓϩʔυΛ࣮ݱ͍ͤͨ͞ • Ϣʔβʔ͕Ξοϓϩʔυͨ͠ը૾Λ৭ʑͳίϯςϯπ Ͱ͏ͨΊʹ৭ʑͳαΠζʹม͍ͨ͠
ैདྷͷߏ • ը૾มͷ͘͠Έ • ϦαΠζɾΫϩοϓɾը࣭ͷௐΩϟογϡػೳΛඋ͑Δ
ैདྷͷߏ • ɿӡ༻͕ൃੜ • ϛυϧΣΞͷߋ৽ΞϥʔτରԠ
S3ͷDirect Upload ॺ໊͖ͭURLΛ dataଐੑͱͯ͠ηοτ ෳͷը૾Λ ඇಉظͰΞοϓϩʔυ access_key_idͱ secret_access_keyΛऔಘ ̍ ̎
̏ Amazon EC2 Amazon S3 IAM &9*'ใΛ मਖ਼͍ͯ͠ͳ͍
ImageFluxͱ ̍ຕͷը૾Λͱʹը૾ͷ֦େॖখɺΓൈ͖ɺ߹ͳͲͰσ όΠεʹ࠷దԽ͞Εͨը૾Λ؆୯ʹੜ͠ɺߴ͔ͭߴ࣭Ͱ ৴͢ΔαʔϏε
ImageFluxར༻ޙͷߏ ը૾ॲཧΛ·ΔͬͱImageFluxʹ͓ͤ͢Δ͜ͱ Ͱը૾पΓͷӡ༻͔Βղ์͞ΕΔ
݁Ռ • ը૾ͷߘ 1.7ഒ • 30595ຕˠ52622ຕ ϦϦʔεޙ4ϲ݄ͷ૯ը૾ߘΛલಉ݄ͱൺֱ • मਖ਼֦ுʹڧ͍ઃܭʹͳͬͨ
ࣦഊஊ
Vanilla JSͷDOMੜ _createThumbnailField(data) { const thumbnailFieldList = document.querySelector(`.js_${this.category}-thumbnail-field-list`) const thumbnailFieldWrapper
= document.createElement('div') thumbnailFieldWrapper.dataset.controller = 'string-counter' thumbnailFieldWrapper.dataset.target = 'thumbnail-field.item' thumbnailFieldWrapper.dataset.stringCounterMax = 20 thumbnailFieldWrapper.className = 'post-pictures-attachments' const thumbnailFieldBackground = document.createElement('div') thumbnailFieldBackground.className = 'os1-container-background' thumbnailFieldBackground.classList.add('-background-color-gold') thumbnailFieldBackground.classList.add('-margin-bottom-M') const hiddenObjectKey = this.createHiddenObjectKey(data.objectKey) const hiddenCategory = this.createHiddenCategory() const hiddenContentType = this.createHiddenContentType('review') this._createReviewThumbnailField({ data, thumbnailFieldBackground, hiddenObjectKey, hiddenContentType, hiddenCategory, }) thumbnailFieldWrapper.appendChild(thumbnailFieldBackground) thumbnailFieldList.appendChild(thumbnailFieldWrapper) }
_createThumbnailField(data) { const thumbnailFieldList = document.querySelector(`.js_${this.category}-thumbnail-field-list`) const thumbnailFieldWrapper = document.createElement('div')
thumbnailFieldWrapper.dataset.controller = 'string-counter' thumbnailFieldWrapper.dataset.target = 'thumbnail-field.item' thumbnailFieldWrapper.dataset.stringCounterMax = 20 thumbnailFieldWrapper.className = 'post-pictures-attachments' const thumbnailFieldBackground = document.createElement('div') thumbnailFieldBackground.className = 'os1-container-background' thumbnailFieldBackground.classList.add('-background-color-gold') thumbnailFieldBackground.classList.add('-margin-bottom-M') const hiddenObjectKey = this.createHiddenObjectKey(data.objectKey) const hiddenCategory = this.createHiddenCategory() const hiddenContentType = this.createHiddenContentType('review') this._createReviewThumbnailField({ data, thumbnailFieldBackground, hiddenObjectKey, hiddenContentType, hiddenCategory, }) thumbnailFieldWrapper.appendChild(thumbnailFieldBackground) thumbnailFieldList.appendChild(thumbnailFieldWrapper) } Vanilla JSͷDOMੜ THIS IS ZIGOKU
ϦΞϧDOMͰԾʢతʣDOM 1. ςϯϓϨʔτΛViewϑΝΠϧʹஔ͍͓ͯ͘ 2. MutationObserverͰಛఆͷHTMLཁૉΛࢹ 3. ը૾ΞοϓϩʔυޙʹඞཁͳใΛͦͷHTMLཁૉͷ attributesͱͯ͠ηοτ 4. MutationObserver͕Ԡ͠ɺςϯϓϨʔτͷCloneʹͦ
ΕͧΕͷΛೖΕͨͷΛAppend
ՆͷΠϯλʔϯγοϓ ։࠵͠·͢ʂ
ΈΜͳͷΣσΟϯά ՆͷΠϯλʔϯ in ԭೄ ࣌ɿ8݄22ɾ23ʢ༧ఆʣ ձɿླྀٿେֶֶ෦ ࣮ࡍͷαʔϏεʹػೳΛՃͯ͠ RubyͱRailsͷجຊΛֶ΅͏ʂ ৄ͘͠connpass (https://mwed.connpass.com/)
Ͱ 21ଔ͚
͋Γ͕ͱ͏͍͟͝·ͨ͠