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
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Shinichi Maeshima
October 16, 2018
Technology
4.7k
0
Share
stimulus
ginza.rb#64 でstimulusを紹介したときに使った資料です
https://ginzarb.doorkeeper.jp/events/81390
Shinichi Maeshima
October 16, 2018
More Decks by Shinichi Maeshima
See All by Shinichi Maeshima
メタプログラミングRuby問題集の活用
willnet
2
1.6k
rails g authenticationから学ぶRails8.0時代の認証
willnet
5
5k
What's a well-behaved Rails extension gem?
willnet
0
830
Sidekiq vs Solid Queue
willnet
15
14k
どうしてこうなった?から理解するActive Recordの関連の裏側
willnet
6
1.6k
Exceptional Rails
willnet
6
8.2k
Breaking the Flaky Test Cycle
willnet
2
2.4k
mrskで広がるインフラの選択肢
willnet
1
1.2k
アプリケーションを長期にわたって無理なく運用するためのたったひとつの方法
willnet
2
2.3k
Other Decks in Technology
See All in Technology
Anthropic「Long-running a gents」をGeminiで再現してみた
tkikuchi
0
730
AI時代における技術的負債への取り組み
codenote
1
2k
Pure Intonation on Browser: Building a Sequencer with Ruby
nagachika
0
340
AI와 협업하는 조직으로의 여정
arawn
0
560
AIはハッカーを減らすのか、増やすのか?──現役ホワイトハッカーから見るAI時代のリアル【MEGU-Meet】
cscengineer
PRO
0
240
Arcana: Production-Ready RAG in Elixir @ ElixirConf EU 2026
georgeguimaraes
0
120
小説執筆のハーネスエンジニアリング
yoshitetsu
0
870
AIでAIをテストする - 音声AIエージェントの品質保証戦略
morix1500
1
150
GitHub Copilot CLI と VS Code Agent Mode の使い分け
tomokusaba
0
110
20年前の「OSS革命」に学ぶ AI時代の生存戦略
samakada
0
510
VespaのParent Childを用いたフィードパフォーマンスの改善
taking
0
150
Route 53 Global Resolver で高額課金発生!
otanikohei2023
0
130
Featured
See All Featured
What's in a price? How to price your products and services
michaelherold
247
13k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.3k
Why Our Code Smells
bkeepers
PRO
340
58k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
290
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
180
SEO for Brand Visibility & Recognition
aleyda
0
4.5k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
750
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
64
54k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1k
Technical Leadership for Architectural Decision Making
baasie
3
340
Abbi's Birthday
coloredviolet
2
7.3k
Crafting Experiences
bethany
1
130
Transcript
stimulus — ginza.rb#64 — @willnet
とは — Stimulus: A modest JavaScript framework for the HTML
you already have. — Basecamp製のJSフレームワーク — 現在のバージョン1.1.0(2018/8/23)
試用 — webpackなどでプリコンパイルするのを推奨 — cloneしてサッと試せるお試し用リポジトリがある — stimulusjs/stimulus-starter: A humble blank
slate for a modest JavaScript framework — rails使いなら rails new --webpack=stimulus yourappname でも環境作れるのでそっちでもよさそう — 公式チュートリアル的なのがあるので、それを見ながら手 を動かすとよいのでは
特徴 — react や vue.js とは志向がぜんぜん違う — データバインディングとかVirtual DOMとか、なにそれ 美味しいの?って感じ
— あくまでサーバが吐くHTMLと仲良くするためのフレーム ワーク — turbolinks friendly — サーバサイドの人が片手間でやるフロントエンドで、 vue.jsなどを導入する余裕がない…みたいなときに導入す るのが良いのでは、という気がする — 現行のjsを整理するために使う
どういうときに便利そうか — 通常RailsのJSはファイルごとにそれっぽく関数やイベント 登録などが整理されるけれど、特に強制力はない — なのでフラットにイベントが登録されたり、関数が登録 されたりする可能性がある — 例えば users.js
に user とあまり関係ない関数が 登録されたりする — DOMのclass属性とjsが紐付けられる事が多いけど、cssのた めに使うclassなのかjsで使うclassなのか分かりづらい — stimulusを使うとDOMに controller, target, action を割 り振ることができ、規約によって関数群を整理できる、と いうのがstimulusのキモの一つ(だと思う)
どういうときに便利そうか — turbolinksを使っているときに、特定のページでだけ実行 したい処理を書くのが面倒 — 特定のDOMがあるかチェックして、なかったらreturnす る、みたいな処理を毎回書く — だるい
こういうやつ $(document).on('ready turbolinks:load', () => { const target = $('.condition_transfer_on')
if (target.length === 0) { return } // .condition_transfer_on͕͋ͬͨ߹ͷॲཧ — stimulusを使うと「controllerがページ表示されたタイミ ング(connectされたタイミング)でなにか処理を実行する」 みたいなのが楽にかける
controller, target, action とは stimulus 公式のトップページを見ながら解説するとわかりや すそう Stimulus: A modest
JavaScript framework for the HTML you already have.
HTMLのコード <div data-controller="hello"> <input data-target="hello.name" type="text"> <button data-action="click->hello#greet"> Greet </button>
<span data-target="hello.output"> </span> </div>
jsのコード import { Controller } from "stimulus" export default class
extends Controller { static targets = [ "name", "output" ] greet() { this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!` } }
結果 名前を入力してGreet!をクリックすると、右側に名前を含んだ 文字列が出力される
HTMLとjsの対応付け — data-controllerの値とjsファイル名が紐付いている — data-actionの値とメソッドが紐付いている — data-targetの値とstatic targets = []
で定義された値が 紐付いている — static targets = ["name"] などとすると、 this.nameTarget でDOMの要素を扱うことができるよう になる
stimulusの大まかな機能は これだけ
完?
それぞれもうちょっと詳し く
controller — html中のdata-controllerに合わせて、紐付いた名前の controllerをインスタンス化し、DOMと紐づけてくれる — 例えば<div data-controller="hello"> であれば hello-controller.jsが自動的に読み込まれる —
ファイル名にアンダースコアを使うこともできる — date_picker_controller.js -> date-picker — 参考: https://stimulusjs.org/handbook/ installing#controller-filenames-map-to- identifiers
複数のコントローラを一つのDOMに紐付けること ができる <div data-controller="clipboard list-item"></div>
コントローラを複数のDOMに紐付けることができ る <ul> <li data-controller="list-item">One</li> <li data-controller="list-item">Two</li> <li data-controller="list-item">Three</li> </ul>
li要素それぞれに、別々のコントローラのインスタンスが割り 当てられる
action <div data-controller="gallery"> <button data-action="click->gallery#next">…</button> </div> — イベントの名前(click) — コントローラ名(garraly)
— アクション名(next) をそれぞれ指定する
eventオブジェクト actionとして定義されたメソッドに、eventオブジェクトが引 数として渡ってくる import { Controller } from "stimulus" export
default class extends Controller { next(event) { // … } }
eventオブジェクト — event.type でなんのイベントなのかが返る(例: 'click') — event.targetでどのDOM発祥なのか返る — event.currentTargetでイベントリスナが登録されている DOMが返る
イベントの名前 — DOM要素によっては省略できる — 例えばa要素ならclickがデフォルトで省略可能
同じDOMに複数イベント登録できる <input type="text" data-action="focus->field#highlight input->search#update">
target Action以外のDOMとjsの紐づけはtargetでやる
html <div data-controller="search"> <input type="text" data-target="search.query"> <div data-target="search.errorMessage"></div> <div data-target="search.results"></div>
</div> controller໊.target໊ で指定する
js import { Controller } from "stimulus" export default class
extends Controller { static targets = [ "query", "errorMessage", "results" ] // … } — statis targets に配列でtargetになる要素の名前を渡す — すると後述のプロパティが生える
プロパティ 例えばqueryという名前のtargetを指定すると次のプロパティ が自動で生える — this.queryTarget — 最初にマッチしたDOMが返る — this.queriesTarget —
マッチしたDOMが全部返る — this.hasQueryTarget — DOMが存在しているのかbooleanで返る
一つのDOMに複数のtargetを指定できる <form data-controller="search checkbox"> <input type="checkbox" data-target="search.projects checkbox.input"> <input type="checkbox"
data-target="search.messages checkbox.input"> … </form>
Data Maps <div data-controller="content-loader" data-content-loader-url="/messages"> </div> — 状態をどこで持つのか、という話 — 他のjsフレームワークはjsで持つけど、stimulusjsはDOMで
持つ — html側からjs(その逆も)になにかデータを渡すとき、data- ίϯτϩʔϥ໊-σʔλ໊で渡すというのがstimulusjsでの お作法
js // controllers/content_loader_controller.js import { Controller } from "stimulus" export
default class extends Controller { connect() { fetch(this.data.get("url")).then(/* … */) } } — this.data.get("url")でdata-content-loader-urlの値を取 得できる
その他のメソッド — this.data.set(key, value) — DOMの方にデータを設定する — this.data.has(key) — booleanで、そのkeyのdataが存在しているのか返す
— this.data.delete(key) — keyに紐づくdataを消す
注意点 — dataはNumberでアサインしても、getするとStringで返って くる — とくに型変換とかはしてないもよう this.data.set("count", 1) this.data.get("count") //
"1"
Lifecycle Callback controllerのインスタンスがDOMに割り当てられたときなどに hookしてメソッド実行をさせることができる import { Controller } from "stimulus"
export default class extends Controller { connect() { // … } }
メソッド — initialize — controllerのインスタンスが作られたタイミング — connect — DOMに紐付いたタイミング —
ドキュメント上にdata-controllerを持つDOMが現れたら connectされる — disconnect — DOMとの紐づけがなくなったタイミング — data-controllerを持つDOMが消されたり、data- controller属性自体が消されたりしたらdisconnect
DOMが存在する/しないで自動でcontrollerが紐付けられるというのが — turbolinksフレンドリーってことっぽい?
インスタンスは使い回される — disconnectしたあとにまたconnectされるケースでは、イン スタンスが使い回される — つまりconnectやdisconnectは複数回呼ばれる可能性が ある
まとめ
メリット — 学習コストがめっちゃ低い — 一日あれば使えるようになるのでは? — vannilajsやjQueryで作っているサービスから移行しやすい — 試してみた結果やめたくなった場合も比較的やめやすそう
デメリット — vannilajsから移行しても「単にメソッドやイベントを整理 した」以上にはならない — マジカルな何かですごいことになる、ということはない — できることが限定的 — SPAとか無理(そういうのはturbolinks使って擬似的にや
ればいいじゃん、という考え) — JSON APIを叩いて云々、とかは考えてない — クライアントサイドでDOMを組み立てる、なんて大変で しょ?全部HTMLでやればいいんだよ
以上