Soumettre la recherche
Mettre en ligne
Isomorphic web development with scala and scala.js
•
11 j'aime
•
23,475 vues
T
TanUkkii
Suivre
isomorphic tokyo meetupで発表した資料です
Lire moins
Lire la suite
Ingénierie
Signaler
Partager
Signaler
Partager
1 sur 23
Télécharger maintenant
Télécharger pour lire hors ligne
Recommandé
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
Kohei Asai
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
spring_raining
One Time Binding & Digest Loop
One Time Binding & Digest Loop
Kon Yuichi
React を導入したフロントエンド開発
React を導入したフロントエンド開発
daisuke-a-matsui
今からでも遅くない! React事始め
今からでも遅くない! React事始め
ynaruta
React.js + Reduxで作るSPA
React.js + Reduxで作るSPA
Shohei Saeki
こんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツール
dcubeio
サーバサイドエンジニアが 1年間まじめにSPAやってみた
サーバサイドエンジニアが 1年間まじめにSPAやってみた
Itaru Kitagawa
Recommandé
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
Kohei Asai
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
spring_raining
One Time Binding & Digest Loop
One Time Binding & Digest Loop
Kon Yuichi
React を導入したフロントエンド開発
React を導入したフロントエンド開発
daisuke-a-matsui
今からでも遅くない! React事始め
今からでも遅くない! React事始め
ynaruta
React.js + Reduxで作るSPA
React.js + Reduxで作るSPA
Shohei Saeki
こんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツール
dcubeio
サーバサイドエンジニアが 1年間まじめにSPAやってみた
サーバサイドエンジニアが 1年間まじめにSPAやってみた
Itaru Kitagawa
Flux react現状確認会
Flux react現状確認会
VOYAGE GROUP
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
TanUkkii
Closure Compiler Updates for ES6
Closure Compiler Updates for ES6
Teppei Sato
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Teppei Sato
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
Kazunari Hara
React+TypeScriptもいいぞ
React+TypeScriptもいいぞ
Mitsuru Ogawa
ReactをRailsとどっぷり使ってみた話と、フロントエンド×AWSのこれから
ReactをRailsとどっぷり使ってみた話と、フロントエンド×AWSのこれから
Yusuke Murata
20160927 reactmeetup
20160927 reactmeetup
Naoki Kurosawa
2016/12/17 ASP.NET フロントエンドタスク入門
2016/12/17 ASP.NET フロントエンドタスク入門
miso- soup3
capybara で快適なテスト生活を
capybara で快適なテスト生活を
Ryunosuke SATO
Service worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたち
Kinuko Yasuda
PHP Application E2E with Capybara
PHP Application E2E with Capybara
Yoshiaki Yoshida
SIROK技術勉強会 #1 「Reactってなんだ?」
SIROK技術勉強会 #1 「Reactってなんだ?」
Naoyuki Kataoka
RailsでReact.jsを動かしてみた話
RailsでReact.jsを動かしてみた話
yoshioka_cb
angular1脳で見るangular2
angular1脳で見るangular2
Moriyuki Arakawa
Ember コミュニティとわたし
Ember コミュニティとわたし
Ryunosuke SATO
おれおれブログシステムにServiceWorkerを導入してみた #serviceworker
おれおれブログシステムにServiceWorkerを導入してみた #serviceworker
Toshiaki Maki
Swagger 入門
Swagger 入門
Yoshiaki Yoshida
なぜ人は必死でjQueryを捨てようとしているのか
なぜ人は必死でjQueryを捨てようとしているのか
Yoichi Toyota
React Canvasで作るFlappy Bird
React Canvasで作るFlappy Bird
Takuya Tejima
ng-japan 2015 TypeScript+AngularJS 1.3
ng-japan 2015 TypeScript+AngularJS 1.3
Masahiro Wakame
AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ
AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ
アシアル株式会社
Contenu connexe
Tendances
Flux react現状確認会
Flux react現状確認会
VOYAGE GROUP
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
TanUkkii
Closure Compiler Updates for ES6
Closure Compiler Updates for ES6
Teppei Sato
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Teppei Sato
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
Kazunari Hara
React+TypeScriptもいいぞ
React+TypeScriptもいいぞ
Mitsuru Ogawa
ReactをRailsとどっぷり使ってみた話と、フロントエンド×AWSのこれから
ReactをRailsとどっぷり使ってみた話と、フロントエンド×AWSのこれから
Yusuke Murata
20160927 reactmeetup
20160927 reactmeetup
Naoki Kurosawa
2016/12/17 ASP.NET フロントエンドタスク入門
2016/12/17 ASP.NET フロントエンドタスク入門
miso- soup3
capybara で快適なテスト生活を
capybara で快適なテスト生活を
Ryunosuke SATO
Service worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたち
Kinuko Yasuda
PHP Application E2E with Capybara
PHP Application E2E with Capybara
Yoshiaki Yoshida
SIROK技術勉強会 #1 「Reactってなんだ?」
SIROK技術勉強会 #1 「Reactってなんだ?」
Naoyuki Kataoka
RailsでReact.jsを動かしてみた話
RailsでReact.jsを動かしてみた話
yoshioka_cb
angular1脳で見るangular2
angular1脳で見るangular2
Moriyuki Arakawa
Ember コミュニティとわたし
Ember コミュニティとわたし
Ryunosuke SATO
おれおれブログシステムにServiceWorkerを導入してみた #serviceworker
おれおれブログシステムにServiceWorkerを導入してみた #serviceworker
Toshiaki Maki
Swagger 入門
Swagger 入門
Yoshiaki Yoshida
なぜ人は必死でjQueryを捨てようとしているのか
なぜ人は必死でjQueryを捨てようとしているのか
Yoichi Toyota
Tendances
(19)
Flux react現状確認会
Flux react現状確認会
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
Closure Compiler Updates for ES6
Closure Compiler Updates for ES6
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
Closure CompilerのES6対応 あるいはES6時代のAltJS生存戦略
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
アメブロ2016 アメブロフロント刷新にみる ひかりとつらみ
React+TypeScriptもいいぞ
React+TypeScriptもいいぞ
ReactをRailsとどっぷり使ってみた話と、フロントエンド×AWSのこれから
ReactをRailsとどっぷり使ってみた話と、フロントエンド×AWSのこれから
20160927 reactmeetup
20160927 reactmeetup
2016/12/17 ASP.NET フロントエンドタスク入門
2016/12/17 ASP.NET フロントエンドタスク入門
capybara で快適なテスト生活を
capybara で快適なテスト生活を
Service worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたち
PHP Application E2E with Capybara
PHP Application E2E with Capybara
SIROK技術勉強会 #1 「Reactってなんだ?」
SIROK技術勉強会 #1 「Reactってなんだ?」
RailsでReact.jsを動かしてみた話
RailsでReact.jsを動かしてみた話
angular1脳で見るangular2
angular1脳で見るangular2
Ember コミュニティとわたし
Ember コミュニティとわたし
おれおれブログシステムにServiceWorkerを導入してみた #serviceworker
おれおれブログシステムにServiceWorkerを導入してみた #serviceworker
Swagger 入門
Swagger 入門
なぜ人は必死でjQueryを捨てようとしているのか
なぜ人は必死でjQueryを捨てようとしているのか
En vedette
React Canvasで作るFlappy Bird
React Canvasで作るFlappy Bird
Takuya Tejima
ng-japan 2015 TypeScript+AngularJS 1.3
ng-japan 2015 TypeScript+AngularJS 1.3
Masahiro Wakame
AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ
AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ
アシアル株式会社
アメブロの大規模システム刷新と それを支えるSpring
アメブロの大規模システム刷新と それを支えるSpring
Takuya Hattori
32 Strategies for Building a Positive Learning Environment
32 Strategies for Building a Positive Learning Environment
Edutopia
Scala.js
Scala.js
ke-m kamekoopa
Scala.js: Next generation front end development in Scala
Scala.js: Next generation front end development in Scala
Otto Chrons
Scala.js for large and complex frontend apps
Scala.js for large and complex frontend apps
Otto Chrons
プログラミング言語Scala
プログラミング言語Scala
TanUkkii
Rendr入門: サーバサイドで(も)動かす、Backbone.js
Rendr入門: サーバサイドで(も)動かす、Backbone.js
Masahiko Tachizono
CRDT in 15 minutes
CRDT in 15 minutes
Shingo Omura
Railsのエラーログとの付き合い方
Railsのエラーログとの付き合い方
Taisuke Kawahara
minne の API 改善
minne の API 改善
Toshihiro Gotou
Rails5とAPIモードについての解説
Rails5とAPIモードについての解説
Fumiya Sakai
チームでつくるUIデザイン
チームでつくるUIデザイン
Sadaaki HIRAI
Deploy to Lobi
Deploy to Lobi
Hiroaki Nagata
WebID and eCommerce
WebID and eCommerce
Henry Story
Akka Clusterの耐障害設計
Akka Clusterの耐障害設計
TanUkkii
ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06
ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06
Yahoo!デベロッパーネットワーク
これからのJavaScriptー関数型プログラミングとECMAScript6
これからのJavaScriptー関数型プログラミングとECMAScript6
TanUkkii
En vedette
(20)
React Canvasで作るFlappy Bird
React Canvasで作るFlappy Bird
ng-japan 2015 TypeScript+AngularJS 1.3
ng-japan 2015 TypeScript+AngularJS 1.3
AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ
AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ
アメブロの大規模システム刷新と それを支えるSpring
アメブロの大規模システム刷新と それを支えるSpring
32 Strategies for Building a Positive Learning Environment
32 Strategies for Building a Positive Learning Environment
Scala.js
Scala.js
Scala.js: Next generation front end development in Scala
Scala.js: Next generation front end development in Scala
Scala.js for large and complex frontend apps
Scala.js for large and complex frontend apps
プログラミング言語Scala
プログラミング言語Scala
Rendr入門: サーバサイドで(も)動かす、Backbone.js
Rendr入門: サーバサイドで(も)動かす、Backbone.js
CRDT in 15 minutes
CRDT in 15 minutes
Railsのエラーログとの付き合い方
Railsのエラーログとの付き合い方
minne の API 改善
minne の API 改善
Rails5とAPIモードについての解説
Rails5とAPIモードについての解説
チームでつくるUIデザイン
チームでつくるUIデザイン
Deploy to Lobi
Deploy to Lobi
WebID and eCommerce
WebID and eCommerce
Akka Clusterの耐障害設計
Akka Clusterの耐障害設計
ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06
ReactとImmutable.jsで関数型を体験してみて思ったこと #scripty06
これからのJavaScriptー関数型プログラミングとECMAScript6
これからのJavaScriptー関数型プログラミングとECMAScript6
Similaire à Isomorphic web development with scala and scala.js
Jjug springセッション
Jjug springセッション
Yuichi Hasegawa
多分モダンなWebアプリ開発
多分モダンなWebアプリ開発
tak-nakamura
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
Yuki Morishita
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
PE-BANK
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
fukuoka.ex
Rails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd edition
Goh Matsumoto
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
fukuoka.ex
試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift
Etsuji Nakai
Backlogでの Perlのつかいかた
Backlogでの Perlのつかいかた
Ryuzo Yamamoto
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略
Hiroshi SHIBATA
scala+liftで遊ぼう
scala+liftで遊ぼう
youku
HTML5&API総まくり
HTML5&API総まくり
Shumpei Shiraishi
Visual Studio 2012 で実現する HTML5 & マルチ デバイス時代の Web 開発
Visual Studio 2012 で実現する HTML5 & マルチ デバイス時代の Web 開発
Akira Inoue
Windows 開発者のための Dev&Ops on AWS
Windows 開発者のための Dev&Ops on AWS
Amazon Web Services Japan
Mvc conf session_1_osada
Mvc conf session_1_osada
Hiroshi Okunushi
コンテナ環境でJavaイメージを小さくする方法!
コンテナ環境でJavaイメージを小さくする方法!
オラクルエンジニア通信
LambdaとMobileの美味しいかもしれない関係
LambdaとMobileの美味しいかもしれない関係
Hiraku Komuro
How to Make Own Framework built on OWIN
How to Make Own Framework built on OWIN
Yoshifumi Kawai
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
Akira Inoue
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
Kazuyuki Miyake
Similaire à Isomorphic web development with scala and scala.js
(20)
Jjug springセッション
Jjug springセッション
多分モダンなWebアプリ開発
多分モダンなWebアプリ開発
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
サンプルアプリケーションで学ぶApache Cassandraを使ったJavaアプリケーションの作り方
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Rails初心者レッスン lesson1 3rd edition
Rails初心者レッスン lesson1 3rd edition
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
試して学べるクラウド技術! OpenShift
試して学べるクラウド技術! OpenShift
Backlogでの Perlのつかいかた
Backlogでの Perlのつかいかた
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略
scala+liftで遊ぼう
scala+liftで遊ぼう
HTML5&API総まくり
HTML5&API総まくり
Visual Studio 2012 で実現する HTML5 & マルチ デバイス時代の Web 開発
Visual Studio 2012 で実現する HTML5 & マルチ デバイス時代の Web 開発
Windows 開発者のための Dev&Ops on AWS
Windows 開発者のための Dev&Ops on AWS
Mvc conf session_1_osada
Mvc conf session_1_osada
コンテナ環境でJavaイメージを小さくする方法!
コンテナ環境でJavaイメージを小さくする方法!
LambdaとMobileの美味しいかもしれない関係
LambdaとMobileの美味しいかもしれない関係
How to Make Own Framework built on OWIN
How to Make Own Framework built on OWIN
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
Plus de TanUkkii
Distributed ID generator in ChatWork
Distributed ID generator in ChatWork
TanUkkii
Non-blocking IO to tame distributed systems ー How and why ChatWork uses async...
Non-blocking IO to tame distributed systems ー How and why ChatWork uses async...
TanUkkii
Architecture of Falcon, a new chat messaging backend system build on Scala
Architecture of Falcon, a new chat messaging backend system build on Scala
TanUkkii
JSON CRDT
JSON CRDT
TanUkkii
WaveNet
WaveNet
TanUkkii
スケールするシステムにおけるエンティティの扱いと 分散ID生成
スケールするシステムにおけるエンティティの扱いと 分散ID生成
TanUkkii
Akka HTTP
Akka HTTP
TanUkkii
すべてのアクター プログラマーが知るべき 単一責務原則とは何か
すべてのアクター プログラマーが知るべき 単一責務原則とは何か
TanUkkii
ディープニューラルネット入門
ディープニューラルネット入門
TanUkkii
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
TanUkkii
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
TanUkkii
Scalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリング
TanUkkii
Plus de TanUkkii
(12)
Distributed ID generator in ChatWork
Distributed ID generator in ChatWork
Non-blocking IO to tame distributed systems ー How and why ChatWork uses async...
Non-blocking IO to tame distributed systems ー How and why ChatWork uses async...
Architecture of Falcon, a new chat messaging backend system build on Scala
Architecture of Falcon, a new chat messaging backend system build on Scala
JSON CRDT
JSON CRDT
WaveNet
WaveNet
スケールするシステムにおけるエンティティの扱いと 分散ID生成
スケールするシステムにおけるエンティティの扱いと 分散ID生成
Akka HTTP
Akka HTTP
すべてのアクター プログラマーが知るべき 単一責務原則とは何か
すべてのアクター プログラマーが知るべき 単一責務原則とは何か
ディープニューラルネット入門
ディープニューラルネット入門
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
Scalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリング
Isomorphic web development with scala and scala.js
1.
Isomorphic Web development with
Scala & Scala.js TanUkkii isomorphic tokyo meetup 2015/4/30
2.
I am ... •
@TanUkkii007 on Twitter • Web frontend engineer • だったけどゲーム開発が辛くてサーバーサイドを Scalaで開発する人に • Scala業務歴4ヶ月
3.
Agenda 1. 開発環境を共有する 2. コードを共有する 3.
アーキテクチャを共有する クライアントーサーバー間で
4.
Motivation • Scala +
Akka + SprayでAPIサーバーを開発 • StrongLoopのApi Exprolerみたいなのを作りたい • Scala.jsでisomorphicにつくる! REST/HTTP server build on Akka Actors
5.
Why Scala.js? • クライアントーサーバーで同一の開発環境 •
クライアントーサーバーでコードの共有 • 片手間クライアント開発
6.
1. Sharing development environment:
Building applications with sbt • プロジェクト定義 • Scalaのバージョン • 依存ライブラリ • コンパイルオプション Java/Scalaのビルドツール 設定 タスク name := “your_project_name” scalaVersion := "2.11.6" libraryDependencies ++= Seq( "com.typesafe.akka" %% “akka-actor" % "2.3.10" ) ! scalacOptions in ThisBuild ++= Seq("-feature") build.sbt • 依存ライブラリの解決 • コンパイル • テスト • REPLの起動
7.
Multi-project build - client -
server - root import sbt._ import Keys._ object IsomorphicBuild extends Build { lazy val root = project.in(file(“.")) lazy val server = Project(“server", file(“server")) lazy val client = Project("client", file(“client”)) ! } project/Build.scala sbtではサブプロジェクトを複数定義できる ↓サーバーもクライアントも サブプロジェクトとして定義 相似のプロジェクト構造ができる→
8.
import sbt._ import Keys._ import
org.scalajs.sbtplugin.ScalaJSPlugin import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ object IsomorphicBuild extends Build { lazy val root = project.in(file(".")).aggregate(server, client) lazy val server = Project(“server", file(“server")) lazy val client = Project("client", file(“client")).enablePlugins(ScalaJSPlugin) .settings( persistLauncher in Compile := true, skip in packageJSDependencies := false ) } project/Build.scala Make Scala.js project ! addSbtPlugin(“org.scala-js" % "sbt-scalajs" % "0.6.2") project/plugins.sbt Scala.jsプラグインを追加 clientプロジェクトで Scala.jsプラグインを有効化
9.
Make Scala.js project isomorphic ! import
sbt._ import Keys._ import org.scalajs.sbtplugin.ScalaJSPlugin import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ object IsomorphicBuild extends Build { lazy val root = project.in(file(".")).aggregate(server, client) lazy val server = Project(“server", file(“server")) lazy val client = Project("client", file(“client")).dependsOn(server).enablePlugins(ScalaJSPlugin) .settings( unmanagedSourceDirectories in Compile += (sourceDirectory in server).value/"main"/"scala"/"jp.isomorphic.example" / “shared", packageJSDependencies in Compile := { val base = (packageJSDependencies in Compile).value IO.copyFile(base, (baseDirectory in server).value / "src/main/resources/js" / base.getName) base }, persistLauncher in Compile := true, skip in packageJSDependencies := false ).settings(Seq(fastOptJS, fullOptJS) map { packageJSKey => crossTarget in (Compile, packageJSKey) := (baseDirectory in server).value / "src/main/resources/js" }) } project/Build.scala サーバーからクライアントに クラスパスを通す (Scalaコンパイルが可能に) コンパイル対象に サーバー側のソースの一部を追加 (Scala.jsコンパイルが可能に) Scala.jsのコンパイル結果を サーバー側にコピー
10.
Using CrossProject to
build isomorphic project structure -shared - js - jvm import sbt.Keys._ import sbt._ import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._ ! ! object ApplicationBuild extends Build { lazy val root = project.in(file(".")) lazy val sharedProject = crossProject.in(file(".")) .settings() .jvmSettings() .jsSettings() ) lazy val js: Project = sharedProject.js.settings() lazy val jvm: Project = sharedProject.jvm.settings() } ! ScalaJSPluginの CrossProjectを使えば 簡単にisomorphicな プロジェクト構造を作れる scalajs-spa-tutorialを参照scalajs-cross-compile-example,
11.
2. Sharing codes
between Client and Server • Scala.jsで利用可能なライブラリ • シリアライゼーションによるScalaデータ型の通信 • 型安全なAPIの呼び出し • マクロ
12.
Available Libraries • DOM •
jQuery • React.js • AngularJS www.scala-js.orgにもっと多く載っている JSライブラリの 型付けされたインターフェース • Scalaz • NICTA/rng Scalaライブラリのポート • Scala.Rx • Monifu • autowire • uPickle 最初からクロスコンパイル前提で 作られたライブラリ※Scalaは型だけ提供。実装はJS。 ※本家のクロスコンパイルできない 部分を修正してJSを提供 ※ScalaとJSを提供
13.
Pickling (serialization) • クラス階層情報の喪失 Scala.jsの大問題:可逆的なJSONのシリアライズ リフレクションを使わずにコンパイル時に少ないコードで解決しなければならない。 サーバー
クライアント JSON {"fruits": [{"color": "yellow"}, {"color": "red"}]} {"points": [{"x": 1, "y": 2}, {"x": 1, "y": 2}]} null [[]] val fruits: List[Fruit] = List(Banana("yellow"), Apple("red")) val p = Point(1,2); val points = List(p, p) val option: Option[Option[Int]] = None 通信 • 参照同一性の喪失 • Optionの扱い Scalaデータ型 Scalaデータ型
14.
Cross-compiled pickling libraries きれいな JSON形式 クラス階 層の保持 参照同一 性の保持 Anyの解 決 uPickle
○ 難しいことは忘れて きれいなJSONを吐くことに注力 Optionが配列として表現される Prickle ○ ○ 可逆性を高めるため メタ情報をJSONに保持させている Scala.js Pickling ○ ○ 型の登録処理が事前に必要 サポートがあまりよくない
15.
Binary serialization with BooPickle
and XHR2 def request(method: String, url: String, body: ArrayBuffer): Future[ByteBuffer] = { val promise = Promise[ByteBuffer] val xhr = new XMLHttpRequest() xhr.onreadystatechange = { (e: Event) => if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300) { val byteBuffer = TypedArrayBuffer.wrap(xhr.response.asInstanceOf[ArrayBuffer]) promise.success(byteBuffer) } else promise.failure(AjaxException(xhr)) }} xhr.open(method, url) xhr.responseType = "arraybuffer" xhr.setRequestHeader("Content-Type", "application/octet-stream") xhr.setRequestHeader("Accept", "application/octet-stream") xhr.send(body) promise.future } val byteBuffer = Pickle.intoBytes(SampleRequest("Hello")) request(method, url, byteBuffer.arrayBuffer()).map(Unpickle[SampleResponse].fromBytes(_)) • JSONではなく、バイナリにシリアライズ • XHR level2のバイナリサポートを利用 • JSのArrayBufferを使う • メディアタイプは application/octet-stream • クラス階層、参照の同一性も復元可能
16.
Client-server communication with Autowire object
AutowireClient extends autowire.Client[String, Reader, Writer]{ override def doCall(req: Request): Future[String] } trait MyApi { def sampleRequest(id: Int): SampleResponse } object MyApiImpl extends MyApi{ def sampleRequest(id: Int) = SampleResponse(id) } AutowireClient[MyApi].sampleRequest(1).call().map(println) path("api" / Segments){ s => extract(_.request.entity.asString) { e => complete { AutowireServer.route[MyApi](MyApiImpl)( autowire.Core.Request(s, upickle.read[Map[String, String]](e))) }}} object AutowireServer extends autowire.Server[String, Reader, Writer]{ val routes = AutowireServer.route[MyApi](MyApiImpl) } Autowire マクロマジック!! AutowireはAjaxにおける クライアントーサーバー間のAPIの煩雑さを RPCスタイルのメソッド呼び出しで 解決するライブラリ • なぜかRPCは自動で解決される • API呼び出しにおける間違いは コンパイル時に発見される 1. sharedでRPCインターフェースを定義 2. serverでRPCインターフェースを実装 3. serverでルーティング部分関数をマクロにより生成 4. serverでルーティング部分関数を呼び出してレスポンスを返す 5. clientでAjaxの通信の仕方を実装 6. clientでRPC関数を呼び出す
17.
Macro performing macro expansion
AutowireServer.route[jp.isomorphic.example.MyApi] (<empty> match { case autowire.Core.Request(Seq("jp", "isomorphic", "example", "MyApi", "sampleRequest"), (args$macro$1 @ _)) => autowire.Internal.doValidate({ <synthetic> <artifact> val x$2 = autowire.Internal.read[String, Int](args$macro$1, scala.util.Left(autowire.Error.Param.Missing("id")), "id", ((x$1) => AutowireServer.read[Int](x$1))); Nil.$colon$colon(x$2) }) match { case scala.$colon$colon((id @ (_: Int @unchecked)), Nil) => scala.concurrent.Future.successful(MyApiImpl.sampleRequest(id)).map(((x$3) => AutowireServer.write(x$3))) case _ => $qmark$qmark$qmark } }: autowire.Core.Router[String]) 種明かし:-Ymacro-debug-liteコンパイルオプションでマクロを展開する package jp.isomorphic.example trait MyApi { def sampleRequest(id: Int): SampleResponse } マクロは ←から、関数のシグニチャに対して パターンマッチをかける部分関数 を作っていた ※Scalaのマクロは抽象構文木を操るすごいやつです
18.
3. Sharing Application Architecture Scalaでフロントエンドのアプリケーションをいざ書くときに 今までやってきたことをScalaでどう表現するとよいか迷う オブザーバーパターン
→ ? アーキテクチャをシェアして コンテクストスイッチのコストを減らそう!
19.
Common Practice: Unidirectional Data
Flow • Tell, don t ask. • Fire and forget. Flux Scalajs SPA Tutorialがこの共通点からアプローチしている • unidirectional data flow • message passing 複雑さに対抗する手段のコンセプトは同じ
20.
Flux in Scala つまりStoreがActorになった Scalajs
SPA Tutorial* image from
21.
trait Actor { type
Receive = PartialFunction[Any, Unit] def receive: Receive def !(message: Any) = { receive(message) } } trait Dispatcher { var actors = Set.empty[Actor] def dispatch(message: Any) = { actors.foreach { actor => actor ! message } } def register(actor: Actor) = { actors = actors + actor } def unregister(actor: Actor) = { if (actors.contains(actor)) { actors - actor } } } Dispatcherは Actorプログラミングにおける Recipient Listパターン var Dispatcher = { _listeners: [], register: function(callback) { this._listeners.push(callback); return this; }, unregister: function(callback) { var index = this._listeners.indexOf(callback); if (index !== -1) { delete this._listeners[index]; } return this; }, dispatch: function(...args) { this._listeners.forEach(callback => callback.apply(this, args) ); return this; } }; ※Recipient List: メッセージを複数のアクターに拡散 し仕事を分散して処理する際に、拡散先の受信者である アクター参照の一覧を保持しているもの
22.
object SampleDispatcher extends
Dispatcher object SampleActorProtocol { case class Foo(message: String) case class Bar(message: String) } object SampleActor extends Actor { import SampleActorProtocol._ SampleDispatcher.register(this) def receive: Receive = { case Foo(message) => println(message) case Bar(message) => println(message) } } ! import SampleActorProtocol._ SampleDispatcher.dispatch(Foo("Hello")) Dispatcher.register(function(payload) { if (payload.type === "FOO") { console.log(payload.message); } else if (payload.type === "BAR") { console.log(payload.message); } }); ! Dispatcher.dispatch({type: "FOO", message: "Hello"}); ! ! ! ! ! ! ! ! ! ! ! • Dispatcherに関数ではなくActorオブジェクトを登録する • payloadを処理する関数はActorのReceive部分関数に相当 • payloadはメッセージ
23.
Conclusion • Scala +
Scala.jsでクライアントーサーバーを高度 に統合できる • (ただし他のシステムとのinteropが犠牲になるかも • みんなScala.jsを使おう!!!
Télécharger maintenant