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
Riot.jsでSPAを作る
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
khdd-mks
December 13, 2018
Programming
0
950
Riot.jsでSPAを作る
Riot.jsの基礎とRiot.jsでSPAを作るときの基礎です
khdd-mks
December 13, 2018
Tweet
Share
More Decks by khdd-mks
See All by khdd-mks
AWS Amplify / AppSync
khddmks
1
360
AWS Amplify HandsOn
khddmks
1
320
GoogleKubernetesEngine is very easy
khddmks
0
210
Other Decks in Programming
See All in Programming
humanlayerのブログから学ぶ、良いCLAUDE.mdの書き方
tsukamoto1783
0
200
フロントエンド開発の勘所 -複数事業を経験して見えた判断軸の違い-
heimusu
7
2.8k
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
650
AgentCoreとHuman in the Loop
har1101
5
240
CSC307 Lecture 03
javiergs
PRO
1
490
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
610
Best-Practices-for-Cortex-Analyst-and-AI-Agent
ryotaroikeda
1
110
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
1
980
なぜSQLはAIぽく見えるのか/why does SQL look AI like
florets1
0
480
そのAIレビュー、レビューしてますか? / Are you reviewing those AI reviews?
rkaga
6
4.6k
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
730
Featured
See All Featured
Six Lessons from altMBA
skipperchong
29
4.2k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
67
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
310
Ruling the World: When Life Gets Gamed
codingconduct
0
140
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.7k
From π to Pie charts
rasagy
0
120
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
180
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
150
Statistics for Hackers
jakevdp
799
230k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.1k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
410
Transcript
Riot.jsでSPAを作る 2018/12/13 fun-tech #7 @khdd-mks
自己紹介 ・北島久資 (@khdd-mks) ・オープンストリーム所属 アーキテクト ・ fun-tech 運営 ・ Scala
が好きですが 仕事では Golang, Python, javascript とかやってます …
Riot.js
https://riot.js.org/
Riot.js ・ Web 上の UI コンポーネントを作るためのライブラリ ・要するに React.js や Vue.js
と同じような領域のライブラリ ・ React.js や Vue.js よりも軽量でシンプルなのが特徴
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML 内にカスタムタグのマウント場所を用意する 4. HTML でカスタムタグファイルを読み込み、マウントする
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML 内にカスタムタグのマウント場所を用意する 4. HTML でカスタムタグファイルを読み込み、マウントする
<todo> <h3>{ opts.title }</h3> <ul> <li each={ item, i in
items }>{ item }</li> </ul> <form onsubmit={ add }> <input ref="input"> <button>Add #{ items.length + 1 }</button> </form> <!-- 本当はこの辺りにcss(<style>~</style>)を指定 --> <script> this.items = [] add(e) { e.preventDefault() var input = this.refs.input this.items.push(input.value) input.value = '' } </script> </todo>
<todo> <h3>{ opts.title }</h3> <ul> <li each={ item, i in
items }>{ item }</li> </ul> <form onsubmit={ add }> <input ref="input"> <button>Add #{ items.length + 1 }</button> </form> <!-- 本当はこの辺りにcss(<style>~</style>)を指定 --> <script> this.items = [] add(e) { e.preventDefault() var input = this.refs.input this.items.push(input.value) input.value = '' } </script> </todo> 全体をカスタムタグ名で囲む
<todo> <h3>{ opts.title }</h3> <ul> <li each={ item, i in
items }>{ item }</li> </ul> <form onsubmit={ add }> <input ref="input"> <button>Add #{ items.length + 1 }</button> </form> <!-- 本当はこの辺りにcss(<style>~</style>)を指定 --> <script> this.items = [] add(e) { e.preventDefault() var input = this.refs.input this.items.push(input.value) input.value = '' } </script> </todo> HTMLを記述する 変数の埋め込みとかあるけど 何となく分かる感じ
<todo> <h3>{ opts.title }</h3> <ul> <li each={ item, i in
items }>{ item }</li> </ul> <form onsubmit={ add }> <input ref="input"> <button>Add #{ items.length + 1 }</button> </form> <!-- 本当はこの辺りにcss(<style>~</style>)を指定 --> <script> this.items = [] add(e) { e.preventDefault() var input = this.refs.input this.items.push(input.value) input.value = '' } </script> </todo> CSSを記述する 普通に <style> h3 { font-size: 14px; } </style> みたいな感じで記述
<todo> <h3>{ opts.title }</h3> <ul> <li each={ item, i in
items }>{ item }</li> </ul> <form onsubmit={ add }> <input ref="input"> <button>Add #{ items.length + 1 }</button> </form> <!-- 本当はこの辺りにcss(<style>~</style>)を指定 --> <script> this.items = [] add(e) { e.preventDefault() var input = this.refs.input this.items.push(input.value) input.value = '' } </script> </todo> 処理を記述する thisでカスタムタグ自身にアクセスできる メソッドを定義してHTML側のイベントハンドラ に指定する等が可能
<todo> <h3>{ opts.title }</h3> <ul> <li each={ item, i in
items }>{ item }</li> </ul> <form onsubmit={ add }> <input ref="input"> <button>Add #{ items.length + 1 }</button> </form> <!-- 本当はこの辺りにcss(<style>~</style>)を指定 --> <script> this.items = [] add(e) { e.preventDefault() var input = this.refs.input this.items.push(input.value) input.value = '' } </script> </todo> カスタムタグに関する内容が 全て同じ場所に記述されているので 分かりやすい
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML 内にカスタムタグのマウント場所を用意する 4. HTML でカスタムタグファイルを読み込み、マウントする
<html> <head> <title>Hello Riot.</title> </head> <body> <todo></todo> <script type="riot/tag" src="todo.tag"></script>
<script src="https://cdn.jsdelivr.net/npm/
[email protected]
/riot+compiler.min.js"></script> <script>riot.mount('todo')</script> </body> </html>
<html> <head> <title>Hello Riot.</title> </head> <body> <todo></todo> <script type="riot/tag" src="todo.tag"></script>
<script src="https://cdn.jsdelivr.net/npm/
[email protected]
/riot+compiler.min.js"></script> <script>riot.mount('todo')</script> </body> </html> コンパイラ付のRiot.js クライアント側でカスタムタグをjavascriptに変換して実行す る
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML 内にカスタムタグのマウント場所を用意する 4. HTML でカスタムタグファイルを読み込み、マウントする
<html> <head> <title>Hello Riot.</title> </head> <body> <todo></todo> <script type="riot/tag" src="todo.tag"></script>
<script src="https://cdn.jsdelivr.net/npm/
[email protected]
/riot+compiler.min.js"></script> <script>riot.mount('todo')</script> </body> </html> カスタムタグ名そのままのタグを用 意するのが簡単 マウント方法が若干変わるが divタグ等でも可能
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML 内にカスタムタグのマウント場所を用意する 4. HTML でカスタムタグファイルを読み込み、マウントする
<html> <head> <title>Hello Riot.</title> </head> <body> <todo></todo> <script type="riot/tag" src="todo.tag"></script>
<script src="https://cdn.jsdelivr.net/npm/
[email protected]
/riot+compiler.min.js"></script> <script>riot.mount('todo')</script> </body> </html> カスタムタグファイルは普通にスクリプト タグで読み込めばいい riot.mount(‘todo’) で <todo></todo>にtodoタグの内容が埋 め込まれる
webpack のようなビルドシステムを 使わなくても普通にできる すごく簡単!!
|゚д゚) < とか言って 実システムで webpack とか使 おうとすると逆に困るんだろ、 騙されんぞ
|゚д゚) < とか言って 実システムで webpack とか使 おうとすると逆に困るんだろ、 騙されんぞ 大丈夫です
ビルドシステムを使用する場合 ・ webpack であれば riot-tag-loader 等の loader を使えば問題ない ・仮に他のビルドシステムを使用しており、そのビルドシステム用のものが 存在しなかったとしても
$ riot --esm [カスタムタグのあるディレクトリ] [出力先のディレクトリ] でESモジュールに変換できるので、変換後のファイルを使用すればいい
ビルドシステムを使用する場合 // エントリポイントのjavascriptファイル import riot from 'riot'; require('./tags/todo.tag'); riot.mount('todo');
…require?
ビルドシステムを使用する場合 // エントリポイントのjavascriptファイル import riot from 'riot'; require('./tags/todo.tag'); riot.mount('todo'); Riot.jsは内部的に
カスタムタグ名とその内容を対応付けて管理している (のでマウント時にカスタムタグ名しか指定していない) → ESモジュールに変換しても何もexportしないのでimportで はなくrequire
Riot.js の基本は分かった というわけで
SPA ※ここからが本題です
SPA SPA(SinglePageApplication) ・1つのページでアプリケーション全体を構築する手法 ・利点:ページ遷移を伴わないので高速化・通信量削減が期待できる ・欠点:クライアントサイドが複雑化しやすい
SPA に欠かせないのが 「見た目上ページ遷移して いるように見える機能」
Riot.js の場合 何を使用することも可能だが 特にこだわりが無いのであれば Riot.js の補助ライブラリである
Riot-Route
Riot-Route ・Riot.jsに標準では組み込まれていない → 別のものを使ってもいい ・特にRiot.jsと相乗効果は無い → Vue.jsのRouter (「Vue.js のコアと深く深く統合されており」とか紹介されている) 等とは真逆の発想
・Riot.jsと同じくシンプル
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML で Riot-Router のスクリプトを読み込む 4. HTML 内に各ページ用のカスタムタグのマウント場所を用意する 5. HTML でカスタムタグファイルを読み込むが、直接マウントしない 6. Riot-Route の設定を行い、ルーティングを開始する
ちなみに webpack とか使わなくても できると思うけど ここでは webpack 使う前提で
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML で Riot-Router のスクリプトを読み込む 4. HTML 内に各ページ用のカスタムタグのマウント場所を用意する 5. HTML でカスタムタグファイルを読み込むが、直接マウントしない 6. Riot-Route の設定を行い、ルーティングを開始する
import riot from 'riot'; import route from 'riot-route'; import todoRoute
from './router/todo'; import todo2Route from './router/todo2'; import todo3Route from './router/todo3'; require('./tags/menu.tag'); riot.mount('menu'); route.base('/'); // ホスト名以下の部分を #hoge -> /hoge で表示するのに必要 const subRoutes = [todoRoute, todo2Route, todo3Route]; for (const subRoute of subRoutes) { subRoute('div#main'); } route('', () => { route('/todo'); }) route.start(true); 普通にnpm install --save riot-route
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML で Riot-Router のスクリプトを読み込む 4. HTML 内に各ページ用のカスタムタグのマウント場所を用意する 5. HTML でカスタムタグファイルを読み込むが、直接マウントしない 6. Riot-Route の設定を行い、ルーティングを開始する
<html lang="ja"> <head> <meta charset="utf-8"> <title>Hello Riot.</title> <script src="js/app.js" defer></script>
</head> <body> <menu></menu> <div id="main"></div> </body> </html> 複数のタグ(各ページ用のタグ)を マウントするため divタグで定義
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML で Riot-Router のスクリプトを読み込む 4. HTML 内に各ページ用のカスタムタグのマウント場所を用意する 5. HTML でカスタムタグファイルを読み込むが、直接マウントしない 6. Riot-Route の設定を行い、ルーティングを開始する
import riot from 'riot'; import route from 'riot-route'; import todoRoute
from './router/todo'; import todo2Route from './router/todo2'; import todo3Route from './router/todo3'; require('./tags/menu.tag'); riot.mount('menu'); route.base('/'); // ホスト名以下の部分を #hoge -> /hoge で表示するのに必要 const subRoutes = [todoRoute, todo2Route, todo3Route]; for (const subRoute of subRoutes) { subRoute('div#main'); } route('', () => { route('/todo'); }) route.start(true); // ./router/todo.js import riot from 'riot'; import route from 'riot-route'; require('../tags/todo.tag'); // 直接マウントはしない export default function(mainSelector) { const todoRoute = route.create(); todoRoute('/todo', () => { riot.mount(mainSelector, 'todo'); }); return todoRoute; }
基本 1. カスタムタグファイルを作る 2. HTML で Riot.js のスクリプトを読み込む ( コンパイラ含む
) 3. HTML で Riot-Router のスクリプトを読み込む 4. HTML 内に各ページ用のカスタムタグのマウント場所を用意する 5. HTML でカスタムタグファイルを読み込むが、直接マウントしない 6. Riot-Route の設定を行い、ルーティングを開始する
import riot from 'riot'; import route from 'riot-route'; import todoRoute
from './router/todo'; import todo2Route from './router/todo2'; import todo3Route from './router/todo3'; require('./tags/menu.tag'); riot.mount('menu'); route.base('/'); // ホスト名以下の部分を #hoge -> /hoge で表示するのに必要 const subRoutes = [todoRoute, todo2Route, todo3Route]; for (const subRoute of subRoutes) { subRoute('div#main'); } route('', () => { route('/todo'); }) route.start(true); // ./router/todo.js import riot from 'riot'; import route from 'riot-route'; require('../tags/todo.tag'); export default function(mainSelector) { const todoRoute = route.create(); todoRoute('/todo', () => { // URLが /todo のとき riot.mount(mainSelector, 'todo'); // div#main にtodoタグをマウント }); return todoRoute; }
import riot from 'riot'; import route from 'riot-route'; import todoRoute
from './router/todo'; import todo2Route from './router/todo2'; import todo3Route from './router/todo3'; require('./tags/menu.tag'); riot.mount('menu'); route.base('/'); // ホスト名以下の部分を #hoge -> /hoge で表示するのに必要 const subRoutes = [todoRoute, todo2Route, todo3Route]; for (const subRoute of subRoutes) { subRoute('div#main'); } route('', () => { route('/todo'); }) route.start(true); ルーティング開始
あと どのエンドポイントを呼ばれても 同じ HTML を返すように サーバー側を設定したりする必要がある が割愛
デモ ( 時間あれば )
ちなみに このスライド内のコードの完全版は $ git clone https://github.com/khdd-mks/funtech.git で見れます
ご清聴ありがとうございました