大阪node学園八時限目 「expressで作るwebアプリ」

50
大阪Node 学園八時限目 node.js ちし express で作Web 2013/10/26

Upload: shunsuke-watanabe

Post on 02-Dec-2014

2.829 views

Category:

Documents


2 download

DESCRIPTION

 

TRANSCRIPT

Page 1: 大阪Node学園八時限目 「expressで作るWebアプリ」

大阪Node学園八時限目

node.jsみちしるべ

expressで作るWebアプリ

2013/10/26

Page 2: 大阪Node学園八時限目 「expressで作るWebアプリ」

スライド内のリンクはクリックできます

リンクは ですこの色

Page 3: 大阪Node学園八時限目 「expressで作るWebアプリ」
Page 5: 大阪Node学園八時限目 「expressで作るWebアプリ」

express

Page 6: 大阪Node学園八時限目 「expressで作るWebアプリ」

expressとは

Webアプリケーションフレームワーク

現状node.jsでのデファクトスタンダード

sinatraライクなシンプルな構成

デフォルトテンプレートエンジンはjade

http://expressjs.com/

Page 7: 大阪Node学園八時限目 「expressで作るWebアプリ」

最新バージョンは 3.4.2大阪Node学園で取り上げるのも4回目になりました

express 2.x 系とはいろいろ変わってます

過去の情報を参照する際はバージョンに注意してく さい

私のブログとかヹヹヹ

Page 8: 大阪Node学園八時限目 「expressで作るWebアプリ」

expressのインスール

$ npm install -g express1

2

Page 9: 大阪Node学園八時限目 「expressで作るWebアプリ」

プロジェクトの初期化

expressコボンドでプロジェクトを初期化します

expressの依存モジュールをインストール

これでexpressが立ち上がるようになっているので動かしてみる。

ブラウザで http://localhost:3000 にアクセスする。

"Error: listen EADDRINUSE" エラーで動かない場合は p.ecstacy app.jsをテキストエディタで開き 15行目のホート番号を3000な に変

更します。

$ express handson1

$ cd handson

$ npm install

1

2

$ node app.js1

Page 10: 大阪Node学園八時限目 「expressで作るWebアプリ」
Page 11: 大阪Node学園八時限目 「expressで作るWebアプリ」

サーバ側の処理の追加

ブラウザから

Page 12: 大阪Node学園八時限目 「expressで作るWebアプリ」

サーバ側の処理の追加

Ctrl+C でサーバを停止し、サーバを再起動する。

ブラウザで http://localhost:3000/hello にアクセスしてみる。

"hello"と表示されます。

$ node app.js1

2

Page 13: 大阪Node学園八時限目 「expressで作るWebアプリ」

パスとイベントハンドラの追加の仕方

パスの追加

イベントハンドラの書き方

jQueryで

と書くのと比較すると覚えやすいかと思います。

app.HTTPメソッ 名('ルー か のURLパス', イベン ハン );1

function(req, res){

//ここでユーザか の入力値を け 、

//ユーザに返す ータを作る

}

1

2

3

4

5

$('#top').on('click', function(){

//イベン ハン ング

});

1

2

3

Page 14: 大阪Node学園八時限目 「expressで作るWebアプリ」

テンプレートで値を表示

先ほ の app.get('/hello', ...); では直接文字列を返していましたが テンプレ

ートを使ってHTMLを返すように変更してみます。

handson/views/ ディレクトリに hello.jade という新しいファイルを作って テキ

ストエディタで開きます。

内容を次のように書いてく さい。

ここで作成したファイルは jade というテンプレートエンジン用のテンプレートファ

イルです。

h1 こんにちは

p #{message} へようこそ

1

2

3

Page 15: 大阪Node学園八時限目 「expressで作るWebアプリ」

テンプレートで値を表示

app.js の res.send('Hello', ...); の部分を次のように変更します。

サーバを再起動してブラウザを再読み込みします。

こんにちは expressハンズオンへようこそ と表示されます。

app.get('/hello', function (req, res) {

// res.send('Hello'); この行は削除する

res.locals.message = 'expressハンズオン';

res.render('hello');

});

1

2

3

4

5

6

Page 16: 大阪Node学園八時限目 「expressで作るWebアプリ」

アプリケーションの自動リロード

スクリプトを変更するたびに手動でサーバの再起動をしてきました。

開発中は変更後に自動で再起動されたほうが便利なので、ツールを使って自

動化します。

nodemonというモジュールを使います

app.jsファイルを保存し直すと、サーバが自動で再起動されます

$ npm install -g nodemon

$ nodemon app.js

1

2

Page 17: 大阪Node学園八時限目 「expressで作るWebアプリ」

入力値の け取り クエリ引数編

ブラウザで http://localhost:3000/hello?greeting=hoge を開きます。

hoge という文字列はま こにも表示されていません。

この hoge という文字列をページに表示してみます。

app.get('/hello', ...); を次のように変更します。

サーバを再起動して 再度ブラウザでアクセスします。

こんにちは hogeへようこそ と表示されます。

app.get('/hello', function(req, res){

res.locals.message = req.query.greeting;

res.render('hello');

});

1

2

3

4

Page 18: 大阪Node学園八時限目 「expressで作るWebアプリ」

入力値の け取り URLパラメータ編

次に app.get('/hello') を次のように変更します

サーバを再起動し ブラウザで

http://localhost:3000/hello/fugaを開くと fugaへようこそ と と表示されます。

app.get('/hello/:greeting', function (req, res) {

res.locals.message = req.params.greeting;

res.render('hello');

});

1

2

3

4

5

Page 19: 大阪Node学園八時限目 「expressで作るWebアプリ」

入力値の け取り URLパラメータ編

この状態で http://localhost:3000/hello や http://localhost:3000/hello/ にアクセスするとエラーになるので

空のパラメータも け付けるようにするには :greeting? のようにパラメータの最

後に?をつけます。

:greeting がないときにデフォルトの値を表示するには

のようにします。

res.locals.message = req.params.greeting || ' フォル メッセージ';1

2

Page 20: 大阪Node学園八時限目 「expressで作るWebアプリ」

入力値の け取り POSTデータ編

hello.jade にフォームを追加します

ブラウザをリロードするとフォームが表示されるので

テキストフィールドに moga と入力して送信ボタンを押します。

Cannot POST /hello というエラーになります。

form(action="/hello", method="post")

input(type="text", name="greeting")

input(type="submit", value="送信")

1

2

3

Page 21: 大阪Node学園八時限目 「expressで作るWebアプリ」

入力値の け取り POSTデータ編

app.get('/hello'); は変更せ 、その後に次のように書きます。

サーバを再起動し 再度 フォームから値を送信してみます。

今度はエラーになら に mogaへようこそ 表示されます。

app.post('/hello', function(req, res){

res.locals.message = req.body.greeting;

res.render('hello');

});

1

2

3

4

5

Page 22: 大阪Node学園八時限目 「expressで作るWebアプリ」

GETとPOSTapp.get と app.post は同じURLパスでも別の処理として記述します。

GET データの取得に使われるHTTPメソッド

POST サーバにデータを送るときに使われるメソッド

HTTPメソッドの種類に関係なく常に処理を実行したい場合は app.all() が使え

ます

Page 23: 大阪Node学園八時限目 「expressで作るWebアプリ」

jadeでテンプレートを継承する

HTMLタグやHEADタグをすべてのテンプレートファイルに書くのは面倒なの

ひとつのファイルに書いた内容を他のファイルでも使うように変更します。

views/layout.jade ファイルがすでにあるので これを使ってみます。

テキストエディタで layout.jadeを開き block contentの行の後に一行追加し

ます。

block content

イアウ フォル コンテンツ

1

2

Page 24: 大阪Node学園八時限目 「expressで作るWebアプリ」

jadeでテンプレートを継承する

hello.jade をテキストエディタで開き いったんすべての内容を削除してから、

次のように変更します。

ブラウザをリロードすると

レイアウトデフォルトコンテンツ と表示されます。

extends layoutのあとに2行追加します

layout.jade にある block content の内容を上書きしています。

ブラウザでアクセスすると helloコンテンツ と表示されます。

extends layout1

2

extends layout

block content

h1 helloコンテンツ

1

2

3

4

Page 25: 大阪Node学園八時限目 「expressで作るWebアプリ」

アプリケーションワイドな値とブルパ

全てのビューで表示する値はあらかじめ設定しておくことができます。

app.js のルート設定の前に次の一行を追加します。

ブラウザをリロードして、ページのタイトルが変わっていることを確認します。

テンプレートで表示はしないが アプリケーション全体で共有したい設定値な

は app.set() で設定し app.get() で参照します。

app.locals.title = 'アプ ケーションワイ なサイ タイ ル';1

2

app.set('some_setting', 'some value');

app.get('some_setting'); // some value が返る

1

2

3

Page 26: 大阪Node学園八時限目 「expressで作るWebアプリ」

アプリケーションワイドな値とブルパ

app.locals には次のように関数を設定することもできます。

設定した関数はテンプレート内でブルパメソッドとして呼び出すことができま

す。

hello.jade でこのブルパを使ってみます。

app.locals.braced = function(str){

return '[' + str + ']';

}

1

2

3

p #{braced('カッコつき文字列')}1

2

Page 27: 大阪Node学園八時限目 「expressで作るWebアプリ」

セッション

セッションを使うには app.js に設定を追加します。

20行目の

の後に二行設定を追加します。

これでセッションが使えるようになりました。

express.sessionはデフォルトでメモリ上にセッション情報を保存するので実運

用には向きません

app.use(express.bodyParser());1

app.use(express.cookieParser());

app.use(express.session({key: 'sess_id', secret: 'salt'}));

1

2

3

Page 28: 大阪Node学園八時限目 「expressで作るWebアプリ」

セッション

セッションが使えることを確認するために

ダミーのログイン画面を作ってみましょう。

app.js にログイン画面用のルートを追加します。

views/login.jade を新規作成します。

app.get('/login', function(req, res){

res.render('login');

});

1

2

3

4

extends layout

block content

form(action="/login", method="post")

label ユーザ名

input(type="text", name="username")

input(type="submit", value="ログイン")

1

2

3

4

5

6

Page 29: 大阪Node学園八時限目 「expressで作るWebアプリ」

セッション

app.js にダミーのログイン処理を追加します。

http://localhost:3000/hello でログイン名を表示できるようにします。

app.post('/login', function(req, res){

req.session.username = req.body.username;

res.redirect('/hello');

});

1

2

3

4

5

app.get('/hello', function(req, res){

res.locals.username = req.session.username;

res.render('hello');

});

1

2

3

4

5

Page 30: 大阪Node学園八時限目 「expressで作るWebアプリ」

セッション

hello.jade にヤーザ名表示を表示します。

ブラウザで http://localhost:3000/login にアクセスします。

ヤーザ名を入力してログインボタンをクリックすると /hello にリダイレクトされ

入力したヤーザ名としてログインしています と表示されます。

p としてログインしています。1

2

Page 31: 大阪Node学園八時限目 「expressで作るWebアプリ」

イベントハンドラの分離

これまでにたくさんルートを追加して app.js が少し長くなったので

イベントハンドラを別ファイルに分離してすっきりさせます。

新しいファイル routes/handson.js をつくります。

app.js で今作成したファイルを読み込みます。

場所は app.get('/hello', ...); の前にします。

var handson = require('./routes/handson');

app.get('/hello', ...);

1

2

3

Page 32: 大阪Node学園八時限目 「expressで作るWebアプリ」
Page 33: 大阪Node学園八時限目 「expressで作るWebアプリ」

イベントハンドラの分離

次に app.js と routes/handson.js をつなげるため

いま handson.js に貼りつけたイベントハンドラに名前をつけます。

routes/handson.js

最後に 今名前をつけた関数を app.js で呼び出します。

app.js

exports.index = function(req, res){

res.locals.username = req.session.username;

res.render('hello');

}

1

2

3

4

5

app.get('/hello', handson.index);1

Page 34: 大阪Node学園八時限目 「expressで作るWebアプリ」

実行時の環境変数

サーバ実行時に環境変数を渡すことができます。

nodemonを使っている場合も同じです。

スクリプト内では process.env で環境変数を参照できます。

app.js の最後に以下の一行を追加してみます。

コンソールの最後にproduction と表示されます。

process.env の代わりに app.get('env') でも同じ結果を得られます。

$ NODE_ENV=production node app.js1

$ NODE_ENV=production nodemon app.js1

2

console.log(process.env.NODE_ENV);1

console.log(app.get('env'));1

Page 35: 大阪Node学園八時限目 「expressで作るWebアプリ」

入力値のエスケープ

express-validatorというexpress用のミドルウェアがあるのでそれを使います

インストール

--saveオプションをつけておくとインストールしたパッケージがpackage.jsonに

自動で追加されます

ミドルウェアの組み込み

app.jsの先頭でモジュールを読み込んで、

bodyParserの後でミドルウェアを有効にします。

https://github.com/ctavan/express-validator

$ npm install express-validator --save1

var validator = require('express-validator');

(略)

app.use(express.bodyParser());

app.use(validator());

(略)

1

2

3

4

5

Page 36: 大阪Node学園八時限目 「expressで作るWebアプリ」

lessのコンパイル

less.js-middlewareをインストールします

ミドルウェアを有効にします

app.use(express.static)の前に入れる必要があります

https://github.com/emberfeather/less.js-middlewarenpm install less-middleware

var lessMiddleware = require('less-middleware');

(略)

app.use(lessMiddleware({

dest: __dirname + '/public/css',

src: __dirname + '/public/less',

//force: true,

compress: true

}));

app.use(express.static(__dirname + '/public'));

(略)

Page 37: 大阪Node学園八時限目 「expressで作るWebアプリ」

データを保存する

今回はMongoDBを使います

MongoDBとは

ドキュメント指向データベース

node.jsでは最初期からモジュールがある

いまやIBM御用達

Page 38: 大阪Node学園八時限目 「expressで作るWebアプリ」

MongoDB用モジュール

MongoDB用のモジュールは大量に有ります

一番有名なのはmongooseですが、

私には使いにくいので今回はmongo-native-driverを紹 します

非公式モジュールから公式モジュールに格上げされました

Page 39: 大阪Node学園八時限目 「expressで作るWebアプリ」

mongo-native-driver

MongoDBのshellと同じような文法で書ける

多数のライブラリから利用されている

インストール

https://github.com/mongodb/node-mongodb-native

$ npm install mongodb --save1

Page 40: 大阪Node学園八時限目 「expressで作るWebアプリ」

モジュールの読み込みと初期化

MongoDBではDBとコレクション(テーブル)は自動で作成されます。

ファイルの前の方、モジュールのrequireをしている部分に以下のコードを追加

します。

続いて、ミドルウェア内でコネクションを初期化します

var mongoClient = require('mongodb').MongoClient;

var mongo = null;

1

2

3

app.use(function(req, res, next){

mongoClient.connect('mongodb://127.0.0.1:27017/handson',

function(err, db) {

if(err) throw err;

mongo = db;

next();

}

);

});

1

2

3

4

5

6

7

8

9

Page 41: 大阪Node学園八時限目 「expressで作るWebアプリ」

データの書き込み

\/helloにPOSTされたmessageをMongoDBに書き込んでみます。

hello.jade に次の二行を付け足すと、 (入力したメッセージ)が保存されました

と表示されます。

app.post('/hello', function(req, res){

var user_message = req.body.greeting;

var messages = mongo.collection('messages');

messages.insert({message: user_message}, function (err, doc) {

res.locals.message = doc[0].message;

res.render('hello');

});

});

1

2

3

4

5

6

7

8

if message

p が保存されました。

Page 42: 大阪Node学園八時限目 「expressで作るWebアプリ」

データの読み出し

/hello/list にアクセスした時に保存されたメッセージをすべて表示します

app.jsに以下のコードを追加します。

hello.jadeに以下のコードを追加します

ブラウザで http://localhost:3000/hello/list にアクセスすると保存したメッセ

ージの一覧が表示されます。

app.get('/hello/list', function (req, res) {

var messages = mongo.collection('messages');

messages.find().toArray(function (err, data) {

res.locals.data = data;

res.render('hello');

});

});

1

2

3

4

5

6

7

h2 保存されたメッセージ

ul

each datum in data

li= datum.message

1

2

3

4

Page 43: 大阪Node学園八時限目 「expressで作るWebアプリ」

asyncを使ったフローコントロール

フロー制御モジュール async

フローコントロールもたくさんモジュールがありますが、asyncが一番有名です。

並列実行、逐次処理、非同期処理の終了待ちな ができます。

フロー制御のほか、コレクションのイテレーションもできます。

https://github.com/caolan/async

Page 44: 大阪Node学園八時限目 「expressで作るWebアプリ」

asyncのインストール

インストール

他のモジュールと同じように、app.jsの先頭でrequireしておきます。

app.js

$ npm install async --save1

var async = require('async');1

Page 45: 大阪Node学園八時限目 「expressで作るWebアプリ」

asyncの例

MongoDBで登録されたメッセージの総数と一覧を取得してみます。

app.get('/hello/list', function (req, res) {

var messages = mongo.collection('messages');

async.parallel({

total: function (callback) {

messages.count(function (err, count) {

callback(err, count);

});

},

list: function (callback) {

messages.find().toArray(function (err, data) {

callback(err, data);

});

}

}, function (err, results) {

res.locals.data = results.list;

res.locals.total = results.total;

res.render('hello');

});

});

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Page 46: 大阪Node学園八時限目 「expressで作るWebアプリ」

asyncの例

3行目でasyncのパラレル処理を開始しています

3行目から14行目のparallelメソッドの第一引数がオブジェクトになっていま

第一引数はオブジェクトか配列になります

この第一引数に並列処理したい関数を渡します

第一引数内に置く関数にはデフォルトで関数が渡されます

処理が終了したらこの関数を呼び出して、明示的に終了を知らせます

全ての関数が終了すると14行目から18行目にある関数が呼び出されるの

で、ここで結果を け取ります

Page 47: 大阪Node学園八時限目 「expressで作るWebアプリ」

その他のフロー制御の方法

Promiseライブラリを使う方法Qが有名です(た し遅い)BlueBirdという速いのが出ている

generatorベースのライブラリを使う方法node 0.12.xから

で取り上げました第六回のスライドの後半

Page 48: 大阪Node学園八時限目 「expressで作るWebアプリ」

Q?

Page 49: 大阪Node学園八時限目 「expressで作るWebアプリ」

Thank you!

photo by from flickrNeilGHamilton

Page 50: 大阪Node学園八時限目 「expressで作るWebアプリ」

宣伝

半年ほ 前に本を書きました

HTML5とJavaScriptによるiPhone/Android両対応アプリ開発ガイド(DESIGN & WEB TECHNOLOGY)