[Deprecated] Node.js学习记录 常用模块
在上一篇文章中,我们初步搭建了一个Node.js Web网页。在本文会着重介绍上一篇文章没有提到的常用的Api以及框架。
Node.js fs 模块
fs是filesystem的缩写,顾名思义,fs模块就是负责读写本地文件的。
1 | readFile(path, charset, callback(err, text)) //异步读取文件 |
这些函数基本上都是十分简单的,有趣的是基本每个函数都有同步和异步两个版本。以下给出示例:
1 | const fs = require('fs'); |
这里我列举了一些常用的,实际上还有fs.exists,fs.appendFile等一堆方法,具体请参考
Node.js官方文档。
顺便我这里为了写得方便,用了ES6的箭头函数、for..of循环,不了解ES6的话请去看一下
箭头函数
for…of循环
Koa 框架 中间件
还记得我们上一篇文章那个奇怪的语法吗?现在我们终于要了解这个啦。
1 | app.use(function *() { |
实际上这那个函数是一个Koa的中间件。这里是一个简化的写法,写完整应该是这样。
1 | app.use(function *(next) { |
这里最奇怪的东西就是,中间那个yield next是啥?
Gogo继续举例子。
1 | const Koa = require('koa'); |
当我们输入 localhost:3000 后,我们会在控制台上看到依次输出了1 3 4 2
。
为什么会是这个顺序?再仔细看一遍代码,或许你能猜到 yield next 的作用了。
yield next 表示去执行下一个中间件。
当第一个中间件输出 1 以后,遇到yield next 于是开始执行第二个中间件 输出 3。
因为没有第三个中间件了,所以第二个中间件继续执行输出 4。
第二个中间件执行完毕,再回到第一个中间件执行输出 2。
画张图来演示大概是这样。
这种写法的好处显而易见,整个程序处理是一条链式结构,所以添加或移除一个功能都十分容易。
例如,有几个页面我们希望用户登录以后才能显示。要添加这个功能,只需要在这几个页面前添加一个中间件,判断登录以后才会yield next 显示页面。如果某天不需要这个需求了,只需要移除中间件即可。
当然这不是中间件被设计出来的唯一的用处,事实上yield 能返回的不仅仅只有 next,它能返回任何一个thunk函数,真正作用实际上是把异步操作简化同步操作的写法,解决回调金字塔。这属于比较高深的内容,Gogo刚开始看到也是大脑短路两眼瞎掉。如果感兴趣的话可以阅读这两篇文章
《koa实战》
koa源码分析系列 co的实现
Koa 路由
在浏览网页的过程中,我们经常会注意到地址栏的变化,比如 example.com/a 是一个网页,example.com/b 是另一个网页。那么用Koa怎么实现不同地址对应不同网页的功能呢?
我们可以用Koa的path 来实现
1 | app.use(function*(next) { |
在浏览器地址栏中输入 localhost:3000,你会看到 home!
输入localhost:3000/hello则会看到 hello!
这里实际上就用到了我们刚刚提到的中间件的用法,判断一个网址是否符合,符合就输出那个中间件的内容。
但是这种写法也是会造成麻烦,难道我们每写一个页面,都需要把那么长一段代码复制一遍吗?再说中间件过多可能也会造成效率问题。
这时我们可以通过一个koa-router的模块来解决这个问题。
添加如下代码,并安装koa-router模块。
1 | const router = require('koa-router')(); |
这里要注意的是require(‘koa-router’)返回的是一个函数,我们直接调用这个函数得到router对象。
把路由的代码改成这样:
1 | const router = require('koa-router')(); |
貌似比前面那个版本简单不少,仔细想想还是不对劲啊,有很多个界面的话我是不是还是得抄好几遍?
行,我们继续简化。
我们先在项目根目录建一个 controllers 文件夹,在 controllers 中建一个 hello.js,内容如下。
1 | ; |
把App.js中的路由改成这样:
1 | const router = require('koa-router')(); |
通过这段代码,我们就能把controllers文件夹中所有路径以及处理的函数加载进来,要添加一个新的页面,只需要在controllers中新建一个js文件,并把对应的url和处理函数暴露出来即可。
Koa内置对象
说道Koa的内置对象,其实我们在前面就已经见到了几个,比如说中间件里的this 实际上就是context对象。
context对象代表一次HTTP请求和回应,通过它我们能获取请求数据,选择如何回应。
它主要有这么几个内容
1 | ctx.request //请求对象 |
其中重点是request和response对象,因此主要也就介绍这么两个对象。
先是request
1 | //示例: http://localhost:3000/hello?name=Gogo&id=1 |
通过request就能详细知道对方到底想干啥。其中最有用的应该是req.query
然后来看response,常用的没几个
1 | res.status //http状态码 |
常用的Koa对象就到这里了,一般来说能满足大部分需求了。
可以参考Koa文档
Nunjucks渲染模板
在开发中渲染一个字符串是一个很常见的需求。
比如有个这样的对象:
1 | var data = { |
我们需要把它渲染成
1 | 小明同学一年级期末考试语文78分,数学87分,位于年级第999名。 |
最古老的方法:
1 | data.name + "同学一年级期末考试语文" + data.chinese + "分,数学" |
Gogo感觉这么写挺反人类的。所幸的是ES6中JavaScript有了模板字符串的功能。
于是可以写成这样:
1 | `${data.name}同学一年级期末考试语文${data.chinese}分,数学${data.math}分,位于年级第${data.ranking}名。` |
对这个语法不熟悉的看这 ECMAScript 6 入门 模板字符串
但是这样拼接字符仍然无法满足web开发的需求,在web开发中,通常都是一个很长的html文件需要渲染输出,并且可能还需要判断、循环输出,因此拼接字符串并不是一个好的方法。Nunjucks就是解决这一问题的。
由于Nunjucks的官网提供了很详细的中文文档,因此Gogo在这里偷下懒,乃们自己看官网去吧。