後端知識點總結——NODE.JS(高級)

後端知識點總結——NODE.JS(高級)

1.Node入門:

什麼是: 針對網絡應用開發的平臺
主要特徵:javascript

  1. 基於Google的JavaScript運行時引擎V8
  2. 擴展了Node標準類庫: TCP,同步或異步文件管理,HTTP

爲何使用Node:css

  1. 能夠在服務器端運行js: 現有前端團隊可直接參與後端js開發
  2. js天生支持非阻塞IO:
    IO: 表明一切數據進出程序的操做:
    包括: 文件讀寫, 數據庫操做, 網絡操做
    問題: 有延遲
    傳統阻塞IO: IO操做會阻塞當前主線程,直到本次IO操做完成,才能執行後續代碼。
    非阻塞IO: 即便處理較慢的IO操做時,主進城仍然能處理其餘請求
    Js天生支持非阻塞: 回調函數=事件循環+回調隊列
    全部非阻塞的操做,返回的結果暫時在回調隊列中等待
    由事件循環,自動依次取回到主程序中恢復執行
    回調隊列在主程序以外存儲回調函數,因此,不會干擾主程序執行
    非阻塞在Web服務器中:
    普通服務器端應用: 雖然可實現每一個請求獨立線程/進程, 但若是一個請求中,包含多個阻塞IO操做(訪問數據庫,網絡,讀寫硬盤文件),該請求返回的時間就等於全部IO操做的時間總和——慢
    Node服務器端應用: 不但每一個請求是一個獨立的線程,且,每一個請求內的每一個IO操做,都是非阻塞的。html

    一個包含多個IO操做的請求,返回的總響應時間,僅僅等於其中一個時間最長的IO操做的時間。
    Node.js vs javascript: 
    Javascript: 編程語言, 依照ECMAScript

    2種運行環境:前端

    1. 客戶端瀏覽器: 由各類客戶端瀏覽器中的js解釋器執行
      擴展: DOM API 和 BOM API 主要目的是爲了操做網頁內容和瀏覽器窗口
    2. 獨立的js解釋器:Node.js 應用程序開發和運行的平臺
      僅支持ECMAScript
      擴展: 各類專門的服務器模塊: TCP, HTTP, 文件讀寫, MYSQL

      構建一個簡單的node應用:
      建立一個新的node項目: 基本命令:
      mkdir 項目文件夾
      cd 項目文件夾
      npm init //負責在當前所在的項目目錄下自動生成package.json配置文件
      運行:node 入口文件.jsjava

2.module

Node應用都是由模塊組成
模塊就是組織程序功能的一種文件或文件夾
Node應用採用CommonJS模塊規範
CommonJS規定:node

  1. 每一個文件就是一個模塊,有本身的做用域——避免全局污染
    一個文件內定義的變量,函數,類都是該文件私有,對其它文件默認不可見
  2. 對象,方法和變量也能夠從一個文件/模塊中導出(exports),用在其它文件/模塊中。

實際項目中,都是將各類功能/數據,劃分爲不一樣項目模塊來管理
如何定義一個模塊:2步:web

  1. 在模塊/文件中定義業務代碼(對象,class,函數)
  2. 將內部的功能拋出,用於未來其它js文件調用

2種狀況:mongodb

2.1面向對象的方式:

  1. 定義一種class或一個對象,包裹屬性和功能
  2. 將class或對象直接賦值給module.exports
    其中: module,指當前模塊對象/當前文件數據庫

    exports是當前module對象的一個屬性
         本質上也是一個對象,保存未來要拋出的全部東西
         exports是當前模塊對外的惟一接口

    從此,只要但願將模塊內部的東西,拋出到外部,供其它文件使用時,都要添加到module.exports上
    其它文件要想使用當前模塊的功能,就必須用require引入當前模塊,而require的本質是找模塊的exports.express

2.2面向函數的方式:

  1. 在文件中,定義多個零散的方法
  2. 將多個零散的方法添加到module的exports上
    其實,可先將零散的方法,先集中定義在一個對象中,再將整個對象賦值給module.exports屬性

引入模塊: require() 專門負責加載模塊文件
什麼時候: 只要在另外一個js文件中,引入自定義模塊並獲取內容時,都用require
本質: 找到js文件,並執行,返回module.exports對象
優化: 單例模式singleton: 始終保持項目中只有一個對象的實例

模塊的引入和加載也是單例模式: 模塊只在第一次被require時,建立。以後,緩存在內存中。反覆require不會致使反覆建立模塊對象。

強調: 模塊是同步加載:前一個加載完,後一個才能開始

強烈建議: 全部require必須集中在頂部

路徑: 以./開頭,表示使用相對路徑,相對於當前正在執行腳本所在路徑——不能省略!

以/開頭,表示Linux系統根目錄——絕對路徑
    以自定義變量開頭,表示在變量保存的地址下繼續查找
    什麼前綴也不加!只寫模塊名: 表示加載一個核心模塊或項目引入的第三方模塊
      路徑查找順序:
        /usr/local/lib/node/模塊名.js
        /home/user/projects/node_modules/模塊名.js
        /home/user/node_modules/模塊名.js
        /home/node_modules/模塊名.js
        /node_modules/模塊名.js

坑: 簡寫: module.exports.fun=function(){…}

可簡寫爲: exports.fun=function(){…}
   exports實際上是module.exports的別名
   var exports=module.exports;
問題: 給exports賦值,沒法賦值給module.exports
   由於exports只是一個變量,臨時保存module.exports的地址值。再次給exports賦任何新值,都致使exports與module.exports分道揚鑣!
避免: 不要用簡寫exports

3.目錄模塊:

什麼時候: 當一個模塊代碼,複雜到須要進一步細分時,一個模塊,就可能由多個文件組成,保存在一個文件夾裏。
如何:

  1. 建立文件夾,集中保存相關的多個js文件模塊
  2. 在文件夾中添加一個主模塊(index.js),主模塊中,引入並組織好多個小模塊一塊兒導出
  3. 在文件夾中添加package.json文件,其中:

    {
        "name":"模塊名",
        "main":"./主模塊相對路徑"
      }

    其實, 若是沒有main甚至沒有package.json,也行。
    會自動優先找文件夾下的index.js

引入目錄模塊: require("./目錄名")
若是但願直接用目錄名引用模塊,不加相對路徑:
將目錄放入node_modules文件夾中

npm: 第三方模塊的包管理工具: 查詢,下載
除了核心模塊和自定義本地模塊,node生態系統還提供了大量優質第三方模塊
如何:
查詢模塊:

模糊查找: npm search 模塊名
精確查找: npm search /^模塊名$/
  若是現實完整描述: npm search /^模塊名$/ --parseable

安裝模塊: 2個位置:

    1. 全局安裝: npm install -g 模塊名
      路徑: Linux: /usr/local/lib/node_modules

      Windows:
          C:\Users\用戶名\AppData\Roaming\npm\node_modules
    2. 項目本地安裝: npm install 模塊名 -save
    1. 全局對象:
      全局做用域對象不是window,而是global
      ECMAScript標準中本來規定的就是global
      在瀏覽器中被window代替
      強調: 交互模式: 直接在命令行中測試node應用,全部全局變量/全局函數自動成爲global的成員

      腳本模式: 經過加載js文件執行node應用,文件內的"全局變量/全局函數",僅當前文件全部,不會成爲global的成員——避免了全局污染

      console對象:
      測試重要手段: 打樁: 在關鍵位置輸出關鍵變量的值
      輸出文本信息: 瀏覽器中4種輸出,node中合併爲2中:
      console.log/info() 輸出普通的文本信息
      console.error/warn() 輸出錯誤信息
      其實: console.xxx()都自帶格式化功能
      Console.log vs console.error: .error可直接導出到文件日誌中

      如何: node xxx.js 2> error-file.log
      其中:2>表示輸出流,專門向硬盤文件寫入內容

      輸出耗時:
      Console.time("標籤"); //預備,開始!
      正常程序邏輯
      Console.timeEnd("標籤"); //完成! 自動輸出與time之間的時間間隔
      單元測試:
      什麼是: 對程序中最小的執行單元進行測試
      開發人員主動對本身的函數執行單元測試
      如何: console.assert(判斷條件, "錯誤提示")

      只有條件不知足時,才輸出msg

      輸出堆棧:
      console.trace()

    1. 全局對象: process:

    process.platform
    process.pid
    process.kill(pid);

    控制檯輸入輸出:
    2步:

    1. 讓控制檯進入輸入狀態:

    process.stdin.resume()
    process.stdin.setEncoding("utf-8")

    1. 監聽stdin的data事件:
      在控制檯輸入後,按回車,會觸發stdin的data事件
    process.stdin.on("data",text=>{
          process.stdout.write( … text … )
        })

    控制檯參數:
    2步: 1. 定義關聯數組,保存參數名和參數對應的處理函數

    2. 啓動時, process.argv數組可自動得到傳入的全部參數,  根據參數調用不一樣的處理函數

    process.argv: ["node.exe","xxx.js","參數值1","參數值2",…]

    高精度計時:
    精確到納秒, 優勢: 不受系統時間影響
    如何: 2步: 1. 得到開始的時間戳: var start=process.hrtime();

    2. 得到結束時間戳: var diff=process.hrtime(start);

    diff: [秒數, 納秒]

    得到秒差: diff[0]+diff[1]/1e9
    得到毫秒差: diff[0]*1000+diff[1]/1e6

    Vs console.time/timeEnd:
    time/timeEnd: 缺: 精度低, 優: 效率高
    hrtime: 優: 精度高,且不受系統時間影響

    缺點: 效率低

    非I/O的異步操做(定時器):
    什麼時候: 要執行異步回調時
    如何:

    1. setTimeout/setInterval() 將回調函數添加到事件循環的timer階段的隊列中等待執行。
      Timer階段是事件循環的第一階段
      習慣上: setTimeout每每都會設置ms數
    2. setImmediate() 將回調函數添加到事件循環的check階段的隊列中等待執行。
      Check階段比Timer要晚執行
      習慣上: 並不設置毫秒數,而是普通的追加到等待隊列末尾便可。
    3. process.nextTick() 將回調函數加入nextTickQueue隊列等待執行
      nextTickQueue不參與事件循環,而是在開始timer以前,就馬上執行nextTickQueue中的回調函數
      優勢: 不會有延遲
    4. 自定義的EventEmiter

    5.EventEmitter類型:

    Node.js全部異步I/O操做完成時,都會發送一個事件到事件隊列
    Node.js中許多對象都會觸發事件:
    好比: http模塊: 建立Server對象,監聽http請求

    一旦收到一個http請求,則馬上觸發事件,將處理函數放入事件隊列
      fs模塊: 在每次讀寫完文件時,也會觸發事件,將處理函數放入事件隊列

    什麼是EventEmitter: 專門封裝事件監聽和事件觸發的API的一種類型
    全部能夠觸發事件的對象,都是EventEmitter類型的子對象
    如何讓一個對象能夠監聽並觸發事件:

    1. 引入events模塊: const events=require("events")
    2. 建立events.EventEmitter類型的子對象:
      var emitter=new events.EventEmitter();
    3. 用on,爲對象添加事件監聽:
      emitter.on("自定義事件名",function 處理函數(參數列表){

      … 得到參數, 執行操做 …

      })

    4. 在任何狀況下,使用對象的emit方法,觸發指定的事件:
      emitter.emit("自定義事件名",參數值,…)

    觸發一次後,自動解綁:
    emitter.once("自定義事件名",處理函數)

    錯誤處理:
    問題: try catch沒法捕獲異步調用中的錯誤
    解決: Domain
    什麼時候: 只要既但願捕獲主程序錯誤,又但願捕獲異步操做的錯誤時
    如何:

    1. 引入domain模塊: const domain=require("domain")
    2. 建立domain對象: const mpDomain=domain.create();
    3. 爲domain對象添加error事件監聽
      mpDomain.on("error",err=>{

      console.log("出錯啦!"+err);

      })

    4. 將可能出錯的程序放入mpDomain中運行:
      mpDomain.run(()=>{

      musicPlayer.emit("play");

      })

    6.協議:

    什麼是: 計算機之間經過網絡實現通訊時,事先達成的一種"約定"
    爲何: 約定使不一樣廠商的設備,不一樣操做系統之間,均可按照統一約定,任意通訊

    7.分組交換方式:

    什麼是: 將大數據分割爲一個個叫作包(packet)的較小單元進行傳輸

    8.ISO/OSI模型:

    ISO(國際標準化組織)
    OSI(開放式通訊系統互聯參考模型)
    7層:

    1. 應用層: 規定應用程序中的通訊細節
      包括: HTTP FTP TELNET SMTP DNS
    2. 表示層: 負責數據格式的轉換
    3. 會話層: 創建鏈接
    4. 傳輸層: 控制整體數據傳輸
      包括:
      TCP(傳輸控制協議): 可靠傳輸
      優: 可靠,客戶端和服務端可雙向通訊
      缺: 傳輸效率低
      什麼時候: 要求可靠性時
      UDP(用戶數據報協議):
      什麼時候: 對可靠性要求不高,對傳輸效率要求高,且發送小數據(qq, 微信, 在線視頻播放)
    5. 網絡層: 將數據分組傳輸到目的地
    6. 數據鏈路層: 負責規劃網絡中節點間的路線
    7. 物理層: 負責經過以太網,藍牙,光纖發送0/1的比特流

    9.TCP/IP: 互聯網協議套件

    包含: TCP 傳輸控制協議

    IP 互聯網協議

    TCP/IP不是ISO標準
    TCP/IP 只有四層:

    鄙視:

    1. TCP/IP四層協議,分別對應ISO/OSI中的哪一層: 圖6
    2. 網絡創建鏈接須要3次握手,斷開鏈接須要4次握手,分別是:
      圖7
    3. HTTP/1.0 1.1 2.0每次升級有哪些不一樣

    10.net模塊:

    使用net模塊:

    1. 可建立基於TCP的客戶端與服務器端通訊

    建立TCP服務器:
    引入net模塊
    使用net.createServer方法建立服務端對象server

    接受一個回調函數做爲參數:
     只要有客戶端鏈接到當前服務端,就自動執行該回調函數
     回調函數接受一個socket參數對象,用於與客戶端通訊
     Socket對象: 是客戶端在服務器端的一個代理對象
                可經過socket和真正的客戶端發送和接受消息
     Socket對象的data事件,可監聽客戶端發來的消息
       回調函數中, data參數爲消息的內容
     Socket對象的end事件,可監聽客戶端的斷開
     Socket的write方法向客戶端輸出消息

    調用server的listen方法,綁定到一個端口,監聽客戶端發來的連接請求

    也接受一個回調函數參數,但僅在啓動監聽後執行一次

    建立TCP客戶端:
    引入net模塊
    使用net.connect()方法向服務器創建鏈接
    var client=net.connect(服務端端口,ip,function(){})
    回調函數在鏈接創建後,自動觸發一次
    爲client的data事件綁定處理函數,處理函數的data參數自動接收服務端發來的消息
    爲client的end事件添加處理函數,當客戶端斷開鏈接時執行操做
    在任何位置可用client.write("消息內容")向服務端發送
    在任何位置可用client.end() 斷開與服務端鏈接

    11.HTTP模塊:

    使用HTTP模塊:

    1. 實現WEB服務器,接受請求並返回響應(代替了apache,tomcat)
    2. 模擬客戶端向一個指定的WEB服務器發送請求

    建立HTTP服務端:
    引入HTTP模塊
    建立HTTP服務端server:
    var server=http.createServer(function(req,res){

    //只要有請求發送到該服務器,就自動觸發該回調函數
     //其中: 
       //req對象,封裝了發來的請求信息
       //res對象,專門用於向服務器端返回響應
        //res.writeHead(狀態碼,{ 屬性:值, …:… ,…})
        //res.write("放入響應主體中")
        //res.end()

    })
    啓動監聽: server.listen(端口,function(){ … })

    建立HTTP請求:
    使用http.request()方法建立一個請求(鏈接),得到請求對象req
    接收2個參數:

    options對象參數:
     host
     port
     method
     path  /index.html?page=12
    回調函數: 在服務器端返回響應時執行
     參數res: 專門用於得到響應內容(響應頭和響應主體)
      HTTP協議規定: 先發響應頭部 用res.headers得到響應頭部對象,用res.statusCode 得到狀態碼
      強調: 響應主題是稍後才發送過來
       必須用res.on("data",function(buffer){ … String(buffer) …})
      強調: 凡是從響應中得到的data,默認都是字符串

    req.end()結束併發送請求。
    強調:必須加req.end(),請求才能發送出去

    http.get()
    專門向服務器端發送get請求
    是http.request()的簡化:

    1. 自動設置method爲get;
    2. 自動調req.end

    但依然須要使用res.on("data",function(buffer){ … })來接受響應主體

    分塊:
    問題: 若是響應主體過大,一次性傳不過來
    解決:

    分塊發送和接受,再拼接,再總體轉換
       若是分塊接受,res.on("data",function(buf){ … })每收到一塊,就會反覆觸發。
       其中buf,僅是其中一塊而已

    請求文件,保存在本地:
    引入fs模塊:
    建立寫入流,指向目標文件: var writable=fs.createWriteStream("相對路徑")
    使用管道,將寫入流writable鏈接到res對象上: res.pipe(writable)

    響應頭部: res.writeHead(狀態碼,{ })
    容許跨域: "Access-Control-Allow-Origin":"請求來源的網站"
    指定內容類型:"Content-Type":"application/json" "text/css"

    req對象:
    請求頭部: req.headers
    請求方法: req.method
    請求地址: req.url
    url的處理:

    引入url模塊
    用url.parse(req.url,true)將req.url字符串轉爲對象
     其中true,表示將search中的參數也轉爲對象屬性
     如何: var obj=url.parse(req.url, true)
      其中: obj.query中保存了全部參數及其值

    得到請求參數:
    Get: get方式的參數都經過url中的search傳遞

    obj=url.parse(req.url,true)
      obj.query

    Post: post方式的參數都是放在請求主體中,沒有在url中

    問題:obj.query沒法得到
      解決: req.on("data",function(buf){ … })
      問題: String(buf)得到的是參數的字符串
      解決: querystring模塊

    12.https模塊:

    問題: http協議是明文的
    危害: 1. 通訊使用明文,內容可能被竊聽

    2. 不驗證身份,有可能遭遇假裝
       3. 沒法證實消息的完整性,消息有可能被篡改

    網絡嗅探器:

    13.解決: https協議

    https是更安全的http協議:

    1. 客戶端和服務器端的雙向認證
    2. 完整性檢查
    3. 內容加密

    https=http+ssl

    ssl/tls: ssl 安全套接層,對傳統socket進一步提供安全的保護

    tls 傳輸層安全, 實際上是ssl的繼任者

    14.提供三大服務:

    1. 客戶端和服務器端的雙向認證 ——可靠
    2. 完整性檢查 ——完整
    3. 數據加密 ——機密性
      tls/ssl的執行過程:

    15.Step0: 得到服務器端證書, 3步:

    1. 在服務器端生成私鑰
    2. 用私鑰生成一個證書申請文件
    3. 將私鑰和申請文件交給第三方CA,第三方CA通過審查,會生成並頒發證書給申請的服務器
      證書包含2樣東西: 公鑰+公司的信息
      Step1: 客戶端請求https協議的web服務器
      Step2: 服務器返回證書給客戶端
      Step3: 客戶端拿到證書後,將證書交給CA。

      客戶端利用CA中的公鑰隨機生成本身的私鑰
        將私鑰發給服務器端

      Step4: 服務器端得到客戶端發來的客戶端私鑰
      到此,客戶端和服務器端,擁有了相同的兩個鑰匙
      以後,服務器和客戶端發送的全部消息,都用兩個相同的私鑰加密和解密

    16.如何實現https的web服務器應用:

    1. 申請https網站的認證證書:

    Step1: 用openssl生成服務器端私鑰:
    openssl genrsa -out d:/privatekey.pem 1024
    Step2: 用私鑰生成證書申請文件:

    openssl  req  -new  -key  d:/privatekey.pem  -out  d:/certificaterequest.csr

    Step3: 用私鑰和證書申請文件共同生成證書文件

    openssl  x509  -req  -in  d:/certificaterequest.csr  -signkey  
    d:/privatekey.pem   -out  d:/certificate.pem

    2.使用node的https模塊建立服務器
    Step1: 引入必須的模塊:
    const https=require(「https」);
    const fs=require(「fs」);
    Step2:讀取服務器私鑰和證書文件,保存到服務器程序的變量中
    let privatekey=fs.readFileSync(「d:/privatekey.pem」);
    let certificate=fs.readFileSync(「d:/certificate.pem」);
    Step3: 用https建立服務器端應用程序,提供私鑰和證書,並定義處理請求的回調函數

    https.createServer(
      {
        key: privatekey,
        cert: certificate
    },
    (req,res)=>{
      res.write(「…」)
      res.end();
    }
    ).listen(443)

    3.用https模塊向https的服務器發送請求
    錯誤: http模塊不支持向https服務器發送請求
    正確:

    var https=require(「https」);
    https.get(「https://...」, res=>{
    res.on(「data」,buf=>{
    buf…
    })
    })

    17.express

    什麼是: 基於node的http模塊和第三方的Connect框架的web框架
    Connect框架: 專門將各類各樣的中間件函數粘合在一塊兒,共同處理http請求中的req對象
    什麼時候: 只要對req對象反覆執行多種操做時,都要用connect組織多箇中間件。
    如何:

    Step1: 安裝connect模塊: npm install connect –save

    Step2: 引入connect模塊: var connect=require(「connect」)

    Step3: 用connect模塊建立處理req對象的應用程序實例var app=connect();

    Step4: 向connect模塊的應用程序實例中添加中間件函數

    app.use(function md1(req,res,next){
      //加工req對象
      … …
      next();
    })

    Step5: connect的應用程序實例,必需要放入createServer中用於處理服務器接收到的req對象
    http.createServer(app)
    總結: express是在connect基礎上的進一步封裝和簡化,因此express也是採用中間件組合的方式,處理req對象
    安裝express框架: 2種:

    1. 使用本地express模塊,進可以提供服務支持,須要自定義添加複雜的程序結構

      Step1: npm install –save express
      Step2: 引入http和express
      const http=require(「http」);
      const express=require(「express」);
      Step3: 建立express應用實例對象:
      let app=express();
      Step4: 爲app添加各類處理中間件函數
      app.use(function md(req,res,next){ … …})
      Step5: 將app和createServer相連
      http.createServer(app).listen(端口號);

    2. 使用腳手架, 簡化生成項目的結構:

    Step1: 全局安裝express生成器:
    npm install –g express-generator

    Step2: 用生成器,生成項目腳手架代碼:
    express 項目文件夾名 –e //-e 表示用EJS做爲前端頁面模板
    強調: 只負責生成項目代碼,並不負責下載依賴包

    Step3: 爲腳手架代碼下載全部依賴包
    cd 項目文件夾下
    npm install //根據package.json中的依賴項

    Step4: 用腳手架代碼啓動nodejs服務器端應用程序: npm start

    express項目結構:

    1. ./bin/www.js express項目的啓動文件

    package.json中: npm start 時 自動執行 node ./bin/www

    2./app.js 對express框架的實例對象的配置
    要求: 對express實例對象app的全部配置必須放在一個獨立的文件模塊app.js中
    而後,在主程序www.js中引入app.js模塊

    3../routes/xxx.js 路由模塊
    每一個子功能,都應該集中定義在一個路由模塊文件中
    在app.js中引入路由文件模塊,並將路由文件模塊添加到app的中間件列表中,並設置上級路徑
    在每一個子路由模塊文件中,建立路由對象,爲路由對象添加不一樣請求方法和不一樣子路徑下的處理函數
    強調: 子路由中的相對路徑,都是在上級路徑之下的相對路徑

    改造腳手架項目結構:

    1. 補充缺失的模塊:
      express-session 讓express能夠處理session
      connect-flash 強化自動維護session的功能
      passport 綜合的用戶驗證解決方案

      ( 使用passport模塊,實現qq,微信登陸)
    2. 在app.js中添加對新模塊的引用:
    3. 爲項目添加mongodb支持

    Step1: 安裝mongoose模塊和promise模塊
    mongoose: node js專用的簡化操做mongodb數據庫的模塊

    Step2: 建立文件夾./config,在文件夾下添加config.js
    在config.js中定義對象模塊,保存鏈接字符串
    module.exports={
    db:」mongodb://主機名或ip/數據庫名」}

    Step3: 在./config文件夾下建立mongoose.js,保存建立鏈接對象的代碼:
    var config=require('./config'),
    mongoose=require('mongoose');
    設置mongoose的promise屬性,使用當前項目的promise模塊
    mongoose.Promise=require(‘promise’);
    var db=mongoose.connect(config.db) module.exports=db;

    Step4: 根據業務須要,定義mongoose模型對象:
    建立./models文件夾, 在models內爲每種業務對象建立專門的模型文件

    3步:

    1. 引入mongoose,得到Schema類型
    2. 用Schema建立UserSchema結構
    3. 將UserSchema編譯爲User模型,並拋出爲User模塊Step5: 回到mongoose.js中,在connect以後,引入User模塊require('../models/user.model');Step6: 回到app.js中,在路由中間件以前,先請求並初始化mongoose.jsrequire("./config/mongoose");
    相關文章
    相關標籤/搜索