目次


MEAN をマスターする

MEAN アプリケーションについて探る

HTTP リクエストをサーバー・サイドからクライアント・サイドまで追跡する

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: MEAN をマスターする

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:MEAN をマスターする

このシリーズの続きに乞うご期待。

MEAN をマスターする: MEAN スタックの紹介」では、MEAN 開発環境をインストールして構成しました。今回のチュートリアルでは、MEAN スタックの主要な 4 つの構成要素を十分に理解できるように、前回作成したサンプル MEAN.JS アプリケーションについて詳しく探ります。この MEAN.JS アプリケーションについて探るツアーでは、受信される HTTP リクエストをサーバー・サイドからクライアント・サイドまで追跡します。

まずは、「mongod」と入力してローカル MongoDB インスタンスを起動してください (または、UNIX ライクなオペレーティング・システムを使用している場合は、「mongod &」と入力すると、バックグラウンドでプロセスを起動することができます)。次に、cd を実行してカレント・ディレクトリーを前回のチュートリアルで作成したテスト・ディレクトリーに変更し、「grunt」と入力して Yeoman ジェネレーターで作成したアプリケーションを起動します。すると、リスト 1 に示すような出力が表示されます。

リスト 1. ローカル MEAN.JS アプリケーションを起動する
$ grunt
Running "jshint:all" (jshint) task
>> 46 files lint free.

Running "csslint:all" (csslint) task
>> 2 files lint free.

Running "concurrent:default" (concurrent) task
Running "nodemon:dev" (nodemon) task
Running "watch" task
Waiting...
[nodemon] v1.0.20
[nodemon] to restart at any time, enter 'rs'
[nodemon] watching: app/views/**/*.* gruntfile.js server.js config/**/*.js app/**/*.js
[nodemon] starting 'node --debug server.js'
debugger listening on port 5858

 NODE_ENV is not defined! Using default development environment

MEAN.JS application started on port 3000

ブラウザーで http://localhost:3000 を開き、アプリケーションのホーム・ページを表示します (図 1 を参照)。

図 1. ローカル MEAN.JS アプリケーションのホーム・ページ
ローカル MEAN.JS アプリケーションのホーム・ページのスクリーンショット
ローカル MEAN.JS アプリケーションのホーム・ページのスクリーンショット

ディレクトリー構造をひと通り見渡して、何がこのアプリケーションを駆動しているのか調べてください (詳しくは、MEAN.JS ドキュメントの「Folder Structure」ページを参照してください)。

ディレクトリー構造をひと通り見渡して、何がこのアプリケーションを駆動しているのか調べてください。

Node.js および Bower 構成ファイルの概要

ソース・コードに取り掛かる前に、前回のチュートリアルで説明した package.json という Node.js 構成ファイルについてざっと復習します。また、クライアント・サイドでこの構成ファイルに相当する bower.json についても簡単に説明しておきます。この両方のファイルは、プロジェクトのルート・ディレクトリーにあります。

package.json

どの Node.js アプリケーションにおいても最も重要な構成ファイルは、ほぼ間違いなく package.json です。このファイルには、Yeoman ジェネレーターに提供したアプリケーションに関するメタデータ (名前、説明、作成者など) が格納されています。該当する部分を package.json から抜粋してリスト 2 に示します。

リスト 2. package.json (パート 1)
{
  "name": "test",
  "description": "Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js",
  "version": "0.0.1",
  "author": "Scott Davis",
  "engines": {
    "node": "0.10.x",
    "npm": "1.4.x"
  },

次に、コマンド・プロンプトで入力できる一連のコマンドを抜粋してリスト 3 に示します。

リスト 3. package.json (パート 2)
"scripts": {
  "start": "grunt",
  "test": "grunt test",
  "postinstall": "bower install --config.interactive=false"
},

上記コマンドのうち、既に「grunt」と入力してアプリケーションを起動しました。後で、「grunt test」と入力してユニット・テストを実行します。postinstall フックは、サーバー・サイドの依存関係とクライアント・サイドの依存関係を区別する最初のヒントです。

しかし、この最も重要なファイルの最も重要な部分には、アプリケーションの依存関係が一覧にされています (リスト 4 を参照)。これらの CommonJS モジュールはすべて、アプリケーションのサーバー・サイドで実行されます。

リスト 4. package.json (パート 3)
"dependencies": {
  "express": "~4.2.0",
  "mongoose": "~3.8.8"
},
"devDependencies": {
  "grunt-mocha-test": "~0.10.0",
  "grunt-karma": "~0.8.2",
  "karma": "~0.12.0",
  "karma-jasmine": "~0.2.1",
  "karma-coverage": "~0.2.0",
  "karma-chrome-launcher": "~0.1.2",
  "karma-firefox-launcher": "~0.1.3",
  "karma-phantomjs-launcher": "~0.1.2"
}

ランタイム依存関係 (ルーティング用の Express や、MongoDB に接続するための Mongoose など) は dependencies ブロックで宣言され、開発者によるビルド時の依存関係 (Mocha、Jasmine、Karma などのテスト・フレームワークを含む) は devDependencies ブロックで宣言されます。

bower.json

今度はクライアント・サイドに焦点を移します。ブラウザーにロードされる JavaScript ライブラリーは、bower.json で定義されます (リスト 5 を参照)。

リスト 5. bower.json
{
  "name": "test",
  "version": "0.0.1",
  "description": "Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js",
  "dependencies": {
    "bootstrap": "~3",
    "angular": "~1.2",
    "angular-resource": "~1.2",
    "angular-mocks": "~1.2",
    "angular-cookies": "~1.2",
    "angular-animate": "~1.2",
    "angular-touch": "~1.2",
    "angular-sanitize": "~1.2",
    "angular-bootstrap": "~0.11.0",
    "angular-ui-utils": "~0.1.1",
    "angular-ui-router": "~0.2.10"
  }
}

ご覧のように bower.json は package.json と似ており、bower.json には package.json と同じメタデータ・フィールドがあります。また、このファイルでも dependencies ブロックを使用して、Bootstrap (ルック・アンド・フィールに加え、レスポンシブ Web デザインに対応) や AngularJS (クライアント・サイドのシングル・ページ・アプリケーションに対応) といったクライアント・サイドの依存関係を定義しています。

アプリケーションのソース・コードも同じく、サーバー・サイド用のディレクトリーとクライアント・サイド用のディレクトリーという 2 つの主要なディレクトリーに分けられています。

ディレクトリー構造の概要

この MEAN アプリケーションには、4 つの主要なディレクトリーがあります (リスト 6 を参照)。

リスト 6. MEAN ディレクトリー構造
$ ls -ld */
drwxr-xr-x+  7 scott  staff   238 Jun  6 14:06 app/
drwxr-xr-x+  8 scott  staff   272 Jun  6 14:06 config/
drwxr-xr-x+ 49 scott  staff  1666 Jun  6 14:07 node_modules/
drwxr-xr-x+  8 scott  staff   272 Jun  6 14:06 public/
app
サーバー・サイドのソース・コードを格納します。
config
構成ファイルを格納します。
node_modules
package.json で指定されたサーバー・サイドのモジュールを格納します。
public
クライアント・サイドのソース・コードを格納します。このディレクトリー内には、bower.json で指定されたクライアント・サイドのライブラリーを格納する lib ディレクトリーもあります。

これから、app および public ディレクトリー内にある成果物にフォーカスします。アプリケーションのホーム・ページ用の理解しにくいソース・コードを理解する作業は、app ディレクトリーから始まります。

MEAN スタックのサーバー・サイドを探る

リスト 7 に、app ディレクトリー構造を示します。

リスト 7. app (サーバー・サイド) ディレクトリー構造
$ tree app
app
|--- controllers
|鐃緒申 |--- articles.server.controller.js
|鐃緒申 |--- core.server.controller.js
|鐃緒申 |--- users.server.controller.js
|--- models
|鐃緒申 |--- article.server.model.js
|鐃緒申 |--- user.server.model.js
|--- routes
|鐃緒申 |--- articles.server.routes.js
|鐃緒申 |--- core.server.routes.js
|鐃緒申 |--- users.server.routes.js
|--- tests
|鐃緒申 |--- article.server.model.test.js
|鐃緒申 |--- user.server.model.test.js
|--- views
    |--- 404.server.view.html
    |--- 500.server.view.html

    |--- index.server.view.html
    |--- layout.server.view.html

サーバー・サイドの MVC アプリケーションを作成したことがある読者の方は、以下の典型的なワークフローをご存知のはずです。

  1. 受信される HTTP リクエストがルーターに到着します。
  2. ルーターがリクエストを渡すのに適切なコントローラーを見つけます。
  3. コントローラーはデータベースからモデル (またはモデルのリスト) を作成して、それをビューに渡します。
  4. ビューはモデルとテンプレートを組み合わせて HTML ページを作成し、完成した出力を待機中の HTTP レスポンスに渡します。

リスト 8 に記載する app/routes/core.server.routes.js ファイル (Express フレームワークの一部) に、アプリケーションへの主要なエントリー・ポイントが保持されています。

リスト 8. app/routes/core.server.routes.js
'use strict';

module.exports = function(app) {
  // Root routing
  var core = require('../../app/controllers/core');
  app.route('/').get(core.index);
};

このルーターが定義する単一のルート (/) は、コア・コントローラーの index 関数によって処理されます。コア・コントローラーは、require で読み込まれた CommonJS モジュールであることに注意してください。

リスト 8 の先頭にある 'use strict' 文は、JavaScript ランタイムを Strict モードにします。Strict モードは、構文に関して「何でもあり」という、かつての JavaScript のように寛容ではありません。Strict モードでの JavaScript ランタイムは、うっかりミス (変数を誤ってグローバル変数にしてしまったとか、前に定義されていなかった変数を使用しようとしている、などのミス) を構文エラーとして扱います。Strict モードは JSHint と相まって、構文エラーが本番においてではなく開発時にキャッチされるように多くのことを行います (もちろん、リリースからバグを一切なくす最終的なかぎは、ユニット・テストでの適切なコード・カバレッジです)。

次に、リスト 9 に記載する app/controllers/core.server.controller.js を見てください (同じく Express フレームワークの一部です)。

リスト 9. app/controllers/core.server.controller.js
'use strict';

/**
 * Module dependencies.
 */
exports.index = function(req, res) {
  res.render('index', {
    user: req.user || null
  });
};

index 関数は受信される HTTP リクエストと送信される HTTP レスポンスを受け入れます。この特定のリクエストにはデータベースのデータは必要ないため、インスタンス化されるモデルはありません。index テンプレートが変数の JSON ブロックとともにレスポンスにレンダリングされ、テンプレート内でこれらの変数と同じ名前を持つプレースホルダーは置き換えられて、これらの変数の値に代わります。

次に記載するのは、app/views/index.server.view.html です (リスト 10 を参照)。

リスト 10. app/views/index.server.view.html
{% extends 'layout.server.view.html' %}

{% block content %}
  <section data-ui-view></section>
{% endblock %}

ここには特に注目する内容はありませんが、app/views/layout.server.view.html (リスト 11 を参照) のリンクは期待できそうです。

リスト 11. app/views/layout.server.view.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">

<head>
  <title>{{title}}</title>

  <!-- General META -->
  <meta charset="utf-8">
  <meta http-equiv="Content-type" content="text/html;charset=UTF-8">

  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width,initial-scale=1">

  <!-- Semantic META -->
  <meta name="keywords" content="{{keywords}}">
  <meta name="description" content="{{description}}">

ここからは、お馴染みの HTML が登場してきます。titlekeywordsdescription は、{{}} デリミターに囲まれているため、実際の値で置き換えられるように意図された Swig プレースホルダーとして識別されます。Swig は、MEAN.JS Yeoman ジェネレーターによってインストールされるテンプレート・エンジンです。

リスト 9core コントローラーをもう一度見てみると、このテンプレートに渡される値は user だけであることがわかります。他のプレースホルダーは構成ファイルのどこかで定義されているデフォルト値だろうと思ったとしたら、それは的外れではありません。

構成および環境の概要

リスト 12 の config/env/all.js に示されている、titledescription、および keywords 変数に注目してください (私はディレクトリー構造全体にわたって検索を行って、これらの値が定義されている場所を見つけました。この手法は、MEAN スタックについて理解するために行う探索手段に加えておくことをお勧めします)。

リスト 12. config/env/all.js
'use strict';

module.exports = {
  app: {
    title: 'Test',
    description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
    keywords: 'MongoDB, Express, AngularJS, Node.js'
  },
  port: process.env.PORT || 3000,
  templateEngine: 'swig',

このファイルには、テンプレートが要求するキーワードの他にも、porttemplateEngine など、興味深い値があります。

環境変数

PORTNODE_ENV の 2 つは、アプリケーション内部の動作を変更するためにアプリケーションの外部で設定できる環境変数の例です。例えば、config/env/all.js での port の設定は以下のようになっています。

port: process.env.PORT || 3000,

上記の設定はアプリケーションに対し、「内部 port 変数を PORT 環境変数の値に設定するか、PORT 環境変数が見つからない場合はデフォルト値の 3000 に設定する」ように指示しています。

この設定をテストするために、Ctrl+C を押してアプリケーションを停止してください。オプションの設定なしで grunt コマンドを実行してアプリケーションを再起動するのではなく、PORT=4000 grunt で再起動します。これで、アプリケーションはポート 4000 で実行されるようになります。

Node.js アプリケーションをコーディングする際には、アプリケーションを実行するランタイム環境のタイプ (開発環境、本番環境、ステージング環境、テスト環境など) に応じて異なる動作をするようにコーディングすることができます。PORT 環境変数の場合と同様に、Express では、NODE_ENV 環境変数に対してランタイム環境を指定する値が明示的に設定されなければ、この環境変数にはデフォルト値 (development) を設定します。アプリケーションを再起動したときに出力される下記の軽めの警告は、以上の内容を警告したものになっています。

NODE_ENV is not defined! Using default development environment

ランタイム構成を環境変数で外部化するのは、柔軟性を加える賢明な方法です。PORTNODE_ENV などの環境変数は、コマンド・ラインで一時的に設定することができるので、開発やテストを行う目的で簡単に変数の値を変更することができます (もちろん、これらの変数を .bash_profile に追加したり、Windows の場合は「コンロトール パネル」の中で設定したりすることで、変数をもっと長い時間、有効にすることができます)。

セキュリティー上の理由からも、環境変数を使用することをお勧めします。ユーザー名、パスワード、接続 URL を環境変数に格納すれば、セキュリティーが侵害される可能性のある構成ファイル (さらにはソース管理) から、これらの値を切り離すことができます。また、この手法では簡単に、複数の開発者や本番マシンに共通の構成ファイル一式を採用し、ローカル環境変数を介してマシンごとに固有の値や資格情報を注入することも可能になります。

こうしたことは、PORT 環境変数と NODE_ENV 環境変数に限られたことではありません。PaaS (Platform as a Service) では一般に、サービス固有の変数が複数用意されていて、ユーザーが設定できるようになっています。

名前付き環境

環境変数を設定するのでも構いませんが、関連する変数の集まりを一斉に変更しなければならない場合もあります。例えば、ユーザー名を変更して対応するパスワードを変更しないという、うっかりミスは避けたいものです。幸い、この MEAN アプリケーションは「名前付き環境」の概念をサポートしています (この概念は MEAN アプリケーションに特有のものではありません。Rails や Grails をはじめ、よく使われている多くの Web フレームワークでも同様の機能を提供しています)。

リスト 13 のディレクトリー・ツリーで config/env を見ると、複数の名前付き環境ファイルが配置されていることがわかります。

リスト 13. config ディレクトリー構造
$ tree config/
config/
|--- config.js
|--- env
|鐃緒申 |--- all.js
|鐃緒申 |--- development.js
|鐃緒申 |--- production.js
|鐃緒申 |--- test.js
|--- express.js
|--- init.js
|--- passport.js
|--- strategies
    |--- facebook.js
    |--- google.js
    |--- linkedin.js
    |--- local.js
    |--- twitter.js
2 directories, 13 files

config/env に格納されている development.js、production.js、test.js は、いずれも名前付き環境を指定しています。もし皆さんが all.js にはすべての環境に共通の値が格納されていると推測したのであれば、自分を褒めてあげてください。

これらのファイルが読み取られて結合される場所を確認するには、config/config.js を調べてください (リスト 14 を参照)。

リスト 14. config/config.js
/**
 * Module dependencies.
 */
var _ = require('lodash');

/**
 * Load app configurations
 */
module.exports = _.extend(
  require('./env/all'),
  require('./env/' + process.env.NODE_ENV) || {}
);

Lo-dash は、配列、オブジェクト、JSON 構造を扱うためのコンビニエンス関数を提供する CommonJS モジュールです。リスト 14 で開発者が意図しているのは、all.js にベースとなる値を設定しておき、これらの値を development.js (またはproduction.js あるいは test.js) の値で上書きできるようにすることです。

config/env/all.js はリスト 12 に記載したので、今度はリスト 15 に config/env/development.js を記載します。

リスト 15. config/env/development.js
'use strict';

module.exports = {
  db: 'mongodb://localhost/meanjs-dev',
  app: {
    title: 'MeanJS - Development Environment'
  },

理想的であれば、lodash.extend 関数によって 2 つの JSON ブロックが結合されて、以下のような結果となります。

app: {
  title: 'MeanJS - Development Environment',
  description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
  keywords: 'MongoDB, Express, AngularJS, Node.js'
}

残念ながら、上記の出力にはなりません。結合された構造を config/config.jsに出力するために、リスト 16 に示すコード行を追加してください。

リスト 16. 結合された実際の結果をコンソールにログ出力する
/**
 * Load app configurations
 */
module.exports = _.extend(
    require('./env/all'),
    require('./env/' + process.env.NODE_ENV) || {}
);
console.log(module.exports)

PORT=4000 NODE_ENV=development grunt」と入力して、アプリケーションを再実行します。すると、コンソールに以下の結果が表示されます。

app: { title: 'MeanJS - Development Environment' }

config/env/development.js 内の JSON 構造は、config/env/all.js の構造と結合するのではなく、これを上書きしているようです。幸い、config/config.js に簡単な変更を加えることで、期待する結果を得ることができます。

関数呼び出しを _.extend から _.merge に変更してください。これでアプリケーションをもう一度再実行すると、期待する結果が表示されるはずです。

app: 
   { title: 'MeanJS - Development Environment',
     description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
     keywords: 'MongoDB, Express, AngularJS, Node.js' },

ブラウザーで、ホーム・ページを表示して「View (表示)」 > 「Source (ソース)」の順にクリックすると、HTML テンプレートと結合された config 値を確認することができます (リスト 17 を参照)。

リスト 17. 適切に結合された結果の HTML ソース
<head>
  <title>MeanJS - Development Environment</title>

  <!-- Semantic META -->
  <meta name="keywords" content="MongoDB, Express, AngularJS, Node.js">
  <meta name="description" content="Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js">

次は、サーバー・サイドからクライアント・サイドに移って、この MEAN アプリケーションについて探るツアーを締めくくります。

MEAN スタックのクライアント・サイドを探る

ホーム・ページの主要な部分 (リスト 18 に記載する app/views/layout.server.view.html で定義されている部分) は、クライアント・サイドの AngularJS によって入力されます。

リスト 18. app/views/layout.server.view.html
<body class="ng-cloak">
  <header data-ng-include="'/modules/core/views/header.client.view.html'" 
  class="navbar navbar-fixed-top navbar-inverse"></header>
  <section class="content">
    <section class="container">
      {% block content %}{% endblock %}
    </section>
  </section>

app ディレクトリーには、MEAN アプリケーションの Express サーバー・サイドの部分が格納されていることを思い出してください。header が AngularJS によってクライアント・サイドで管理されていることを示唆する点は 2 つあります。まず、HTML 属性の値に「ng」が含まれている場合は、AngularJS がその属性を管理していることを示唆します。より実際的なもう 1 つの点は、サーバー・サイドのすべてのコードを格納する app ディレクトリー内に、modules ディレクトリーがないことです。考えられるソリューションとしてサーバー・サイドを除外するとなると、クライアント・サイドのソース・コードは public ディレクトリー内にあることになります。modules ディレクトリーは明らかに public ディレクトリー配下にあります (リスト 19 を参照)。

リスト 19. public (クライアント・サイド) ディレクトリー構造
$ tree -L 1 public/
public/

|--- application.js
|--- config.js
|--- lib
|--- modules

lib には、複数のサード・パーティー・ライブラリーが含まれています。

リスト 20. サード・パーティー・ライブラリー用の public/lib ディレクトリー
$ tree -L 1 public/lib
public/lib
|--- angular
|--- angular-animate
|--- angular-bootstrap
|--- angular-cookies
|--- angular-mocks
|--- angular-resource
|--- angular-sanitize
|--- angular-touch
|--- angular-ui-router
|--- angular-ui-utils
|--- bootstrap
|--- jquery

これらのライブラリーは、bower.json で指定されているライブラリーであることを思い出してください。

一方、modules ディレクトリーをいろいろと調べて回ると、app/views/layout.server.view.html に指定されている modules/core/views/header.client.view.html テンプレートが見つかります。

リスト 21. modules/core/views/header.client.view.html
<div class="container" data-ng-controller="HeaderController">
  <div class="navbar-header">
    <button class="navbar-toggle" type="button" data-ng-click="toggleCollapsibleMenu()">
      <span class="sr-only">Toggle navigation</span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </button>
    <a href="/#!/" class="navbar-brand">MeanJS</a>
  </div>

class="navbar-brand" アンカーの対象を MeanJS から別の値に変更すると、ファイルを保存した直後にその変更がブラウザーに反映されます。しかし、メイン・ペイロード (ホーム・ページの主要なコンテンツ) へ辿り着くにはもっと回り道をすることになります。もう一度、app/views/layout.server.view.html を見てください (リスト 22 を参照)。

リスト 22. app/views/layout.server.view.html
<body class="ng-cloak">
  <header data-ng-include="'/modules/core/views/header.client.view.html'" 
  class="navbar navbar-fixed-top navbar-inverse"></header>
  <section class="content">
    <section class="container">
      {% block content %}{% endblock %}
    </section>
  </section>

container セクションの内部に、content という名前の block があります。無味乾燥に見える app/views/index.server.view.html を思い出してください。

{% extends 'layout.server.view.html' %}

{% block content %}
  <section data-ui-view></section>
{% endblock %}

上記の block content には、data-ui-view 属性を持つ空のセクションが含まれています。この属性は、クライアント・サイドの AngularJS ルーターが使用します。次に、public/modules/core/config/core.client.routes.js を見てください (リスト 23 を参照)。

リスト 23. app/views/index.server.view.html
'use strict';

// Setting up route
angular.module('core').config(['$stateProvider', '$urlRouterProvider',
  function($stateProvider, $urlRouterProvider) {
    // Redirect to home view when route not found
    $urlRouterProvider.otherwise('/');

    // Home state routing
    $stateProvider.
    state('home', {
      url: '/',
      templateUrl: 'modules/core/views/home.client.view.html'
    });
  }
]);

直感的には明らかでありませんが、このクライアント・サイドのルーターは URLが / の場合、app/views/index.server.view.html の data-ui-view 属性が含まれるセクションに modules/core/views/home.client.view.html テンプレート (リスト 24 を参照) を注入します。このテンプレートのコンテンツは、MEAN アプリケーションのホーム・ページにアクセスしているときにブラウザーに表示される内容と一致するはずです。

リスト 24. modules/core/views/home.client.view.html
<section data-ng-controller="HomeController">
    <h1 class="text-center">THANK YOU FOR DOWNLOADING MEAN.JS</h1>
    <section>
        <p>
          Before you begin we recommend you read about the basic building 
          blocks that assemble a MEAN.JS application:
        </p>

まとめ

今回のチュートリアルでは、MEAN アプリケーションの重要な部分を 1 つひとつ探りました。サーバー・サイドでは、パスが Express ルートで始まること、それによって Express コントローラーの関数が呼び出されること、そしてこれらの関数が JSON データを Swig テンプレートに結合してクライアントに返すことを説明しました。しかし、プロセスはこれで終わりではありません。クライアント・サイドでは、AngularJS ルートが HTML テンプレートを取得してメイン・ページに注入します。

次回は、アプリケーションの記事の部分を探ることにより、MongoDB が AngularJS とともに果たす役割を詳しく調べます。また、サーバー・サイドとクライアント・サイドの両方でテストを行い、本番での予期せぬ動作を最小限に抑える方法についても説明します。

それまでは、楽しみながら MEAN スタックをマスターしてください。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source
ArticleID=989669
ArticleTitle=MEAN をマスターする: MEAN アプリケーションについて探る
publish-date=11202014