ewd 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

73
EWD 3 トトトトトト トトト #30 ewd-xpress トトトトトトトトト トトトトトトトト M/Gateway Developments Ltd. Rob Tweed ト : トトトトトトトトトトトトト ト トト GT.M トトト : トト ト ※ トトトトトトトト Cache’ トトトトトトト

Upload: kiyoshi-sawada

Post on 15-Apr-2017

49 views

Category:

Software


0 download

TRANSCRIPT

Page 1: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

EWD 3トレーニング・コース  #30

ewd-xpress アプリケーションを

モジュラー化するM/Gateway Developments Ltd.

Rob Tweed訳 : 日本ダイナシステム株式会社 嶋 芳成

GT.M 版編集 : 澤田 潔

※ 本稿オリジナルは Cache’ 向けとして編纂

Page 2: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

2

バックエンド・モジュール

• 今まで、モジュール・ファイルは、• ~/ewd3/node_modules

 に保存してきました• アプリケーション名 = モジュール・ファイル名

2016/9/8 EWD 3 トレーニング・コース #30

Page 3: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

3

完全な Node.js モジュールにできる

• すなわち、次のようなファイルを入れて完全なモジュール・パッケージ・ディレクトリを作ります• index.js• Package.json• README.md• その他

• NPM 上に発行することもできます• NPM からインストールすることもできます

2016/9/8 EWD 3 トレーニング・コース #30

Page 4: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

4

例えば

• demo1 アプリケーションのバックエンド・モジュール• ~/ewd3/node_modules/demo1.js を入れて

おくだけではなく• ~/ewd3/node_modules/demo1 というディ

レクトリを作り、そこに次のファイルを入れます• package.json• index.js• /lib フォルダ• オプションとして仕様書ファイルの

READme.md2016/9/8 EWD 3 トレーニング・コース #30

Page 5: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

5

package.json• 最小限 :

{ “name”: “demo1”, “version”: “1.0.0”, “main”: “index.js”,}

2016/9/8 EWD 3 トレーニング・コース #30

Page 6: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

6

package.json• 典型的にはもう少し :

{ “name”: “demo1”, “version”: “1.0.0”,  “ description”: “demo アプリのバックエンド・メッセージ・ハンドラ” , “main”: “index.js”, “author”: “Rob Tweed”, “license”: “Apache-2.0”, “repository”: { “type”: “git”, “url”: “git+https://github.com/robtweed/demo1.git” }}

2016/9/8 EWD 3 トレーニング・コース #30

Page 7: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

7

package.json• 典型的にはもう少し :

{ “name”: “demo1”, “version”: “1.0.0”,  “ description”: “demo アプリのバックエンド・メッセージ・ハンドラ” , “main”: “index.js”, “author”: “Rob Tweed”, “license”: “Apache-2.0”, “repository”: { “type”: “git”, “url”: “git+https://github.com/robtweed/demo1.git” }}

2016/9/8 EWD 3 トレーニング・コース #30

Node.js に、メインのコード/スクリプト・ファイルがあるかを教えます

Page 8: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

8

index.js• メインのスクリプト・ファイル• コードを入れることができます• 通常は、コードへのポインターのみ• コードは通常別のフォルダに入れます• 例えば /lib

2016/9/8 EWD 3 トレーニング・コース #30

Page 9: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

9

index.js‘use strict’;module.export = require(‘./lib/demo1’);

• メインのコードは実際には /lib/demo1.js にあります

2016/9/8 EWD 3 トレーニング・コース #30

Page 10: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

10

/lib/demo1.js module.exports = { init: funciton() { serviceAllowed: { testService: true }, handlers: { login: function(messageObj,session,send,finished) { // その他 }, // その他 }, } };

標準的な ewd-xpress のバックエンド・モジュール2016/9/8 EWD 3 トレーニング・コース #30

Page 11: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

11

これで完全な Node.js / NPM モジュール

• demo1 モジュールはこれで NPM に対して発行することができます ( それが適切であればですが )

• 他の人は、次のコードでそれをインストールして使うことができるようになります• npm install demo1

2016/9/8 EWD 3 トレーニング・コース #30

Page 12: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

12

ewd-xpress サービス

• ewd-xpress サービス・モジュールは、 NPM 上に発行することのできるモジュールとしてパッケージ化する良い候補です• それを他の人が、自分のアプリケーションで再利

用することができます

2016/9/8 EWD 3 トレーニング・コース #30

Page 13: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

13

フロントエンドのコードをモジュラー化する

• “ フラグメント” を用いる• Browserify や WebPack のような “バンド

ラー” を用いる

2016/9/8 EWD 3 トレーニング・コース #30

Page 14: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

14

フラグメント

• 少し旧式のアプローチになっています• React.js や Angular のような、最新のフレーム

ワークには適切ではありません

• より慣習的な開発については、アプリケーションをモジュラー化する効率的な方法になり得ます• サービスの一部にすることができます

2016/9/8 EWD 3 トレーニング・コース #30

Page 15: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

15

フラグメント

• 概念:• まず最初の HTML ファイル ( 例えば

index.html) を読み込みます• そこには通常少しのマークアップしかありません• しかし、アプリケーションにより、必要なすべて

の JavaScript や CSS を読み込みます

• 続いて、 HTML のフラグメントが、動的に <div> やその他のタグの中に、ブラウザで生じたイベントの結果として読み込まれます• Ajax や WebSocket 経由

2016/9/8 EWD 3 トレーニング・コース #30

Page 16: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

16

フラグメント

• フラグメントは、サービス・モジュールの一部として組み込むことができます• バックエンドのメッセージ・ハンドラーのロジッ

ク• マークアップに関係するフラグメント• NPM 上に発行可能

• 従って、ひとつのアプリケーションが、複数のサービスから、フラグメントやバックエンド・ロジックを用いることができます• 即ち、再利用可能なロジック、マークアップ/ UI

の部品

2016/9/8 EWD 3 トレーニング・コース #30

Page 17: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

17

EWD.getFragment()• フラグメントを取り込むには、ブラウザ側の

ロジックに、次のコードを入れます EWD.getFragment(argObj, callback);

2016/9/8 EWD 3 トレーニング・コース #30

Page 18: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

18

EWD.getFragment()• フラグメントを取り込むには、ブラウザ側の

ロジックに、次のコードを入れます• EWD.getFragment(artObj, callback);

• argObj: オブジェクトで、その内容は• name: ( 例えば : loginForm.html )

デフォルトで、同じディレクトリから index.html ファイルとして取り込む

• targetId:そのマークアップが挿入されるべきタグの id例えば <div id=“myTargetDiv”></div>

2016/9/8 EWD 3 トレーニング・コース #30

Page 19: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

19

EWD.getFragment()• フラグメントを取り込むには、ブラウザ側の

ロジックに、次のコードを入れます• EWD.getFragment(artObj, callback);

• callback: フラグメントがブラウザに読み込まれたときに呼び出されます• オプションの引数は1つだけ : name

読み込まれたフラグメントのファイル名• フラグメントのマークアップが必要とするハンド

ラーを読み込むためにこのコールバックを利用します

例えば、ボタンをクリックしたときのハンドラ

2016/9/8 EWD 3 トレーニング・コース #30

Page 20: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

20

例 : index.html<html> <head> <title>Fragment Demo</title> <link href=“//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css” rel=“stylesheet” /> </head> <body> <script src=“//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js”></script> <script src=“//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js”></script> <script src=“/socket.io/socket.io.js”></script> <script src=“/ewd-client.js”></script> <script src=“app2.js”></script>

<div id=“loginFormDiv”></div>

</body></html>

2016/9/8 EWD 3 トレーニング・コース #30

Page 21: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

21

例 : app2.js$(document).ready(function() { EWD.log = true;

EWD.on(‘ewd-registered’, function() {

EWD.on(‘error’, function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on(‘socketDisconnected’, function() { toastr.info(‘You have been logged out’); setTimeout(function() { location.reload(); },1000); });

var params = { name: ‘loginForm.html’, targetId: ‘loginFormDiv’ }; EWD.getFragment(params, function(name) { toastr.info(‘flagment loaded: ‘ + JSON.stringify(name)); }); }); EWD.start(‘demo1’, $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

Page 22: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

22

例 : index.html<html> <head> <title>Fragment Demo</title> <link href=“//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css” rel=“stylesheet” /> </head> <body> <script src=“//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js”></script> <script src=“//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js”></script> <script src=“/socket.io/socket.io.js”></script> <script src=“/ewd-client.js”></script> <script src=“app2.js”></script>

<div id=“loginFormDiv”></div>

</body></html>

2016/9/8 EWD 3 トレーニング・コース #30

var params = { name: ‘loginForm.html’, targetId: ‘loginFormDiv’};EWD.getFragment(params, function(name) { toastr.info(‘flagment loaded: ‘ + JSON.stringify(name));});

Page 23: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

23

例 : loginForm.html<table id=“loginForm”> <tr> <td>Username: </td> <td><input type=“text” id=“username” /></td> </tr> <tr> <td>Password: </td> <td><input type=“password” id=“password” /></td> </tr> <tr> <td colspan=“2”> <button id=“loginBtn”>Login</button> </td> </tr></table>

2016/9/8 EWD 3 トレーニング・コース #30

ログイン・フォームのためのマークアップのみ

Page 24: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

24

実行してみよう

2016/9/8 EWD 3 トレーニング・コース #30

Page 25: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

25

フォームは何もしません

2016/9/8 EWD 3 トレーニング・コース #30

例えば、このボタンをクリックしても何もおこりません

Page 26: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

26

編集 : app2.js var params = { name: ‘loginForm.html’, targetId: ‘loginFormDiv’ }; EWD.getFragment(params, function(name) { $(’#loginBtn’).on(’click’,function(e) { var username = $(’#username’.val(); if (username === ’’) { toastr.error(’You must enter a username’); return; } var password = $(’#password’).val(); if (password === ’’) { toastr.error(’You must enter a password’); return; } var message = { type: ’login’, params: { username: username, password: password } EWD.send(message(function(responseObj) { if (!responseObj.message.error){ $(’#loginForm’).hide(); } }); }); });

2016/9/8 EWD 3 トレーニング・コース #30

Page 27: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

27

編集 : app2.js var params = { name: ‘loginForm.html’, targetId: ‘loginFormDiv’ }; EWD.getFragment(params, function(name) { $(’#loginBtn’).on(’click’,function(e) { var username = $(’#username’.val(); if (username === ’’) { toastr.error(’You must enter a username’); return; } var password = $(’#password’).val(); if (password === ’’) { toastr.error(’You must enter a password’); return; } var message = { type: ’login’, params: { username: username, password: password } EWD.send(message(function(responseObj) { if (!responseObj.message.error){ $(’#loginForm’).hide(); } }); }); });

2016/9/8 EWD 3 トレーニング・コース #30

Login ボタン用のクリック・ハンドラを追加しています

Page 28: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

28

編集 : app2.js var params = { name: ‘loginForm.html’, targetId: ‘loginFormDiv’ }; EWD.getFragment(params, function(name) { $(’#loginBtn’).on(’click’,function(e) { var username = $(’#username’.val(); if (username === ’’) { toastr.error(’You must enter a username’); return; } var password = $(’#password’).val(); if (password === ’’) { toastr.error(’You must enter a password’); return; } var message = { type: ’login’, params: { username: username, password: password } EWD.send(message(function(responseObj) { if (!responseObj.message.error){ $(’#loginForm’).hide(); } }); }); });

2016/9/8 EWD 3 トレーニング・コース #30

Login ボタン用のクリック・ハンドラを追加していますクリックされると ‘ login’ という type とともに、 username と password がメッセージとして ewd-xpress のバックグラウンドに送信されます

Page 29: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

29

これで作動します

2016/9/8 EWD 3 トレーニング・コース #30

Page 30: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

30

これで作動します

• しかし、アプリケーションのメインの app.js ロジックの中に、フラグメントを読み込むロジックを定義しなくてはなりませんでした• loginForm フラグメントに付随するロジック

を別の場所に置くことができれば、よりモジュラー化できたことになります• 別々に維持管理できる• 再利用可能となる

2016/9/8 EWD 3 トレーニング・コース #30

Page 31: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

31

loginForm.js を作る

• app.js と同じディレクトリ内に• または、 /www の下の独自のサブディレクトリ内

2016/9/8 EWD 3 トレーニング・コース #30

Page 32: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

32

loginForm.jsvar loginForm = { loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: 'login', params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

Page 33: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

33

例 : index.html<html> <head> <title>Fragment Demo</title> <link href=“//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css” rel=“stylesheet” /> </head> <body> <script src=“//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js”></script> <script src=“//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js”></script> <script src=“/socket.io/socket.io.js”></script> <script src=“/ewd-client.js”></script> <script src=“app2.js”></script>     <script src=“loginForm.js”></script>

<div id=“loginFormDiv”></div>

</body></html>

2016/9/8 EWD 3 トレーニング・コース #30

Page 34: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

34

例 : app2.js$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

var params = { name: 'loginForm.html', targetId: 'loginFormDiv' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

Page 35: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

35

例 : app2.js$(document).ready(function() { EWD.log = true;

EWD.on(‘ewd-registered’, function() {

EWD.on(‘error’, function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on(‘socketDisconnected’, function() { toastr.info(‘You have been logged out’); setTimeout(function() { location.reload(); },1000); });

var params = { name: ‘loginForm.html’, targetId: ‘loginFormDiv’ }; EWD.getFragment(params, loginForm.loader); });

EWD.start(‘demo1’, $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

loginForm.jsvar loginForm = { loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: 'login', params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

Page 36: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

36

バックエンドのコードについてはどうでしょう?

2016/9/8 EWD 3 トレーニング・コース #30

Page 37: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

37

バックエンドのコードについてはどうでしょう?

var loginForm = { loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: 'login', params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

ログインメッセージはバックエンドに送られます。現時点では ewd-xpress は、それのハンドラーが、メインのアプリケーション・モジュール (demo1.js) 内に存在すると期待しています

そうではなくて、これをモジュラー化します ...

Page 38: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

38

ログイン・サービスを生成するfunction checkLogin(username,password) { // 現時点ではハードコード版 if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: tur};}module.exports = { handlers: { login: function(messageObj,session,send,finished) { if (session.authenticated) { finished({error: 'You are already logged in!'}); return; } var username = messageObj.params.username; if (username === '') { finished({error: 'You must enter a username'}); return; } var password = messageObj.params.password; if (password === '') { finished({error: 'You must enter a password'}); return; } var status = checkLogin(username,password); if (status.ok) { session.authenticated = true; session.timeout = 3600; session.updateExpiry(); finished({ok: true}); } else { finished({error: status.error}); } } }};

2016/9/8 EWD 3 トレーニング・コース #30

node_modules/Login.js に保存します

ここには、バックエンドで、ログイン認証を処理するロジックが書かれています

Page 39: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

39

loginForm.js を編集するvar loginForm = { loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: ‘login’, service: ‘Login’, params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

ログイン・メッセージには “ Login” サービスを用います。

Page 40: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

40

demo1.js を編集する

module.exports = { servicesAllowed { Login: true }};

demo1 アプリケーションが Login サービスを用いることができるようにするための、これが最小限のモジュールである必要があります

2016/9/8 EWD 3 トレーニング・コース #30

Page 41: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

実行してみる

• 新しいバックエンド・モジュールが確実に読み込まれるように、 ewd-xpress をリスタートしてください• 同じように稼働するはずですが、今回は

Login サービスを利用しています

2016/9/8 EWD 3 トレーニング・コース #30 41

Page 42: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

42

さらなるモジュラー化

• loginForm.html というフラグメントは、現在 www/demo1 のディレクトリにあります• これは Login サービスのフラグメント側の

部分にするにはどうしますか?

2016/9/8 EWD 3 トレーニング・コース #30

Page 43: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

43

Login モジュールを生成する

• 新しいフォルダを作ります

• ~/ewd3/node_modules/Login

2016/9/8 EWD 3 トレーニング・コース #30

Page 44: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

44

Login モジュールを生成する

• ~/ewd3/node_modules/Login

2016/9/8 EWD 3 トレーニング・コース #30

package.json{ “name”: “Login”, “version”: “1.0.0”, “description”: “Modular login system”, “main”: “index.js”}

index.js‘use strict’;module.exports = require(‘.lib/Login’);

⁻ index.js⁻ package.json

Page 45: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

45

Login モジュールを生成する

• ~/ewd3/node_modules/Login.js を、

  ~/ewd3/node_modules/Login/lib/login.js に移動する

2016/9/8 EWD 3 トレーニング・コース #30

⁻ lib⁻ Login.js

⁻ index.js⁻ package.json

Page 46: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

46

Login モジュールを生成する

• ~/ewd3/www/demo1/loginForm.html を、

  ~/ewd3/node_modules/Login/fragments/loginForm.html に移動する

2016/9/8 EWD 3 トレーニング・コース #30

⁻ fragments⁻ loginForm.html

⁻ lib⁻ Login.js

⁻ index.js⁻ package.json

Page 47: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

47

例 : app2.js$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

loginForm.html を Login サービス・モジュールから読み込みます

ewd-xpress は、そのフラグメントを探すとき、 Login/fragments フォルダの中を見ることになります

Page 48: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

48

例 : app2.js$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

loginForm.html を Login サービス・モジュールから読み込みます

ewd-xpress は、そのフラグメントを探すとき、 Login/fragments フォルダの中を見ることになります

⁻ fragments⁻ loginForm.html

⁻ lib⁻ Login.js

⁻ index.js⁻ package.json

Page 49: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

49

クライアント側の loginForm.jsvar loginForm = { loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: ‘login’, service: ‘Login’, params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

ログイン・メッセージには “ Login” サービスを用います。

Page 50: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

50

loginForm.js はサービスに含めるか?

• loginForm.js は、 loginForm.html フラグメントに対応するハンドラを定義しているので、これも Login サービスの一部とするのは賢明です• しかし、ブラウザは JavaScript を Node.js

モジュールから読み込むことはできません• 直接的にはできません

•2つのアプローチがあります ...

2016/9/8 EWD 3 トレーニング・コース #30

Page 51: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

51

Login モジュールに追加する

• ~/ewd3/www/demo1/loginForm.js を、• ~/ewd3/node_modules/Login/client/loginForm.js  にコピーする

2016/9/8 EWD 3 トレーニング・コース #30

⁻ client⁻ loginForm.js

⁻ fragments⁻ loginForm.html

⁻ lib⁻ Login.js

⁻ index.js⁻ package.json

Page 52: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

52

オプション 1• 発行し、他の人もインストール/利用できる

が、しかし• ~/ewd3/node_modules/Login/client/loginForm.js を、

• ~/ewd3/www/{ アプリケーション名 }/loginForm.js  にコピーする

2016/9/8 EWD 3 トレーニング・コース #30

⁻ client⁻ loginForm.js

⁻ fragments⁻ loginForm.html

⁻ lib⁻ Login.js

⁻ index.js⁻ package.json

Page 53: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

53

オプション 2: よりモダンなアプローチ

• 発行し、他の人もインストール/利用できる• バンドラ ( 例 Browserify または WebPack) を使う

• フロントエンドの JavaScript を Node.js を使っているかのように定義する• 即ち var loginForm = require(‘Login/client/loginForm’); とできます

• ブラウザが <script> タグを用いてロードできる単一の JavaScript に変換するためにパンドラを用いる

• しかし、 loginForm.js はモジュールとして書き換えなくてなりません• 後述 ...

2016/9/8 EWD 3 トレーニング・コース #30

⁻ client⁻ loginForm.js

⁻ fragments⁻ loginForm.html

⁻ lib⁻ Login.js

⁻ index.js⁻ package.json

Page 54: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

54

フロントエンドのモジュラー開発

• Browserify をインストールします• cd /ewd3• npm install babelify• npm install –g browserify

2016/9/8 EWD 3 トレーニング・コース #30

Page 55: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

55

クライアント側 JavaScript の NPM バージョン

• <script> タグを用いて読み込まれるライブラリはすべて、 Node.js モジュールとしてアクセスできる必要があります• 最近はほとんどはこのフォーマットで入手可

能です

• cd /ewd3• npm install toastr jquery socket.io-client• ewd-client はすでにモジュールとしてインス

トールされています

2016/9/8 EWD 3 トレーニング・コース #30

Page 56: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

56

loginForm.js を編集する

• Login モジュール内の、クライアント側のスクリプト・ファイル loginForm.js は、変更する必要があります• Node.js のモジュールである必要があります

• とても単純な変更です ...

2016/9/8 EWD 3 トレーニング・コース #30

⁻ client⁻ loginForm.js

⁻ fragments⁻ loginForm.html

⁻ lib⁻ Login.js

⁻ index.js⁻ package.json

Page 57: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

57

loginForm.js を編集するvar toastr = require(‘toastr’);var EWD;

module.exports = { init: function(ewd) { EWD = ewd; }, loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: ‘login’, service: ‘Login’, params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

Page 58: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

58

loginForm.js を編集するvar toastr = require(‘toastr’);var EWD;

module.exports = { init: function(ewd) { EWD = ewd; }, loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: ‘login’, service: ‘Login’, params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

Node.js モジュールは、完全に自給自足していなくてはなりません

toastr と EWD はどこかから来なくてはなりません

Page 59: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

59

loginForm.js を編集するvar toastr = require(‘toastr’);var EWD;

module.exports = { init: function(ewd) { EWD = ewd; }, loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: ‘login’, service: ‘Login’, params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

toastr の場合は、それを require() で呼び出すことができます

Page 60: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

60

loginForm.js を編集するvar toastr = require(‘toastr’);var EWD;

module.exports = { init: function(ewd) { EWD = ewd; }, loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: ‘login’, service: ‘Login’, params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

EWD についてはもう少し複雑です

loginForm.loader は、 send() API とセッション・トークンにアクセスする必要があるので、 EWD の登録後のバージョンを利用する必要があります

従って require(‘ewd-client’) という形では、これは登録前のものなので使うことができません

Page 61: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

61

loginForm.js を編集するvar toastr = require(‘toastr’);var EWD;

module.exports = { init: function(ewd) { EWD = ewd; }, loader: function(name) { $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val(); if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: ‘login’, service: ‘Login’, params: { username: username, password: password } }; EWD.send(message,function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); } }): }); }};

2016/9/8 EWD 3 トレーニング・コース #30

ひとつのアプローチは、 init() 関数を用いて EWD の登録後のバージョンをこのモジュールに渡せるようにすることです

これをどのように使うか、 app.js を見てください

Page 62: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

62

app.js を編集するvar io = require('socket.io-client');var jQuery =require('jquery');window.$ = window.jQuery = jQuery;var toastr = require('toastr');var EWD =require('ewd-client').EWD;var Login = require('Login/client/loginForm');

$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

Login.init(EWD); var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

この場合 app.js は require() を用いてすべてをロードする必要があります

Page 63: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

63

app.js を編集するvar io = require('socket.io-client');var jQuery =require('jquery');window.$ = window.jQuery = jQuery;var toastr = require('toastr');var EWD =require('ewd-client').EWD;var Login = require('Login/client/loginForm');

$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

Login.init(EWD); var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

jQuery の $ オブジェクトは、window のひとつのプロパティとしてインスタンス化される必要があります

これにより $ にはグローバルのスコープが設定されるので、他のモジュールは $ を require() で再び参照する必要はなくなります。

例えば loginForm.js の中でも $ が使われています

Page 64: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

64

app.js を編集するvar io = require('socket.io-client');var jQuery =require('jquery');window.$ = window.jQuery = jQuery;var toastr = require('toastr');var EWD =require('ewd-client').EWD;var Login = require('Login/client/loginForm');

$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

Login.init(EWD); var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

EWD オブジェクトは、 ewd-client モジュールから読み込まれます

Page 65: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

65

app.js を編集するvar io = require('socket.io-client');var jQuery =require('jquery');window.$ = window.jQuery = jQuery;var toastr = require('toastr');var EWD =require('ewd-client').EWD;var Login = require('Login/client/loginForm');

$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

Login.init(EWD); var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

そして、 Login サービス・モジュールから loginForm のコードを読み込みます

Page 66: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

66

app.js を編集するvar io = require('socket.io-client');var jQuery =require('jquery');window.$ = window.jQuery = jQuery;var toastr = require('toastr');var EWD =require('ewd-client').EWD;var Login = require('Login/client/loginForm');

$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

Login.init(EWD); var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

そして、 Login サービス・モジュールから loginForm のコードを読み込みます

そして登録後の EWD オブジェクトを loginForm に渡します

Page 67: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

67

app.js を編集するvar io = require('socket.io-client');var jQuery =require('jquery');window.$ = window.jQuery = jQuery;var toastr = require('toastr');var EWD =require('ewd-client').EWD;var Login = require('Login/client/loginForm');

$(document).ready(function() { EWD.log = true;

EWD.on('ewd-registered', function() {

EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); });

EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { location.reload(); },1000); });

Login.init(EWD); var params = { name: 'loginForm.html', targetId: 'loginFormDiv' service: 'Login' }; EWD.getFragment(params, loginForm.loader); });

EWD.start('demo1', $, io);});

2016/9/8 EWD 3 トレーニング・コース #30

そして、 Login サービス・モジュールから loginForm のコードを読み込みます

そして登録後の EWD オブジェクトを loginForm に渡します

これで loader 関数が getFragment のコールバックとして利用できるようになり、 EWD はメッセージを送信し、応答を処理することができるようになりました

Page 68: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

68

index.html を編集する

• CSS を読み込むための <link> タグはそのままにします• <script> タグはすべて取り除きますが、以下

は必要です• bundle.js• Browserify を用いてモジュラー化された

JavaScript を生成します

2016/9/8 EWD 3 トレーニング・コース #30

Page 69: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

69

index.html を編集する<html> <head> <title>Demo modularised ewd-xpress application</title> <link href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet" /> </head> <body>

<script src="bundle.js"></script>

<div id="loginFormDiv"></div> </body></html>

2016/9/8 EWD 3 トレーニング・コース #30

Page 70: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

70

では bundle ファイルを作ります

• cd /ewd3/www/demo1• browserify –t [ babelify ] app.js –o bundle.js

• エラーの報告がなければ、 demo1 のディレクトリに、 bundle.js ファイルができているはずです

2016/9/8 EWD 3 トレーニング・コース #30

Page 71: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

71

実行してみよう

• アプリケーションは前と同じように稼働するはずです• JavaScript コンソールを見て、 bundle.js

ファイルが使われていることを確かめてください

• これでアプリケーションを完全にモジュラー化できました• ログインに関係するものはすべて、独自の Login

サービスモジュールの中に定義することができました• これで、あなたのアプリケーションの中で再利用

が可能になりました2016/9/8 EWD 3 トレーニング・コース #30

Page 72: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

72

バンドリング : 注意点

• フロントエンドの JavaScript を何か変更した場合には、そのアプリケーションのコードや、そのモジュールを使うすべてのアプリケーションで Browserfy を再実行する必要があります• Browserify の代替として WebPack もあり

ます• こちらの方が良いという人もいるかもしれません

• bundle.js ファイルを最小化したいかもしれません• 例えば minify があります

2016/9/8 EWD 3 トレーニング・コース #30

Page 73: EWD 3トレーニングコース#30 ewd-xpressアプリケーションをモジュラー化する

73

自動化

• このトレーニング・コースの範囲外になりますが、今のトレンドは、このアプリケーション構築の自動化です• あるファイルが変更されると、それが引き金とな

り再構築をします• ファイルを bundle し、• 最小化し、• ユニット・テストし、• Git のリポジトリを更新する

• 例えば、 Gulp のよようなツールを用います

2016/9/8 EWD 3 トレーニング・コース #30