Node+Express+MongoDB + Socket.io搭建實時聊天應用實戰教程(三)--前后端環境配置


前言

之前都是介紹一些基礎知識,在這一節,我們就要開始實戰coding了。正所謂磨刀不誤砍柴工,准備工作顯得尤為重要。很多demo只是追求效果的實現,並不注重整個demo的架構性。從我個人的角度看來,既然是demo,就應該是有參考價值的,而作為web的demo,就更加應該凸顯整個demo的結構,所以這一節着重講解個人喜歡的node項目的前后端架構。
另,本教程乃系列教程,如需從頭看起,可先看前面兩篇博客:
http://www.cnblogs.com/yuanzm/p/4179766.html
http://www.cnblogs.com/yuanzm/p/4205891.html
源代碼地址是:https://github.com/yuanzm/Node-Chat-Demo

后端架構之Express框架

和大多實戰demo一樣,我們的后端會采用Node的官方推薦框架Express。根據Express官網的定義:Express 是一個簡潔而靈活的 node.js Web應用框架, 提供一系列強大特性幫助你創建各種Web應用。之所以選擇框架而不是采用原生開發,主要有兩個原因。其一,框架幫助我們抽象出了很多功能,能幫助我們快速搭建Web應用;其二,用Express新建的項目,本身具有非常優秀的MVC架構,能夠讓我們更加良好的管理我們的項目。

  • Express安裝
    Express的安裝非常簡單,只需要采用在CMD窗口輸入npm install -g express即可,其中-g代表全局安裝。這個命令默認安裝的就是最新版本的Express。為了驗證Express是否安裝成功,通常在命令行輸入express -V查看版本來確認。

    如圖所示,輸入如上命令時出現了“‘express’不是內部或者外部命令,也不是可運行的程序或者批處理文件”提示。原來,最新express4.0版本中將命令工具分家出來了(項目地址:https://github.com/expressjs/generator),所以我們還需要安裝一個命令工具,命令如下:
    npm install -g express-generator

    到這一步,我們成功安裝了最新的Express,也就是v 4.11.2
  • 新建一個Express項目
    新建一個Express項目非常簡單,只需要在命令行輸入express project-name即可。需要注意的是,在新建Express項目的時候,需要指定前端模板引擎。根據百度百科的定義,模板引擎(這里特指用於Web開發的模板引擎)是為了使用戶界面與業務數據(內容)分離而產生的,它可以生成特定格式的文檔,用於網站的模板引擎就會生成一個標准的HTML文檔。Express默認采用的模板是jade模板,我們的demo也將采用這這個模板,所以不需要手動指定。本實戰教程中,我們新建一個名為Node-Chat-Demo的項目。在命令行先輸入express Node-Chat-Demo,然后按照提示輸入cd Node-Chat-Demo && npm install就完成了后端基礎環境的搭建。下面是這一步之后的文件目錄截圖(其中LICENSE以后的為Git管理需要的文件,可忽略):
  • 項目簡介
  1. bin是express本身配置的啟動文件,我們將不采用,可忽略
  2. node_modules是后端使用的node插件
  3. public防止了前端文件
  4. routes是express的路由模塊
  5. view是express的模板引擎放置的地方
  6. app.js是express項目的配置文件,也可以算是項目入口文件
  7. package.json聲明聲明項目中使用的模塊
  • 項目啟動
    Express項目的啟動有自己獨特的方式--npm start,但是博主嘗試之后發現這個並不能監聽文件變化,也就是在文件更改的時候需要重新啟動項目,這在調試的時候就會顯得非常麻煩。針對這種情況,我們將采用一個叫做supervisor的npm包,npm包的主頁是[supervisor](npm install supervisor -g)。安裝也很簡單,只需要在命令行輸入npm install supervisor -g全局安裝即可。然后我們在app.js的33行后面加入兩行:
    app.listen(3000); console.log("Listening on port 3000")

    最后只需要在項目根目錄輸入supervisor app.js就能夠在監聽文件變化模式下啟動我們的項目了。


    到這里后台就已經搭建好了,接下來講解前端架構。

前端架構之前端自動化工作流

前端給很多開發者的印象就是一堆HTML和CSS和Javascript,雜亂無章和沒有難度。其實不然,正因為Web前端開發零散化的特性,使得前端架構尤為重要。什么叫零散化特性呢,這是和后台開和安卓開發等對比而來的。在安卓開發中,有強大的Eclipse,新建一個項目,整個架構完全給你搭建好了,不用自己操心。對於傳統的后台開發,經常采用各種MVC框架比如我們剛剛采用的Express,一行命令同樣把結構什么的全給你弄好了。但是前端就完全不一樣了,因為他只是整個項目的一個組成部分,通常沒有特定的結構,經常是一堆css和js在需要的時候出現,顯得尤為零散。當然正是因為這種特性才讓前端開發顯得更加靈活和有意思,在這個實戰教程中,將采用本人自己總結的一套自動化工作流,力求維持項目的有序性。這個自動化工作流主要采用了browserify、Sass、Grunt,下面逐一介紹。

  • 前端模塊化之browserify

    這里特指前端模塊化是因為后端的Node本身良好支持了模塊化開發,前端的Javascript暫時還不支持模塊化開發,或者說離模塊化廣泛推行的一天還有很長一段時間。為了能夠在前端使用模塊化的編程思想,可以采用強大的browserify。什么是browserify呢?Browserify 通過預編譯的方法,讓Javascript前端可以直接使用Node后端的程序。我們可以用一套代碼完成前后端,不僅工作量變少了,程序重用性增強,還可以直接在瀏覽器中使用大量的NPM第三方開源庫的功能。直觀一點表達就是通過browserify,我們可以像寫Node一樣把每個js文件當作一個模塊,實現特定的功能,最終只暴露模塊接口。browserify會分析我們的模塊引入順序,形成一棵模塊依賴樹,最終可以只生成一個js文件。最終只生成一個js文件的好處是顯而易見的,瀏覽器下載200k的文件和下載幾k的文件所用的時間並不會差別很大,把所有文件合在一起會加快頁面加載速度。從互聯網結構的角度來看,這樣能夠大幅度減少http請求的數量,提高網站性能。對於怎么使用browserify,這里不做累贅,會在后面的教程和介紹Grunt時一並提及,這里只附上Browserify官網主頁
  • CSS預處理器之Sass

    我們知道,CSS是沒有語法的,所以寫CSS其實是一件非常煩人的事情。很自然地,有人就開始為CSS加入編程元素,這被叫做"CSS預處理器"(css preprocessor)。它的基本思想是,用一種專門的編程語言,進行網頁樣式設計,然后再編譯成正常的CSS文件。在本實戰教程中,我們選擇Sass。Sass是CSS的一個擴展,它使CSS的使用起來更加優雅和強大。簡而言之,Sass可以理解成CSS的超集,你可以在Sass里面寫熟悉的CSS。Sass的終極目標是解決CSS的缺陷。如我們所知,CSS並不是一個完美的語言。CSS雖然簡單易學,卻也能迅速制造嚴重的混淆,尤其是在工程浩大的項目中。本文同樣不涉及Sass的使用教程,因為Sass非常簡單,只需要好好看看文檔即可。這里推薦一個教程:http://www.w3cplus.com/sassguide/
  • 使用Grunt

    之所以把Grunt放到最后面是因為整個自動化工作流的核心是基於Grunt的。我們可以使用Browserify,可以使用Sass等其他一系列的工具,但是使用它們大多數都需要用到命令行操作,如果我們每次修改文件都要手動在命令行進行編譯操作將會使開發效率大大降低。自然而然的,自動化工具就會出現,目前最主流的自動化工具應該是Grunt和Gulp。什么是Grunt呢?Grunt是Javascript任務運行工具,對於Grunt的優勢,Grunt官網自己給出了非常好的解答:Grunt是一個龐大的生態系統,每天都在成長。你可以自由的選擇數以百計的插件以幫助你自動化的處理任務。如果你所需要的插件還被有人創建,那么你可以自己創建插件並通過npm很方便的發布以供更多人使用並一起完善。其中生態系統這四個字是非常重要的,Grunt本身很優秀,但是不算傑出,因為Grunt是基於文件的,當項目很大的時候,就會非常慢!Grunt之所以如此流行,正式因為Grunt有良好的社區支持。
  • 前端工作目錄
    正如前面所述,采用Express框架的項目前端文件主要放置在public文件夾里面。我們先來看看最終的public目錄:

    大概介紹一下每個文件夾的作用:
  1. .sass-cache是Sass在預處理的過程中產生的緩存文件,可忽略
  2. node_modules是前端使用的node插件,在寫好Gruntfile.js文件之后在public文件夾根目錄在命令行運行npm install會自動成成
  3. asserts是靜態資源如圖片存放的地方,里面包含一個文件夾images,存放了所用到的圖片
  4. bin是Grunt處理之后的文件,包括兩個文件夾,分別是jscss,包含了最終生成的main.js和main.css文件,在運行Grunt的時候會自動生成這兩個文件夾,新建bin即可
  5. lib是前端使用到的類庫存放的地方,包括jquery和bootstrap等,暫時先新建空的lib文件夾,后續使用到了某個類庫添加即可
  6. src顧名思義是源代碼存放的地方,我們在開發過程中編寫的js和scss文件都存放在這里,包括兩個文件夾,分別是jsscss,分別包含了開發過程中的js和scss文件
  7. Gruntfile.js是Grunt的配置文件,復制下面貼出的Gruntfile.js即可。
  8. package.json用來聲明聲明項目中使用的模塊,復制下面貼出的package.json即可。
    使用Grunt關鍵是寫好它的配置文件,包括package.json和Gruntfile.js兩個文件。對於怎么書寫這兩個文件,博主推薦大家看看Grunt的官方主頁,這里僅貼上本實戰教程的Gruntfile.js和package.json文件。
  1. Gruntfile.js
(function() {
  module.exports = function(grunt) {
    var remapify = require('remapify');
    grunt.initConfig({
      //每次運行Grunt的時候清除之前生成的文件
      clean: {
        bin: ["bin"],
        sassCache: '.sass-cache'
      },
      //分析模塊依賴樹,最后生成一個main.js文件
      browserify: {
        dev: {
          expand: true,
          flatten: true,
          src: ["src/js/main.js"],
          dest: "bin/js",
          ext: ".js"
        }
      },
      //壓縮js文件
      uglify: {
        build: {
          files: [
            {
              expand: true,
              cwd: 'bin/js',
              src: '**/*.js',
              dest: 'dist/js'
            }
          ]
        }
      },
      //壓縮css文件
      cssmin: {
        build: {
          files: {
            "dist/css/main.css": ["bin/css/main.css"]
          }
        }
      },
      //監聽文件變化,如果src文件夾中的js或css文件變化了,執行任務`browserify`和`sass`
      watch: {
        compile: {
          files: ["src/**/*.js", "src/**/*.scss"],
          tasks: ["browserify","sass"]
        }
      },
      //scss文件編譯成css
      sass: {
        dist: {
          files: {
            "bin/css/main.css": "src/scss/main.scss"
          }
        }
      }
    });
    //加載上述任務所需要的插件
    grunt.loadNpmTasks("grunt-contrib-clean");
    grunt.loadNpmTasks("grunt-browserify");
    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-contrib-sass");
    grunt.loadNpmTasks("grunt-contrib-uglify");
    grunt.loadNpmTasks("grunt-contrib-cssmin");
    grunt.loadNpmTasks("grunt-contrib-copy");
    //定義被執行的任務列表
    grunt.registerTask("default", function() {
      return grunt.task.run(["clean:bin","browserify", "sass", "watch"]);
    });
    return grunt.registerTask("build", function() {
      return grunt.task.run(["clean:bin", "clean:dist", "browserify", "sass", "clean:sassCache", "cssmin", "uglify", "copy"]);
    });
  };
}).call(this);
  1. package.json
{
  "name": "Node-Chat-Demo",
  "version": "0.0.1",
  "author": "yuanzm",
  "license": "MIT",
  "devDependencies": {
    "grunt": "*",
    "grunt-browserify": "*",
    "grunt-contrib-clean": "*",
    "grunt-contrib-cssmin": "*",
    "grunt-contrib-uglify": "*",
    "grunt-contrib-watch": "*",
    "grunt-contrib-sass": "*"
  },
  "dependencies": {
    "browserify": "^8.1.3"
  }
}

簡單描述一下這個工作流:在寫前端代碼的時候,為了充分利用好CSS,采用了Sass來彌補CSS本身的缺陷;為了落實模塊化的編程思想,采用了browserify來使Javascript編寫更加高效規范;為了能夠最大化省去人工操作,采用Grunt來自動執行編譯任務;為了升項目性能,最終生成的文件只有一個且經過高度壓縮。
綜上所述,在配置本實戰教程需要的前端環境的時候,我們需要做以下幾件事情:
(1). 按照public文件目錄截圖以及描述建立好需要的文件目錄
(2). 確保Gruntfile.js正確的情況下在public根目錄執行命令npm install
(3). 在public根目錄執行命令grunt,如果沒有報錯,並且bin文件夾里面生成了相應的main.js和main.css,說明環境配置成功。
其中,運行grunt命令的效果圖如下:

產生壓縮文件的命令和效果如下:

到這里前端環境也配置好了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM