精通 MEAN: MEAN 堆棧

精通 MEAN: MEAN 堆棧

端到端地開發現代的、全堆棧的二十一世紀 Web 項目javascript

Web 開發專家 Scott Davis 將在一個包含 6 篇文章的文章系列中,使用 MongoDB、Express、AngularJS 和 Node.js 構建一個現代的 Web 應用程序。本文是該文章系列的第一篇文章,其中包含一些演示和示例代碼,並對建立一個基礎的 MEAN 應用程序進行了完整介紹。您還將瞭解 Yeoman 生成器,您可使用它快速地輕鬆建立一個新的 MEAN 應用程序。css

Scott Davis, 創始人, IBMhtml5

2014 年 10 月 30 日java

  • +內容node

在 IBM Bluemix 雲平臺上開發並部署您的下一個應用。git

在 2002 年的一本著做中,David Weinberger 將發展迅速的 Web 內容描述成一個 小塊鬆散組合(Small Pieces Loosely Joined)。這個比喻讓我印象深入,由於你們通常很容易認爲 Web 是一個巨大的技術堆棧。實際上,您訪問的每一個網站都是庫、語言與 Web 框架的一種獨特組合。 github

LAMP 堆棧 是早期表現突出的開源 Web 技術集合之一:它使用 Linux 做爲操做系統,使用 Apache 做爲 Web 服務器,使用 MySQL 做爲數據庫,並使用 Perl(或者 Python 和 PHP)做爲生成基於 HTML Web 頁面的編程語言。這些技術的出現並不是爲了一塊兒聯合工做。它們是獨立的項目,由多位雄心勃勃的軟件工程師前赴後繼地整合在一塊兒。自那之後,咱們就見證了 Web 堆棧的大爆發。每一種現代編程語言彷佛都有一個(或兩個)對應的 Web 框架,可將各類混雜的技術預先組裝在一塊兒,快速而又輕鬆地建立一個新的網站。web

MEAN 堆棧是 Web 社區中贏得大量關注和使人興奮的一種新興堆棧:MongoDBExpressAngularJS 和 Node.js。MEAN 堆棧表明着一種徹底現代的 Web 開發方法:一種語言運行在應用程序的全部層次上,從客戶端到服務器,再到持久層。本系列文章演示了一個 MEAN Web 開發項目的端到端開發狀況,但這種開發並不只限於簡單的語法。本文將經過做者的親身實踐向您深刻淺出地介紹了該堆棧的組件技術,包括安裝與設置。參見 下載 部分,以便獲取示例代碼。 

關於本系列

在使用開源軟件構建專業網站領域時,MEAN(MongoDB、Express、AngularJS 和 Node.js)堆棧是對流行已久的 LAMP 堆棧的一個新興挑戰者。MEAN 表明着架構與心理模型(mental model)方面的一次重大變遷:從關係數據庫到 NoSQL,以及從服務器端的模型-視圖-控制器到客戶端的單頁面應用程序。本系列文章將介紹 MEAN 堆棧技術如何互補,以及如何使用堆棧建立二十一世紀的、現代的全堆棧 JavaScript Web 應用程序。 

實際上,您訪問的每一個網站都是庫、語言與 Web 框架的獨特組合。


從 LAMP 到 MEAN

MEAN 不只僅是一次首字母縮寫的簡單從新安排與技術升級。將基礎平臺從操做系統 (Linux) 轉變爲 JavaScript 運行時 (Node.js) 讓操做系統變得獨立:Node.js 在 Windows 與 OS X 上的運行狀況和在 Linux 上同樣優秀。 

Node.js 一樣取代了 LAMP 堆棧中的 Apache。但 Node.js 遠遠不止是一種簡單的 Web 服務器。事實上,用戶不會將完成後的應用程序部署到單機的 Web 服務器上;相反,Web 服務器已經包含在應用程序中,並已在 MEAN 堆棧中自動安裝。結果,部署過程獲得了極大簡化,由於所需的 Web 服務器版本已經與餘下的運行時依賴關係一塊兒獲得了明肯定義。 

不只是 MEAN

儘管本系列文章重點講述的是 MEAN 太陽系中的四大行星,但也會介紹 MEAN 堆棧中的一些較小的(但並不是不重要的)衛星類技術: 

  • Yeoman:一種功能強大的命令行開發工具組合,用於基架 (Yo)、編譯腳本 (Grunt) 與客戶端依賴關性管理 (Bower)。

  • Bootstrap:一個 CSS 庫,支持開箱即用的移動端 響應式 Web 設計

  • 測試庫:除了 Mocha、Jasmine 和 Karma 之外,還有大量測試庫可用於模擬 Ajax 調用 (Chai),顯示測試範圍 (Istanbul),以及自動完成功能測試,以便在實際的瀏覽器中 運行它們(Protractor)。

從傳統數據庫(如 MySQL)到 NoSQL,再到無架構的、以文檔爲導向的持久存儲(如 MongoDB),這些表明着持久化策略發生了根本性的轉變。用戶花費在編寫 SQL 上的時間將會減小,將會有更多的時間編寫 JavaScript 中的映射/化簡功能。用戶還能省掉大量的轉換邏輯,由於 MongoDB 能夠在本地運行 JavaScript Object Notation (JSON)。所以,編寫 RESTful Web 服務變得史無前例的容易。 

但從 LAMP 到 MEAN 的最大轉變在於從傳統的服務器端頁面生成變爲客戶端 單頁面應用程序 (SPA)。藉助 Express 仍然能夠處理服務器端的路由與頁面生成,但目前的重點在客戶端視圖上,而 AngularJS 能夠實現這一點。這種變化並不只僅是將 模型-視圖-控制器 (MVC) 工件從服務器轉移到客戶端。用戶還要嘗試從習慣的同步方式轉而使用基本由事件驅動的、實質上爲異步的方式。或許最重要的一點是,您將從以頁面爲中心的應用程序視圖轉到面向組件的視圖。 

MEAN 堆棧並不是以移動爲中心,AngularJS 在桌面電腦、筆記本電腦、智能手機、平板電腦和甚至是智能電視上的運行效果都同樣,但它不會把移動設備看成二等公民對待。並且測試過後再也不是問題:藉助世界級的測試框架,好比MochaJSJasmineJS 和 KarmaJS,您能夠爲本身的 MEAN 應用程序編寫深刻而又全面的測試套件。 

準備好得到 MEAN 了嗎?

安裝 Node.js

您須要安裝 Node.js,以便在本系列中的示例應用程序上工做,若是還沒有安裝它,那就馬上開始安裝吧。 

若是使用 UNIX 風格的操做系統(Linux、Mac OS X 等),我推薦使用 Node Version Manager (NVM)。(不然,在 Node.js 主頁上單擊Install,下載適合您操做系統的安裝程序,而後接受默認選項便可。)藉助 NVM,您能夠輕鬆下載 Node.js,並從命令行切換各類版本。這能夠幫助您從一個版本的 Node.js 無縫轉移到下一版本,就像我從一個客戶項目轉到下一個客戶項目同樣。 

NVM 安裝完畢後,請輸入命令 nvm ls-remote 查看哪些 Node.js 版本可用於安裝,如清單 1 中所示。 

清單 1. 使用 NVM 列出可用的 Node.js 版本
$ nvm ls-remote

v0.10.20

v0.10.21
v0.10.22
v0.10.23
v0.10.24
v0.10.25
v0.10.26
v0.10.27
v0.10.28

輸入 nvm ls 命令能夠顯示本地已經安裝的 Node.js 版本,以及目前正在使用中的版本。

在撰寫本文之際,Node 網站推薦 v0.10.28 是最新的穩定版本。輸入 nvm install v0.10.28 命令在本地安裝它。 

安裝 Node.js 後(經過 NVM 或平臺特定的安裝程序都可),能夠輸入 node --version 命令來確認當前使用的版本:

$ node --version

v0.10.28

什麼是 Node.js?

Node.js 是一種 headless JavaScript 運行時。它與運行在 Google Chrome 內的 JavaScript 引擎(名叫 V8)是同樣的,但使用 Node.js 能夠從命令行(而非瀏覽器)運行 JavaScript。 

訪問瀏覽器的開發人員工具

熟悉本身所選瀏覽器中的開發人員工具。我將在整個系列中通篇使用 Google Chrome,但用戶能夠自行選擇使用 Firefox、Safari 或者甚至是 Internet Explorer。 

  • 在 Google Chrome 中,單擊 Tools > JavaScript Console

  • 在 Firefox 中,單擊 Tools > Web Developer > Browser Console

  • 在 Safari 中,單擊 Develop > Show Error Console。(若是看不到 Develop 菜單,能夠在 Advanced preferences 頁面上單擊 Show Develop menu in menu bar。) 

  • 在 Internet Explorer 中,單擊 Developer Tools > Script > Console

我曾有些學生嘲笑過從命令行運行 JavaScript 的主意:「若是沒有要控制的 HTML,那 JavaScript 還有什麼好處呢?" JavaScript 是在瀏覽器(Netscape Navigator 2.0)中來到這個世界的,所以那些反對者的短視和天真是能夠原諒的。 

事實上,JavaScript 編程語言並未針對 文檔對象模型 (DOM) 操做或造成 Ajax 請求提供本地功能。該瀏覽器提供了 DOM API,能夠方便用戶使用 JavaScript 來完成這類工做,但在瀏覽器以外的地方,JavaScript 不具有這些功能。 

下面給出了一個例子。在瀏覽器中打開一個 JavaScript 控制檯(參見 訪問瀏覽器的開發人員工具)。輸入 navigator.appName。得到響應後,請輸入 navigator.appVersion。獲得的結果相似於圖 1 中所示。 

圖 1. 在 Web 瀏覽器中使用 JavaScript navigator 對象

在 Web 瀏覽器中使用 navigator JavaScript 對象的屏幕截圖

在圖 1 中,Netscape 是對 navigator.appName 的響應,而對 navigator.appVersion 的響應則是經驗豐富的 Web 開發人員已經熟知但愛恨不一的、神祕的開發人員代理字符串。在圖 1 中(截自 OS X 上的 Chrome 瀏覽器),該字符串是 5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36

如今,咱們要建立一個名爲 test.js 的文件。在文件中輸入一樣的命令,並將每一個命令包含在 console.log() 調用中: 

console.log(navigator.appName);
console.log(navigator.appVersion);

保存文件並輸入 node test.js 來運行它,如清單 2 中所示。 

清單 2. 查看 Node.js 中的 navigator is not defined 錯誤
$ node test.js 

/test.js:1
ion (exports, require, module, __filename, __dirname) { console.log(navigator.
                                                                    ^
ReferenceError: navigator is not defined
    at Object.<anonymous> (/test.js:1:75)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

正如您看到的那樣,navigator 在瀏覽器中可用,但在 Node.js 中不可用。(很差意思,讓您的第一個 Node.js 腳本失敗了,但我想確保讓您相信,在瀏覽器中運行 JavaScript 與在 Node.js 中運行它是不一樣的。) 

根據堆棧跟蹤的狀況,正確的 Module 沒有獲得加載。(Modules 是在瀏覽器中運行 JavaScript 與在 Node.js 中運行它之間的另外一主要區別。咱們將馬上講述 Modules 的更多相關內容。)爲了從 Node.js 得到相似的信息,請將 test.js 的內容修改成: 

console.log(process.versions)
console.log(process.arch)
console.log(process.platform)

再次輸入 node test.js,能夠看到相似於清單 3 中的輸出。 

清單 3. 在 Node.js 中使用過程模塊
$ node test.js
 
{ http_parser: '1.0',
  node: '0.10.28',
  v8: '3.14.5.9',
  ares: '1.9.0-DEV',
  uv: '0.10.27',
  zlib: '1.2.3',

  modules: '11',
  openssl: '1.0.1g' }
x64
darwin

在 Node.js 中成功運行第一個腳本以後,咱們將接觸下一個主要概念:模塊。 

什麼是模塊?

能夠在 JavaScript 中建立單一功能的函數,但與在 Java、Ruby 或 Perl 中不一樣,沒法將多個函數打包到一個可以導入導出的內聚模塊或 」包「 中。固然,使用 <script> 元素能夠包含任意 JavaScript 源代碼文件,但這種歷史悠久的方法在兩個關鍵方面缺乏正確的模塊聲明。 

首先,使用 <script> 元素包含的任意 JavaScript 將被加載到全局命名空間中。使用模塊能夠導入的函數被封裝在一個局部命名的變量中。其次,同時更爲關鍵的是,可使用模塊顯式地聲明依賴關係,而使用 <script> 元素則作不到這一點。結果,導入 Module A 時也會同時導入依賴的 Modules B 和 C。當應用程序變得複雜時,傳遞依賴關係管理很快將成爲一種關鍵需求。 

CommonJS

顧名思義,CommonJS 項目定義了一種通用的模塊格式(包括其餘瀏覽器以外的 JavaScript 規範)。Node.js 屬於衆多非官方的 CommonJS 實現之一。RingoJS (相似於 Node.js 的一種應用服務器,運行在 JDK 上的 Rhino/Nashorn JavaScript 運行時之上) 基於 CommonJS,流行的 NoSQL 持久存儲 CouchDB 和 MongoDB 也是如此。

模塊是用戶衷心期盼的下一 JavaScript 主要版本 (ECMAScript 6) 的功能,但直到該版本被普遍接受以前,Node.js 目前使用的是它本身基於 CommonJS 規範的模塊版本。 

使用 require 關鍵字能夠在腳本中包含 CommonJS 模塊。例如,清單 4 是對 Node.js 主頁上的 Hello World 腳本稍微進行修改後的版本。建立一個名爲 example.js 的文件,並將清單 4 中的代碼複製到其中。 

清單 4. Node.js 中的 Hello World
var http = require('http');
var port = 9090;
http.createServer(responseHandler).listen(port);
console.log('Server running at http://127.0.0.1:' + port + '/');

function responseHandler(req, res){
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end('<html><body><h1>Hello World</h1></body></html>');
}

輸入 node example.js 命令運行新的 Web 服務器,而後在 Web 瀏覽器中訪問 http://127.0.0.1:9090。 

看一看清單 4 中的頭兩行。您極可能寫過幾百次(或幾千次)像 var port = 9090; 這樣的簡單語句。這條語句定義了一個名爲 port 的變量,並將數字 9090 賦值給它。第一行 (var http = require('http');) 用於導入一個 CommonJS 模塊。它引入 http 模塊並將它指派給一個局部變量。 and assigns it to a local variable. All of the corresponding modules that http 依賴的全部對應模塊也同時被 require 語句導入。 

example.js 後面的代碼行:

  1. 建立一個新的 HTTP 服務器。

  2. 指定一個函數來處理響應。

  3. 開始監聽指定端口上進入的 HTTP 請求。

這樣經過寥寥幾行 JavaScript 代碼,就能夠在 Node.js 中建立了一個簡單的 Web 服務器。在本系列隨後的文章中您會看到,Express 將這個簡單的例子被擴展用於處理更爲複雜的路由,同時還將提供靜態與動態生成的資源。 

http 模塊是 Node.js 安裝的標準組件之一。其餘標準的 Node.js 模塊還支持文件 I/O,讀取來自用戶的命令行輸入,處理底層的 TCP 和 UDP 請求等等。訪問 Node.js 文檔的 Modules 部分,查看標準模塊的完整列表並瞭解它們的功能。 

儘管模塊列表內容十分豐富,但與可用的第三方模塊列表相比,仍然是小巫見大巫。要訪問它們,您須要熟悉另外一個命令行實用工具:NPM。 

什麼是 NPM?

NPM 是 Node Packaged Modules 的簡寫。要查看包含超過 75,000 個公用第三方 Node 模塊的清單,請訪問 NPM 網站。在網站上搜索 yo 模塊。圖 2 顯示了搜索結果。 

圖 2. yo 模塊的詳細狀況

顯示了 yo 模塊的詳細信息的 NPM 搜索結果的屏幕截圖

結果頁面簡要介紹了該模塊(搭建 Yeoman 項目的 CLI 工具),並顯示它在過去一天、一週和一月內被下載的次數、編寫該模塊的做者、它依賴於哪些其餘的模塊(若是存在)等內容。最重要的是,結果頁面給出了安裝該模塊的命令行語法。 

要從命令行獲取關於 yo 模塊的相似信息,請輸入 npm info yo 命令。(若是您還不知道模塊的官方名稱,能夠輸入 npm search yo 來搜索名稱中包含字符串 yo 的全部模塊。)npm info 命令顯示模塊的 package.json 文件的內容。 

瞭解 package.json

每一個 Node.js 模塊都必須關聯一個格式良好的 package.json 文件,所以,熟悉此文件的內容是值得的。清單 五、清單 6 和清單 7 分三部分顯示了 yo 模塊的 package.json 文件的內容。 

如清單 5 中所示,第一個元素一般是 namedescription 和一個可用 versions 的 JSON 數組。 

清單 5. package.json,第 1 部分
$ npm info yo

{ name: 'yo',
  description: 'CLI tool for scaffolding out Yeoman projects',
  'dist-tags': { latest: '1.1.2' },
  versions: 
   [ 
     '1.0.0',
     '1.1.0',
     '1.1.1',
     '1.1.2' ],

要安裝一個模塊的最新版本,請輸入 npm install package 命令。輸入 npm install package@version 能夠安裝一個特定的版本。 

如清單 6 中所示,接下來將顯示做者、維護者和能夠直接查找源文件的 GitHub 庫。

清單 6. package.json,第 2 部分
author: 'Chrome Developer Relations',
repository: 
 { type: 'git',
   url: 'git://github.com/yeoman/yo' },
homepage: 'http://yeoman.io',
keywords: 
 [ 'front-end',
   'development',
   'dev',
   'build',
   'web',
   'tool',
   'cli',
   'scaffold',
   'stack' ],

在這個例子中,還能夠看到一個指向項目主頁的連接和一個相關關鍵字的 JSON 數組。並不是全部 package.json 文件中都會出現全部這些字段,但用戶不多會抱怨與一個項目相關的元數據太多。 

最後,清單 7 中列出了附有顯式版本號的依賴關係。這些版本號符合主版本.次版本.補丁版本的經常使用模式,被稱爲 SemVer(語義版本控制)。 

清單 7. package.json,第 3 部分
engines: { node: '>=0.8.0', npm: '>=1.2.10' },
dependencies: 
 { 'yeoman-generator': '~0.16.0',
   nopt: '~2.1.1',
   lodash: '~2.4.1',
   'update-notifier': '~0.1.3',
   insight: '~0.3.0',
   'sudo-block': '~0.3.0',
   async: '~0.2.9',
   open: '0.0.4',
   chalk: '~0.4.0',
   findup: '~0.1.3',
   shelljs: '~0.2.6' },
peerDependencies: 
 { 'grunt-cli': '~0.1.7',
   bower: '>=0.9.0' },
devDependencies: 
 { grunt: '~0.4.2',
   mockery: '~1.4.0',
   'grunt-contrib-jshint': '~0.8.0',
   'grunt-contrib-watch': '~0.5.3',
   'grunt-mocha-test': '~0.8.1' },

這個 package.json 文件代表,它必須安裝在 0.8.0 或更高版本的 Node.js 實例上。若是試圖使用 npm install 命令安裝一個不受支持的版本,那麼安裝將會失敗。 

SemVer 的快捷語法

在 清單 7 中,您會注意到,不少依賴關係版本中都有一個波浪符號 (~)。這個符號至關於 1.0.x(也屬於有效語法),意思是 」主版本必須是 1,次版本必須是 0,但您能夠安裝所能找到的最新補丁版本「。SemVer 中的這種隱含表達法意味着,補丁版本毫不會 對 API 作出重大修改(一般是對現有功能的缺陷修復),而次版本會在不打破現有功能的狀況下引入另外的功能(好比新的函數調用)。 

除了平臺要求以外,這個 package.json 文件還提供幾個依賴關係列表:

  • dependencies 部分列出了運行時的依賴關係。

  • devDependencies 部分列出了開發過程當中須要的模塊。

  • peerDependencies 部分支持做者定義項目之間的 」對等「 關係。這種功能一般用於指定基礎項目與其插件之間的關係,但在這個例子中,它指出了包含 Yeoman 項目與 Yo 的其餘兩個項目(Grunt 與 Bower)。

若是在不指定模塊名的狀況下輸入 npm install 命令,那麼 npm 會訪問當前目錄中的 package.json 文件,並安裝我剛剛討論過的三部份內容中列出的全部依賴關係。 

安裝一個能正常工做的 MEAN 堆棧,下一步是安裝 Yeoman 與相應的 Yeoman-MEAN 生成器。 

安裝 Yeoman

做爲一名 Java 開發人員,我沒法想象在沒有諸如 Ant 或 Maven 這樣的編譯系統的狀況下如何啓動一個新項目。相似地,Groovy 和 Grails 開發人員依靠的是 Gant(Ant 的一種 Groovy 實現)或 Gradle。這些工具能夠搭建起一個新的目錄結構,動態下載依賴關係,並準備好將項目發佈。 

在純粹的 Web 開發環境中,Yeoman 能夠知足這種須要。Yeoman 是三種 Node.js 工具的集合,包括用於搭建的純 JavaScript 工具 Yo,管理客戶端依賴關係的 Bower,以及準備項目發佈的 Grunt。經過分析 清單 7 能夠得出這樣的結論:安裝 Yo 時也會安裝它對等的 Grunt 和 Bower,這要感謝 package.json 中的 peerDependencies 部分。 

一般,輸入 npm install yo --save 命令能夠安裝 yo 模塊並更新 package.json 文件中的 dependencies 部分。(npm install yo --save-dev 用於更新 devDependencies 部分。)但這三個對等的 Yeoman 模塊算不上是特定於項目的模塊,它們是命令行實用工具,而非運行時依賴關係。要全局安裝一個 NPM 包,須要在 install 命令後增長一個 -g 標誌。 

在系統上安裝 Yeoman:

npm install -g yo

在完成包安裝後,輸入 yo --version 命令來驗證它已經在運行中。 

Yeoman 與基礎架構的全部餘下部分都準備就緒後,即可以開始安裝 MEAN 堆棧了。 

安裝 MeanJS

您能夠手動安裝 MEAN 堆棧的每一部分,但須要十分當心。謝天謝地,Yeoman 經過其 generators(生成器) 提供了一種更輕鬆的安裝方式。 

Yeoman 生成器就是引導一個新 Web 項目更輕鬆的方式。該生成器提供了基礎包及其全部依賴關係。此外,它一般還會包含一個工做的編譯腳本及其全部相關插件。一般,該生成器還包含一個示例應用程序,包括測試在內。 

Yeoman 團隊構建和維護了幾個 "官方的" Yeoman 生成器社區驅動的 Yeoman 生成器(超過 800 個)遠遠超過官方生成器的數量。 

您將用於引導第一個 MEAN 應用程序的社區生成器被稱爲 MEAN.JS,這也在乎料之中。

在 MEAN.JS 主頁上,單擊 Yo Generator 菜單選項或者直接訪問 Generator 頁面,圖 3 中顯示了其中的一部分。 

圖 3. MEAN.JS Yeoman 生成器

MEAN.JS Yeoman 生成器頁面的屏幕截圖

該頁面上的說明指出要首先 Yeoman,這一點您已經完成。下一步是全局安裝 MEAN.JS 生成器: 

npm install -g generator-meanjs

生成器準備就緒後,即可以開始建立您的第一個 MEAN 應用程序了。建立一個名爲 test 的目錄,使用 cd 命令進入它,而後輸入 yo meanjs命令生成應用程序。回答最後兩個問題,如清單 8 中所示。(您能夠爲開始四個問題提供本身的答案。) 

清單 8. 使用 MEAN.JS Yeoman generator
$ mkdir test
$ cd test
$ yo meanjs


     _-----_
    |       |
    |--(o)--|   .--------------------------.
   `---------  |    Welcome to Yeoman,    |
    ( _U`_ )   |   ladies and gentlemen!  |
    /___A___\   '__________________________'
     |  ~  |
   __'.___.'__
    `  |  Y `

You're using the official MEAN.JS generator.
[?] What would you like to call your application? 
Test
[?] How would you describe your application? 
Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js
[?] How would you describe your application in comma separated key words?
MongoDB, Express, AngularJS, Node.js
[?] What is your company/author name? 
Scott Davis
[?] Would you like to generate the article example CRUD module? 
Yes
[?] Which AngularJS modules would you like to include? 
ngCookies, ngAnimate, ngTouch, ngSanitize

在回答最後一個問題後,您會看到一系列行爲,這是 NPM 在下載全部服務器端的依賴關係(包括 Express)。NPM 完成後,Bower 將下載全部客戶端的依賴關係(包括 AngularJS、Bootstrap 和 jQuery)。 

至此,您已經安裝了 EAN 堆棧(Express、AngularJS 和 Node.js) — 目前只缺乏 M (MongoDB)。若是如今輸入 grunt 命令,在沒有安裝 MongoDB 的狀況下啓動應用程序,您會看到相似於清單 9 中的一條錯誤消息。 

清單 9. 試圖在沒有 MongoDB 的狀況下啓動 MeanJS
events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: failed to connect to [localhost:27017]
    at null.<anonymous> 
(/test/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:546:74)

[nodemon] app crashed - waiting for file changes before starting...

若是啓動應用程序時看到這條錯誤消息,請按下 Ctrl+C 鍵中止應用程序。 

爲了使用新的 MEAN 應用程序,如今須要安裝 MongoDB。 

安裝 MongoDB

MongoDB 是一種 NoSQL 持久性存儲。它不是使用 JavaScript 編寫的,也不是 NPM 包。必須單獨安裝它才能完成 MEAN 堆棧的安裝。 

訪問 MongoDB 主頁,下載平臺特定的安裝程序,並在安裝 MongoDB 時接受全部默認選項。 

安裝完成時,輸入 mongod 命令啓動 MongoDB 守護程序。 

MeanJS Yeoman 生成器已經安裝了一個名爲 Mongoose 的 MongoDB 客戶端模塊,您能夠檢查 package.json 文件來確認這一點。我將在後續的文章中詳細介紹 MongoDB 和 Mongoose。 

安裝並運行 MongoDB 後,最終您能夠運行您的 MEAN 應用程序並觀察使用效果了。 

運行 MEAN 應用程序

要啓動新安裝的 MEAN 應用程序,在運行 MeanJS Yeoman 生成器以前,必定要位於您建立的 test 目錄中。在輸入 grunt 命令時,輸出內容應該如清單 10 中所示。

清單 10. 啓動 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 "watch" task
Waiting...
Running "nodemon:dev" (nodemon) task
[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

jshint 和 csslint 模塊(均由生成器進行安裝)能夠確保源代碼在句法和語體上是正確的。nodemon 包監控文件系統中的代碼修改狀況,並在檢測到有的狀況下自動重啓服務器,當開發人員須要快速而頻繁地修改代碼基礎時,這能夠極大地提升他們的效率。(nodemon 包只在開發階段運行,要監測生產環境的變化,必須從新部署應用程序並重啓 Node.js。) 

按照控制檯輸出的提示,訪問 http://localhost:3000 並運行您的新 MEAN 應用程序。 

圖 4 顯示了 MEAN.JS 示例應用程序的主頁。

圖 4. MEAN.JS 示例應用程序的主頁

MEAN.JS 主頁的屏幕截圖

在菜單欄中單擊 Signup 建立一個新的用戶帳號。如今填寫 Sign-up 頁面上的全部字段(如圖 5 中所示),而後單擊 Sign up。在後續的指南中,您能夠經過 Facebook、Twitter 等啓用 OAuth 登陸 

圖 5. MEAN.JS 示例應用程序的 Sign-up 頁面

MEAN.JS 示例應用程序的 Sign-up 頁面的屏幕截圖

如今,您的本地 MongoDB 實例中已經保存了一組用戶證書,您能夠開始撰寫新的文章了。單擊 Articles 菜單選項(當您登陸以後纔會顯示出來),並建立一些示例文章。圖 6 顯示了 Articles 頁面。 

圖 6. MeanJS 的文章頁面

MeanJS 文章頁面的屏幕截圖

您已經建立了本身的第一個 MEAN 應用程序。歡迎加入! 

結束語

在這篇指南中,您完成至關多的內容。安裝 Node.js 並編寫了第一個 Node.js 腳本。學習了模塊並使用 NPM 安裝了幾個第三方模塊。安裝 Yeoman 並將它做爲可靠的 Web 開發平臺,其中包含一個搭建實用工具 (Yo),一個編譯腳本 (Grunt),以及一個管理客戶端依賴關係的實用工具 (Bower)。安裝 MeanJS Yeoman 生成器,並使用它來建立第一個 MEAN 應用程序。安裝 MongoDB 與 Node.js 客戶端庫 Mongoose。最後運行您的首個 MEAN 應用程序。 

下一次,咱們會詳細瞭解示例應用程序的源代碼,從而瞭解 MEAN 太陽系中的全部四顆行星 (MongoDB、Express、AngularJS 和 Node.js)是如何相互做用的。 

下載

描述 名字 大小
樣例代碼 wa-mean1src.zip 1.38MB

參考資料 

學習

討論

  • 參與 developerWorks 社區。探索由開發人員驅動的博客、論壇、羣組與維基,並與其餘 developerWorks 用戶進行交流。