koa2 入门及express应用迁移到koa2实例

来源:互联网 发布:软件开发做账 编辑:程序博客网 时间:2024/06/01 20:56

首先双手奉上koa的官网:点击这里

嗯,非常简洁,而且是英文的

这个是中文的:koa.js

这篇博文涉及到的两个项目工程都已上传到github:点击这里


koa–基于node.js平台的下一代web开发框架

这是官网的说明

koa也是express框架的原班人马打造的

koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。

可以看到在说明里最重要的就是,解决异步编程回调问题,通过引入ES6 中generator的概念来实现的

koa2中也开始用es7中的async概念来更加优雅的解决异步编程问题~

如果对这些概念不是很了解的话,阮老师的书会是你的好朋友的:ECMAScript6入门

任何的入门都是从hello world开始的,我们来从头开始建立一个hello world工程

我这里的环境: node 6.11

首先全局安装koa-generator:npm install -g koa-generator

这个项目生成器不是koa官方的,是社区里一位大神做出的贡献

好的安装完毕,然后用这个koa-generator来自动建立一个koa2项目(它同时也可以自动建立koa项目的)

koa2 koa2-test

项目建立完成,接下来用webstorm或者sublime打开项目

这是创建好的koa2项目

打开app.js之后发现好多报错

比如说这样的:

仔细一看,都是es6,es7的新语法使IDE报错了,很好解决

打开setting,将下面的选项里面的设置改成ECMAScript 6就OK了

再安装项目依赖项:npm install

安装完成,我们运行一下试试

npm run start

但是,报错了……

G:\node\koa2-test>npm start> koa2-test@0.1.0 start G:\node\koa2-test> node bin/wwwG:\node\koa2-test\app.js:28app.use(async (ctx, next) => {              ^SyntaxError: Unexpected token (    at createScript (vm.js:56:10)    at Object.runInThisContext (vm.js:97:10)    at Module._compile (module.js:542:28)    at Object.Module._extensions..js (module.js:579:10)    at Module.load (module.js:487:32)    at tryModuleLoad (module.js:446:12)    at Function.Module._load (module.js:438:3)    at Module.require (module.js:497:17)    at require (internal/module.js:20:19)    at Object.<anonymous> (G:\node\koa2-test\bin\www:7:11)npm ERR! Windows_NT 10.0.10240npm ERR! argv "D:\\nodejs\\node.exe" "D:\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "start"npm ERR! node v6.11.2npm ERR! npm  v3.10.10npm ERR! code ELIFECYCLEnpm ERR! koa2-test@0.1.0 start: `node bin/www`npm ERR! Exit status 1npm ERR!npm ERR! Failed at the koa2-test@0.1.0 start script 'node bin/www'.npm ERR! Make sure you have the latest version of node.js and npm installed.npm ERR! If you do, this is most likely a problem with the koa2-test package,npm ERR! not with npm itself.npm ERR! Tell the author that this fails on your system:npm ERR!     node bin/wwwnpm ERR! You can get information on how to open an issue for this project with:npm ERR!     npm bugs koa2-testnpm ERR! Or if that isn't available, you can get their info via:npm ERR!     npm owner ls koa2-testnpm ERR! There is likely additional logging output above.npm ERR! Please include the following file with any support request:npm ERR!     G:\node\koa2-test\npm-debug.log

大概看了一下,发现是async这个新语法,node它不认识……

虽然我们之前设置了一下IDE,让IDE认识了ES6和ES7,但是运行这个application,node不认识的话就没办法运行了啊

怎么办呢?机智的你一定想到了babel

是的,就是它~

我们来安装babel转码器,使得node能够“认识” ES6,ES7新语法

npm install --save-dev babel-core babel-polyfill babel-preset-es2015 babel-preset-stage-3

等待安装完成~

然后在入口文件 bin/www 中使用babel,将下面的代码放在var app=require(‘../app’)前面

require("babel-polyfill");require('babel-core/register')({    presets: ['es2015', 'stage-3']});

然后再运行试试:npm start

这次没有报错了,我们在浏览器里输入localhost:3000试试

界面出来了,访问成功~


然后我们再来认真的看了一下项目~

这个是项目结构

观察一下

首先是app.js

const Koa = require('koa');const app = new Koa();const views = require('koa-views');const json = require('koa-json');const onerror = require('koa-onerror');const bodyparser = require('koa-bodyparser');const logger = require('koa-logger');const index = require('./routes/index');const users = require('./routes/users');// error handleronerror(app);// middlewaresapp.use(bodyparser({    enableTypes: ['json', 'form', 'text']}));app.use(json());app.use(logger());app.use(require('koa-static')(__dirname + '/public'));app.use(views(__dirname + '/views', {    extension: 'pug'}));// loggerapp.use(async (ctx, next) => {    const start = new Date();    await next();    const ms = new Date() - start;    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);});// routesapp.use(index.routes(), index.allowedMethods());app.use(users.routes(), users.allowedMethods());// error-handlingapp.on('error', (err, ctx) => {    console.error('server error', err, ctx);});module.exports = app;

使用过express的一定很熟悉,因为他们的代码结构差不多(出自于同一个团队,不足为奇)

先是加载Koa和各个中间件,然后配置他们

值得注意的是logger的配置代码

app.use(async (ctx, next) => {    const start = new Date();    await next();    const ms = new Date() - start();    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);});

如果不熟悉ES6/ES7的话,那一定一脸懵逼

这是箭头函数和异步新写法async+await

我们再来看看index.js

const router = require('koa-router')();router.get('/', async (ctx, next) => {    await ctx.render('index', {        title: 'Hello Koa 2!'    });});router.get('/string', async (ctx, next) => {    ctx.body = 'koa2 string';});router.get('/json', async (ctx, next) => {    ctx.body = {        title: 'koa2 json'    };});module.exports = router;

这个示例代码给出了3种常用路由方法

users.js

const router = require('koa-router')();router.prefix('/users');router.get('/', function (ctx, next) {    ctx.body = 'this is a users response!';});router.get('/bar', function (ctx, next) {    ctx.body = 'this is a users/bar response';});module.exports = router;

模版代码是pug,不要懵逼,其实它就是jade…因为商标的原因改名成pug而已……学习资料:Pug模版


然后我打算以这个建好的种子工程去重构一下我以前的一个程序

开工!

首先奉上我以前写的一个photo wall程序,非常简单,拿来学习再合适不过了,github地址:点击这里

首先我们先来运行一下原来的程序

只有1张图,效果不是很明显……

主页的应用逻辑就是这样:node从public目录下读取imgages目录下的图片,路径存储到json数组中,然后传到前端模版中遍历显示出来

首先是html代码,当初写的时候主要是为了摸索express,所以前端就直接用的一个Bootstrap的模版了

所以我们首先把静态资源拷贝过去

然后再来拷贝html代码,这里需要注意的是以前用的是ejs模版,和html很像,但是jade就……

所以如果不想重新从头到尾写一次的话,就用在线的转码器吧,比如说这个:点击这里

这是转换后的index.pug

doctype html//if lt IE 7  html.no-js.lt-ie9.lt-ie8.lt-ie7//if IE 7  html.no-js.lt-ie9.lt-ie8//if IE 8  html.no-js.lt-ie9// [if gt IE 8] <!|html.no-js  // <![endif]  head    meta(charset="utf-8")    |    title Photo Wall    |    meta(name="viewport", content="width=device-width, initial-scale=1")    // Animate.css    link(rel="stylesheet", href="/css/animate.css")    // Icomoon Icon Fonts    link(rel="stylesheet", href="/css/icomoon.css")    // Magnific Popup    link(rel="stylesheet", href="/css/magnific-popup.css")    // Salvattore    link(rel="stylesheet", href="/css/salvattore.css")    // Theme Style    link(rel="stylesheet", href="/css/style.css")    // Modernizr JS    script(src="js/modernizr-2.6.2.min.js")    // FOR IE9 below    //if lt IE 9      script(src="/js/respond.min.js")  body    #fh5co-offcanvass      a.fh5co-offcanvass-close.js-fh5co-offcanvass-close(href="#")        | 菜单        i.icon-cross      |      h1.fh5co-logo        a.navbar-brand(href="/") Photo wall      |      ul        li.active          a(href="/") 主页        |        li          a(href="/upload") 上传        |        li          a(href="/delete") 删除      |      h3.fh5co-lead Connect me in seekhow    header#fh5co-header(role="banner")      .container        .row          .col-md-12            a.fh5co-menu-btn.js-fh5co-menu-btn(href="#")              | 菜单              i.icon-menu            |            a.navbar-brand(href="/") Photo wall    // END .header    #fh5co-main      .container        .row          #fh5co-board(data-columns="")            .item              .animate-box                a.image-popup.fh5co-board-img(href="/images/QQ图片20170404163104.jpg", title="QQ图片20170404163104.jpg")                  img(src="/images/QQ图片20170404163104.jpg", alt="This image not exist")              |              .fh5co-desc 2333    footer#fh5co-footer      .container        .row.row-padded          .col-md-12.text-center            p.fh5co-social-icons              a(href="#")                i.icon-twitter              |              a(href="#")                i.icon-facebook              |              a(href="#")                i.icon-instagram              |              a(href="#")                i.icon-dribbble              |              a(href="#")                i.icon-youtube            |            p              small just an exercise program    // jQuery    script(src="/js/jquery.min.js")    // jQuery Easing    script(src="/js/jquery.easing.1.3.js")    // Bootstrap    script(src="/js/bootstrap.min.js")    // Waypoints    script(src="/js/jquery.waypoints.min.js")    // Magnific Popup    script(src="/js/jquery.magnific-popup.min.js")    // Salvattore    script(src="/js/salvattore.min.js")    // Main JS    script(src="/js/main.js")

很明显,完全不像html了,如果之前没接触过jade的话,基本就是GG了,这里是jade语法简略介绍:jade语法学习

好的,静态的网页资源算是迁移完了

接下来,我们来运行一下试试

修改index.js里面的 ‘/’路由

router.get('/', async (ctx, next) => {    await ctx.render('index');});

然后 npm run start

好的,运行成功,不过现在只是加载的固定资源,我们做的是要传递一个文件夹里的所有图片过去遍历展示,所以先修改jade模版

需要重复出现的就是这段模版

.item     .animate-box        a.image-popup.fh5co-board-img(href="/images/QQ图片20170404163104.jpg", title="QQ图片20170404163104.jpg")                  img(src="/images/QQ图片20170404163104.jpg", alt="This image not exist")        |       .fh5co-desc 2333

我们先修改后端的代码,模拟一个json数组,存储的是图片的名字和路径
修改index.js

router.get('/', async (ctx, next) => {    let imgs = [        {"imgPath":"/images/QQ图片20170404163104.jpg",        "imgName":"QQ图片20170404163104"},        {"imgPath":"/images/timg.jpg",        "imgName":"timg"}        ];    await ctx.render('index',{'imgs':imgs});});

这段代码的意思是:当路由为”/”的时候,渲染index这个模版,并传输imgs这个数组

然后我们再修改index.pug,让它遍历传过来的数据,把图片都显示出来
index.pug

 each item in imgs               .item                 .animate-box                   a.image-popup.fh5co-board-img(href=item.imgPath, title=item.imgName)                     img(src=item.imgPath, alt="This image not exist")                   |                 .fh5co-desc 2333

两个item没有关系。。。

然后运行一下

成功~

原创粉丝点击