美文网首页
从零开始创建简单 koa2 应用

从零开始创建简单 koa2 应用

作者: wwpeng520 | 来源:发表于2018-06-02 13:11 被阅读0次

创建一个 koa2 工程

mkdir hello-koa2 && cd hello-koa2

npm init

yarn add koa

通过以上命令行创建一个文件夹 hello-koa2,并进入该文件夹,然后我们初始化一个项目并安装 koa。
接下来用编辑器(如vscode)打开项目,创建文件app.js,输入以下代码:(当然,最好使用 git 方式管理项目)

const Koa = require('koa');
const app = new Koa();

// 对于任何请求,app 将调用该异步函数处理请求:
app.use(async(ctx, next) => {
    await next();
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, koa2!</h1>';
});

app.listen(3000);

此时通过命令 node app.js 我们就可以项目可以运行了,浏览器打开http://localhost:3000/就可以看到内容了。
我们可以把该命令放到 package.json 的 scripts 下,后续可以一步一步构建一个完善的项目框架。

创建 middleware

什么我们已经使用 app.use 方法处理请求了,我们在该函数中使用了await next()方法,我们知道 koa2 是洋葱圈模型。当一个请求过来的时候,会依次经过各个中间件进行处理,中间件跳转的信号是await(yield) next,当到某个中间件后,该中间件处理完不执行await next的时候,然后就会逆序执行前面那些中间件剩下的逻辑,组成一个处理链。
根据这个逻辑,我们在处理过程中自己添加 middleware,做一些我们想做的事情。以下是摘自网上的一个示例:

app.use(async (ctx, next) => {
    console.log(`${ctx.request.method} ${ctx.request.url}`); // 打印URL
    await next(); // 调用下一个middleware
});

app.use(async (ctx, next) => {
    const start = new Date().getTime(); // 当前时间
    await next(); // 调用下一个middleware
    const ms = new Date().getTime() - start; // 耗费时间
    console.log(`Time: ${ms}ms`); // 打印耗费时间
});

app.use(async (ctx, next) => {
    await next();
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, koa2!</h1>';
});

处理 URL

在以上的代码中我们对所有 URL 返回的是一样的内容,实际情况下不可能如此。正常情况下,我们应该对不同的 URL 调用不同的处理函数,返回不同的结果。例如:

app.use(async (ctx, next) => {
    if (ctx.request.path === '/') {
        ctx.response.body = 'HOME page';
    } else {
        await next();
    }
});

app.use(async (ctx, next) => {
    if (ctx.request.path === '/user') {
        ctx.response.body = 'USER page';
    } else {
        await next();
    }
});

我们可以使用 koa-router 这个 middleware,让它负责处理 URL 映射。安装 koa-router

yarn add koa-router

然后把 app.js 改造如下:

const Koa = require('koa');
const app = new Koa();
const Router = require('koa-router');
const router = new Router();

app.use(async(ctx, next) => {
    console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);
    await next();
});

router.get('/hello/:name', async(ctx, next) => {
    let name = ctx.params.name;
    ctx.response.body = `<h1>Hello, ${name}!</h1>`;
});

router.get('/', async(ctx, next) => {
    ctx.response.body = '<h1>Home page</h1>';
});

app.use(router.routes());

app.listen(3000);

然后我们可以看到请求根页面//hello/:name显示的内容就不一样了。

处理 post 请求

上面我们用到的都是 get 请求,接下来我们试一下 post 请求。
我们使用koa-bodyparser组件来解析我们获取的 request 对象。 安装yarn add koa-bodyparser完之后在 app.js 中引入 koa-bodyparser。由于middleware的顺序很重要,这个koa-bodyparser必须在router之前被注册到app对象上。

const bodyParser = require('koa-bodyparser');

// 在合适的位置加上
app.use(bodyParser());

接下来我们就可以测试 post 请求了。同理,patch、delete、put等请求也可以由 router 处理。

router.post('/login', async (ctx, next) => {
    let
        name = ctx.request.body.name || '',
        password = ctx.request.body.password || '';
    console.log(`login with name: ${name}, password: ${password}`);
    if (name === 'hello' && password === '123456') {
        ctx.response.body = `<h1>Welcome, ${name}!</h1>`;
    } else {
        ctx.response.body = `<h1>Login failed!</h1>
        <p><a href="/">Try again</a></p>`;
    }
});

调整项目结构

随着 URL 请求数量的越来越多,app.js 就会越来越长,这样不利于项目的管理和拓展。
如果能把 URL 处理函数集中到特定 js 文件,然后让 app.js 自动导入所有处理 URL 的函数。这样,代码一分离,逻辑就显得清楚了。我们可以在根目录下创建 controllers 文件夹,按照分类把各 url 处理函数放在该目录下的不同 js 文件。
例如我们可以在 controllers 目录下创建 hello.js 文件,内容如下:

let fn_hello = async(ctx, next) => {
    let name = ctx.params.name;
    ctx.response.body = `<h1>Hello, ${name}!</h1>`;
};

module.exports = {
    'GET /hello/:name': fn_hello
};

app.js 修改:

const files = fs.readdirSync(__dirname + '/controllers');

// 过滤出.js文件:
const js_files = files.filter((file)=>{
    return file.endsWith('.js');
});

// 处理每个js文件:
for (let f of js_files) {
    console.log(`process controller: ${f}...`);
    // 导入js文件:
    let mapping = require(__dirname + '/controllers/' + f);
    for (var url in mapping) {
        if (url.startsWith('GET ')) {
            // 如果url类似"GET xxx":
            let path = url.substring(4);
            router.get(path, mapping[url]);
            console.log(`register URL mapping: GET ${path}`);
        } else if (url.startsWith('POST ')) {
            // 如果url类似"POST xxx":
            let path = url.substring(5);
            router.post(path, mapping[url]);
            console.log(`register URL mapping: POST ${path}`);
        } else {
            // 无效的URL:
            console.log(`invalid URL: ${url}`);
        }
    }
}

使用模板引擎

模板引擎有很多,比如 pug, ejs, nunjucks...,这里以 nunjucks 为例,配合 koa-views 中间件。
我们需要创建一个 views 文件夹,用来存放我们的目标文件。

 app.use(views(path.join(__dirname, './views'), {
    map: {
        html: 'nunjucks'
    },
    extension: 'html'
}));

// 简单用法如下
app.use(async(ctx, next) => {
    if (ctx.request.path === '/hello') {
        let name = 'Koa2'
        await ctx.render('hello', {
            name,
        })
    } else {
        await next();
    }
});

使用其他中间件

创建 public 目录,用来存放公共资源,如 css, js, 图片, 字体等资源,使用koa-static

const static = require('koa-static');

app.use(static(path.join(__dirname, './public')));

相关文章

  • 从零开始创建简单 koa2 应用

    创建一个 koa2 工程 通过以上命令行创建一个文件夹 hello-koa2,并进入该文件夹,然后我们初始化一个项...

  • 5分钟入门Angular2.0

    本文将会不断更新和整理 让我们从零开始,创建一个超级简单的angular2.0的应用。文件结构: 1、创建一个新的...

  • 基于koa2创建api

    这里就不废话什么是node,node做什么之类的。目标就是创建基于koa2的一个node应用。环境:node v...

  • koa2中间件

    如何写一个koa2中间件呢?下面写一个简单的案例 创建koa2服务,新建一个文件 如何使用? 在需要使用的地方引入...

  • nuxt

    一、koa基础知识 koa-generator koa2脚手架创建项目:koa2 -e project -e表示...

  • 第1节 设计游戏窗口、背景颜色

    学习子弹飞机游戏,从零开始,坚持学习! 创建Pygame 窗口以及响应用户输入 安装pygame pip in...

  • Node 环境下配置 Babel

    最近用 Koa2 搞 node 服务端应用,鉴于官网文档太散,简单记录下配置 babel 的过程: 1. 安装需要...

  • Angular 2五分钟快速教程

    让我们从零开始用JavaScript创建一个Angular 2应用。(教程同时也有TypeScript版和Dart...

  • koa2+ Sequelize试玩

    创建koa2项目 安装koa-generator 生成koa2项目 安装并启动服务 打开浏览器并访问http://...

  • Node.js - koa入门

    摘要 - 廖雪峰JavaScript教程 创建一个koa2工程 首先,我们创建一个test目录,并在目录里面创建一...

网友评论

      本文标题:从零开始创建简单 koa2 应用

      本文链接:https://www.haomeiwen.com/subject/bvkrsftx.html