Koa2快速入门上手

  |     |   本文总阅读量:

Koa2快速入门上手

Koa2快速开始

Koa2路由


Koa2快速开始

  • 环境准备

    • 由于Koa中使用的是 async/await 的语法,所有需要NodeJS的版本在 7.6.0 以上,注:7.6.0开始完全支持 async/await
    • npm 版本需要 3.x 以上
  • 编写Koa2的第一个Demo

    • 创建一个 quick-start 文件夹作为项目文件夹

      1
      mkdir quick-start && cd quick-start
    • 初始化项目并安装koa

      1
      2
      3
      4
      5
      6
      7
      8
      # 初始化项目,填写相应信息
      yarn init

      # 安装 koa
      yarn add koa

      # 创建一个 index.js
      touch index.js
    • 编写一个Koa程序

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      const Koa = require("koa");

      const app = new Koa();

      app.use(async ctx => {
      ctx.body = "Hello Koa2!";
      });

      app.listen(8080, () => {
      console.log("The Server Start At Port 8080 !");
      });
    • 启动项目并查看结果

      1
      node index.js

      打开浏览器访问 http://localhost:8080/ ,效果如下:

      Koa2第一个Demo程序

  • async/await 的特点

    • 可以使异步逻辑用同步写法实现
    • 最底层的 await 返回需要是 Promise对象
    • 可以解决传统的回调地狱问题
  • Koa结构简析

    • Koa 源码地址: https://github.com/koajs/koa
    • Koa 源码在项目的 lib 文件夹下,我们可以看到有四个文件
      • application.js:整个Koa的入口文件,封装了 contextrequestresponse 以及最核心的中间件处理流程
      • context.js:处理应用上下文,里面直接封装部分 request.js 和 response.js 的方法
      • request.js:处理 http请求
      • response.js:处理 http响应
    • Koa的特性
      • 只提供封装好了 http上下文请求响应 以及基于 async/await 的中间件容器
      • 利用ES7的 async/await 来处理传统的回调嵌套问题以及替代 generator函数
      • 中间件只支持使用 async/await 封装的中间件,如果使用 generator函数 中间件,需要通过 koa-convert 封装一下才可使用
  • 编写Koa中间件

    • 使用 generator函数 编写中间件

      • 中间件代码

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        # logger-generator.js
        function log(ctx) {
        console.log(ctx.method, ctx.header.host + ctx.url);
        }

        module.exports = function() {
        return function*(next) {
        // 执行中间件的操作
        log(this);

        if (next) {
        yield next;
        }
        };
        };
      • 在Koa1中编写中间件

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        # index.js
        const Koa = require("koa");
        const logger = require("./middleware/logger-generator");

        const app = new Koa();

        app.use(logger());

        app.use(function*() {
        ctx.body = "Hello Koa1 Gneerator";
        });

        app.listen(8080, () => {
        console.log("The Server Start At Port 8080 !");
        });
      • 在Koa2中编写中间件

        1
        2
        # 安装 koa-convert
        yarn add koa-convert
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        # index.js
        const Koa = require("koa");
        const convert = require("koa-convert");
        const logger = require("./middleware/logger-generator");

        const app = new Koa();

        app.use(convert(logger()));

        app.use(ctx => {
        ctx.body = "Hello Koa2 Gneerator";
        });

        app.listen(8080, () => {
        console.log("The Server Start At Port 8080 !");
        });
    • 使用 async/await 编写中间件

      • 中间件代码

        1
        2
        3
        4
        5
        6
        7
        8
        9
        module.exports = (ctx, next) => {
        console.log(
        "logger async middleware",
        ctx.method,
        ctx.header.host + ctx.url
        );

        next();
        };
      • 使用中间件

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        const Koa = require("koa");
        const logger = require("./middleware/logger-async");

        const app = new Koa();


        app.use(logger);

        app.use(async ctx => {
        ctx.body = "Hello Koa Async Middleware!";
        });

        app.listen(8080, () => {
        console.log("The Server Start At Port 8080 !");
        });

Koa2路由

  • Koa原生路由

    路由指的就是我们请求的URL地址,Koa的 url 存储在 ctx.request 对象中;我们看如下的代码:将请求的url地址,显示在浏览器中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    const Koa = require("koa");

    const app = new Koa();

    app.use(ctx => {
    const url = ctx.request.url;
    ctx.body = { url };
    });

    app.listen(3000, () => {
    console.log("The server running at: http://localhost:3000/");
    });


    // 浏览器访问: http://localhost:3000/users
    // 返回: { url: '/users' }


    // 浏览器访问: http://localhost:3000/hello/world
    // 返回: { url: '/hello/world' }

    // 读者可自己多测试一些url
    • 定制化路由

      • 创建一个文件夹作为项目目录, 并初始化项目、安装依赖

        1
        2
        3
        mkdir custom-router && cd custom-router
        yarn init -y
        yarn add koa
      • 新建 index.js 文件,作为项目的主入口文件

      • 创建 views 文件夹,作为视图文件的根目录。分别新建 not-found.htmlusers.htmltodo.htmlindex.html

      • 编写路由处理核心代码:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        const Koa = require("koa");
        const path = require("path");
        const fs = require("fs");

        const app = new Koa();

        /**
        * 使用Promise封装文件读取函数
        * @param {string} page 文件名称(包含后缀名)
        */
        const render = page => {
        return new Promise((resolve, reject) => {
        const pageUrl = path.join(__dirname, `./views/${page}`);
        fs.readFile(pageUrl, "utf8", (err, data) => {
        if (!err) {
        resolve(data);
        } else {
        reject(err);
        }
        });
        });
        };

        /**
        * 根据url获取渲染的HTML文件
        * @param {*} url 请求url
        */
        const route = async url => {
        let view;
        switch (url) {
        case "/":
        case "/index":
        view = "index.html";
        break;
        case "/users":
        view = "users.html";
        break;
        case "/todo":
        view = "todo.html";
        break;
        default:
        view = "not-found.html";
        break;
        }
        const html = await render(view);
        return html;
        };

        app.use(async ctx => {
        const url = ctx.request.url;
        const html = await route(url);
        ctx.body = html;
        });

        app.listen(3000, () => {
        console.log("The server running at: http://localhost:3000/");
        });
      • 其他文件源码参考

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        <!-- index.html -->
        <!DOCTYPE html>
        <html lang="en">
        <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>首页</title>
        <style>
        .index {
        display: flex;
        justify-content: center;
        align-items: center;
        }
        </style>
        </head>
        <body>
        <div class="index">
        <h1>首页</h1>
        <ul>
        <li><a href="/users">用户列表</a></li>
        <li><a href="/todo">待办事项</a></li>
        </ul>
        </div>
        </body>
        </html>
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        <!-- users.html -->
        <!DOCTYPE html>
        <html lang="en">
        <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>用户页列表</title>
        <style>
        .users {
        margin: 0 auto;
        padding: 20px;
        }

        span {
        margin-right: 50px;
        }

        span.title {
        font-weight: bolder;
        }
        </style>
        </head>
        <body>
        <div class="users">
        <h1>用户列表</h1>
        <p>
        <span class="title">用户名</span>
        <span class="title">年龄</span>
        <span class="title">地址</span>
        </p>
        <hr />
        <p>
        <span>Divier</span>
        <span>18</span>
        <span>北京市海淀区中关村</span>
        </p>
        <p>
        <span>陈皮皮</span>
        <span>20</span>
        <span>北京市昌平区回龙观</span>
        </p>
        <p>
        <span>哈士奇</span>
        <span>16</span>
        <span>北京市朝阳区望京</span>
        </p>
        </div>
        </body>
        </html>
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        <!-- todo.html -->
        <!DOCTYPE html>
        <html lang="en">
        <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>代办清单</title>
        <style>
        .todo {
        margin: 0 auto;
        }
        </style>
        </head>
        <body>
        <div class="todo">
        <h1>代办清单列表</h1>
        <ul>
        <li>学习Koa</li>
        <li>洗衣做饭</li>
        <li>跑步</li>
        </ul>
        </div>
        </body>
        </html>
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        <!-- not-found.html -->
        <!DOCTYPE html>
        <html lang="en">
        <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>404</title>
        <style>
        h1 {
        text-align: center;
        }
        </style>
        </head>
        <body>
        <h1>您访问的地址不存在!</h1>
        </body>
        </html>
      • 运行项目

        1
        node index.js
      • 访问效果

  • Koa Router路由系统


赏作者一颗糖吧, 您的支持将鼓励我继续创作!



文章目录
  1. 1. Koa2快速入门上手
    1. 1.0.1. Koa2快速开始
    2. 1.0.2. Koa2路由
您是第 位小伙伴 | 本站总访问量 | 已经写了 22.6k 字啦

载入天数...载入时分秒...