node js(框架)

  • 框架

    • 是一種概念,是對(duì)常見功能的封裝,是整個(gè)或部分系統(tǒng)的可重用設(shè)計(jì),表現(xiàn)為一組抽象構(gòu)件及構(gòu)件實(shí)例間交互的方法,通過制定一種規(guī)則,具有約束性,給定一些Api,可讓開發(fā)人員能夠快速開發(fā)項(xiàng)目的工具,假如你要造一輛馬車,在沒有框架的情況下,你需要自己去伐木,去把木頭做成木板,木棍,然后組成輪子,門,等部件,然后組裝起來,但如果你用了框架,就相當(dāng)于你有現(xiàn)成的輪子,門等部件,你只需要組裝一下就可以了
  • Express

    • 基于NodeJs平臺(tái),快速開發(fā)項(xiàng)目的web開發(fā)框架

    • 起步

      • 生成項(xiàng)目文件并初始化包管理文件

      • mkdir myapp && cd myapp && npm init -y
        
      • 下載express模塊

      • npm install express -S
        
      • 創(chuàng)建文件

      • cd myapp && touch app.js
        
      • 打開app.js輸入以下代碼

      • // 引入express模塊
        const Express = require('express');
        // 實(shí)例化Express對(duì)象或者const app = express()調(diào)用也可以得到實(shí)例對(duì)象
        const app = new Express();
        // 注冊(cè)路由
        app.get('/', (req, res) => {
          res.end('Hello World');
        })
        // 啟動(dòng)服務(wù)
        app.listen(3000, err => {
          !err && process.stdout.write('服務(wù)啟動(dòng)成功');
        })
        
    • Express應(yīng)用生成器

      • 安裝全局命令

      • npm install express-generator -g
        
      • 生成express應(yīng)用

      • // --view=pug 代表所使用的模板引擎為pug
        // 模板引擎-使用特定格式快速渲染頁面的一種方式
        // myapp表示要生成的應(yīng)用的文件名稱
        express --view=pug myapp
        
      • 打開myapp

      • cd myapp
        
      • 下載依賴

      • npm install
        
      • 啟動(dòng)應(yīng)用

      • // DEBUG=myapp:* 表示開啟bug檢測模式
        // npm start 表示啟動(dòng)項(xiàng)目
        // Linux或mac下
        DEBUG=myapp:* npm start
        // windows下
        set DEBUG=myapp:* & npm start
        
      • 默認(rèn)端口為3000,瀏覽器輸入localhost:3000,看到Welcome to Express 表示成功生成應(yīng)用并啟動(dòng)

  • Koa

    • 基于NodeJs的web應(yīng)用框架,由Express的原班人馬打造,致力于提供一個(gè)輕量級(jí)的架子,幾乎所有功能都需要第三方的中間件來輔助完成,使用了node的新特性,比express更簡潔,更輕量

    • express與koa對(duì)比

      • koa相對(duì)于express更加年輕,意味著express生態(tài)更加成熟,koa比express更加輕量,本身只提供一個(gè)架子,幾乎所有功能都需要依賴于第三方插件,而express自身就集成了許多功能,這也意味著express更加笨重,會(huì)產(chǎn)生冗余的功能,express對(duì)于初學(xué)者更加友好,自身的功能足夠使用,而koa則學(xué)習(xí)成本更高,畢竟連核心的路由也去掉了,都需要通過學(xué)習(xí)第三方中間件來實(shí)現(xiàn),而很多中間件的功能一樣,api卻不同,koa使用了很多node的新特性及es6的新特性,而express則語法上比較陳舊一點(diǎn),但是兼容性更好

      • koa起步

      • 生成項(xiàng)目文件并初始化包管理文件package.json

      • mkdir myapp && cd myapp && npm init -y
        
      • 下載koa模塊

      • npm install koa -S
        
      • 創(chuàng)建app.js

      • touch app.js
        
      • 編輯app.js

      • // 引入koa模塊
        const Koa = require('koa');
        // 實(shí)例化koa
        const app = new Koa();
        // 創(chuàng)建接受Context對(duì)象的函數(shù),Context由koa提供,表示一次對(duì)話的上下文
        const main = ctx => {
          // ctx包含請(qǐng)求及響應(yīng)對(duì)象,通過響應(yīng)對(duì)象的body設(shè)置返回的內(nèi)容
          ctx.response.body = 'Hello World';
        }
        // 使用加載main函數(shù),注冊(cè)到koa
        app.use(main);
        // 監(jiān)聽并啟動(dòng)服務(wù)
        app.listen(3000);
        
      • 銜接上文對(duì)象,ctx.response.type設(shè)置返回?cái)?shù)據(jù)類型

      • const Koa = require('koa');
        const app = new Koa();
        const main = ctx => {
          // text或text/plain純文本
          // html或text/html解析為html
          // json
          ctx.response.type = 'html';
          ctx.response.body = 'Hello World';
        }
        app.use(main);
        app.listen(3000);
        
      • 路由

        • 簡單來說路由間url到函數(shù)的映射,一個(gè)url指向一個(gè)地址,由此執(zhí)行一個(gè)對(duì)應(yīng)的規(guī)則,通常在web中理解為一個(gè)函數(shù),而url到這個(gè)函數(shù)的過程稱之為路由

        • 原生路由

          • 網(wǎng)站一般都是由多個(gè)頁面組成的,不同的url指向不同的頁面,在koa中可以通過ctx.request.path獲取用戶請(qǐng)求的路徑

          • 我們可以將我們的body指向一個(gè)網(wǎng)頁模板,通過fs.createReadStream()獲取文件流

          • const Koa = require('koa');
            const fs = require('fs');
            const app = new Koa();
            const main = ctx => {
              ctx.response.type = 'html';
              if(ctx.request.path === '/') {
                ctx.response.body = fs.createReadStream('./index.html');
              }
              else {
                ctx.response.body = '頁面未找到';
              }
            }
            app.use(main);
            app.listen(3000);
            
        • 中間件

          • 簡單來說就是處于操作系統(tǒng)和應(yīng)用軟件之間的一個(gè)類或者說插件,具有承上啟下的作用,用于連接兩個(gè)模塊,可重用與業(yè)務(wù)邏輯無關(guān)的各種組件
        • koa-route模塊

          • koa-route是koa的一個(gè)第三方中間件

          • const Koa = require('koa');
            
            const app = new Koa();
            
            const fs = require('fs');
            
            const route = require('koa-route');
            
            const about = require('./about.js');
            
            const home = require('./home.js');
            
            app.use(route.get('/home', home));
            
            app.use(route.get('/about', about));
            
            app.listen(3000);
            
          • home.js

          • const home = cxt => {
                console.log(cxt)
                cxt.response.body = '首頁';
            }
            module.exports = home;
            
          • about.js

          • const about = cxt => {
                cxt.response.body = '關(guān)于我們';
            }
            module.exports = about;
            
        • 靜態(tài)資源

          • 網(wǎng)站的靜態(tài)資源(腳本、圖片、字體、樣式表),假如為他們都寫一個(gè)路由將會(huì)很麻煩,比如用戶需要單獨(dú)訪問該服務(wù)地址下的一張圖片

          • 這里用到了koa-static

          • const Koa = require('koa');
            const app = new Koa();
            const path = require('path');
            const static = require('koa-static');
            const main = static(path.join(__dirname, 'static'));
            app.use(main);
            app.listen(3000);
            
        • 重定向

          • 重新指定方向(路由),有時(shí)候當(dāng)用戶訪問一個(gè)頁面,當(dāng)用戶權(quán)限不夠或者其他問題的時(shí)候,我們需要給用戶一個(gè)響應(yīng),則需要重新為用戶指定頁面

          • const Koa = require('koa');
            const app = new Koa();
            const route = require('koa-route');
            const redirect = ctx => {
                ctx.response.redirect('/');
            };
            const main = ctx => {
                ctx.response.body = '首頁';
            };
              
            app.use(route.get('/redirect', redirect));
            app.use(route.get('/', main));
            app.listen(3000);
            
        • 異步中間件

          • 當(dāng)出現(xiàn)異步操作時(shí),比如異步讀取文件,查詢數(shù)據(jù)庫等,我們就必須把我們的中間件設(shè)置為異步

          • const Koa = require('koa');
            const app = new Koa();
            const route = require('koa-route');
            const fs = require('fs');
            function readFile() {
                return new Promise((resolve, reject) => {
                    fs.readFile('./index.html', (err, data) => {
                        resolve(data);
                    })
                })
            }
            const main = async function (ctx, next) {
                ctx.response.type = 'html';
                ctx.response.body = await readFile();
            };
              
            app.use(main);
            app.listen(2000);
            
        • 中間件的合成

          • koa-compose模塊可以將多個(gè)中間件合成為一個(gè)

          • const compose = require('koa-compose');
            
            const logger = (ctx, next) => {
              console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`);
              next();
            }
            
            const main = ctx => {
              ctx.response.body = 'Hello World';
            };
            
            const middlewares = compose([logger, main]);
            app.use(middlewares);
            
        • 錯(cuò)誤處理

          • 如果代碼運(yùn)行過程中發(fā)生錯(cuò)誤,我們需要把錯(cuò)誤信息返回給用戶。HTTP 協(xié)定約定這時(shí)要返回500狀態(tài)碼。

          • ctx.throw()

          • const Koa = require('koa');
            const app = new Koa();
            const main = async function (ctx, next) {
                ctx.throw(500)
            };
              
            app.use(main);
            app.listen(2000);
            
        • 404錯(cuò)誤

          • const main = ctx => {
              ctx.response.status = 404;// 等同于ctx.throw(404)
              ctx.response.body = 'Page Not Found';
            };
            
        • 錯(cuò)誤處理中間件

          • const handler = async (ctx, next) => {
              try {
                await next();
              } catch (err) {
                ctx.response.status = err.statusCode || err.status || 500;
                ctx.response.body = {
                  message: err.message
                };
              }
            };
            
            const main = ctx => {
              ctx.throw(500);
            };
            
            app.use(handler);
            app.use(main);
            
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。