はじめに
私は、StimulusをRailsで使うとき、stimulus-rails gemをインストールします。
そして、以下のコマンドを実行してStimulusを使う環境を整えます。
./bin/rails stimulus:install
このコマンドを実行すると、複数のファイルが作成されます。
このファイルがあるおかげで、Stimulusが気軽に使える状態になります。
作成されるファイルの中に、Stimulusアプリケーションを起動している以下のファイルがあります。
import { Application } from "@hotwired/stimulus"
const application = Application.start()
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
export { application }
Application.start()
で、Stimulusアプリケーションを起動しています。
このおかげで、Stimulus controllerがいい感じに使えるようになってるのだろうと推測できます。
実際のところ、Application.start()
は何をしているのでしょうか?
Application.start()
は何をしているのか?
static start
メソッド
Application.start()
で呼び出されているのは、static start
メソッドです。
static start
メソッドは、Application
classのインスタンスapplication
を作り、start
メソッドを実行しています。
static start(element?: Element, schema?: Schema): Application {
const application = new this(element, schema)
application.start()
return application
}
constructor
メソッド
Application
classのconstructor
は以下のように定義されています。
constructor(element: Element = document.documentElement, schema: Schema = defaultSchema) {
this.element = element
this.schema = schema
this.dispatcher = new Dispatcher(this)
this.router = new Router(this)
this.actionDescriptorFilters = { ...defaultActionDescriptorFilters }
}
仮引数element
に何も渡さなければ、<html>
要素がelement
プロパティに代入されます。Stimulusアプリケーションを適用する範囲を指定したい場合は、仮引数element
に何らかのDOMを渡せば良いということです。
仮引数schema
に何も渡さなければ、defaultSchema
がschema
プロパティに代入されます。defaultSchema
は、Stimulusで使われるキーワードが定義されているオブジェクトです。例えば、HTMLタグにhello
というStimulus controllerを適用する場合、HTML要素の属性にdata-controller="hello"
をセットします。このときに使うキーワードが、defaultSchema
で定義されています。
適用するStimulus controllerを指定するキーワードを変えるようなことはあまりないと思います。最も使いそうなユースケースは、action descriptorのカスタマイズです。action descriptorとは、下記<div>
要素のkeydown.esc
の部分です。これは、「Escキーを押したとき」という意味です。デフォルトでは、「@キーを押したとき」という意味のaction descriptorはありません。これを追加したい場合は、defaultSchema
をカスタマイズして、constructor
メソッドの仮引数schema
に渡します。
<div data-controller="modal"
data-action="keydown.esc->modal#close" tabindex="0">
</div>
constructor
メソッドでは、以下のプロパティの初期化もしています。
router
dispatcher
actionDescriptorFilters
router
、dispatcher
がどういうものなのかは、まだ読み解けてないのですが、大雑把に以下のような役割があるようです。
-
router
: DOMの監視 -
dispatcher
: DOMイベントとstimulus controllerのメソッドの紐付け
actionDescriptorFilters
では、DOM event listener optionsにないStimulus独自のoptionを定義しています。
async start
メソッド
async start
メソッドは、static start
メソッドで実行されています。domReady
関数を使って、DOMが読み込まれるまで待ちます。その後、dispather
とrouter
を起動しています。
async start() {
await domReady()
this.logDebugActivity("application", "starting")
this.dispatcher.start()
this.router.start()
this.logDebugActivity("application", "start")
}
おわりに
Stimulus アプリケーションの起動時に、以下のことをしていることがわかりました。
- Stimulusで使われるキーワードを定義
-
Router
を起動 -
Dispatcher
を起動
Router
、Dispatcher
については、それぞれどのような目的を持つものなのかはっきりわかりませんでした。
なので、今後は、これらがどのように動いているのか調べてみたいと思います。