美文网首页
node.js笔记2

node.js笔记2

作者: 王大吉Rock | 来源:发表于2018-12-20 17:55 被阅读38次

    web开发框架、koa和koa-router、模板引擎、MVC

    web开发

    Web框架:提供了一套开发和部署网站的方式,提供web服务的。Express,Sails.js,koa,Meteor,DerbyJS,Total.js,restify

    ORM框架:对象-关系映射,通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。Sequelize,ORM2,Bookshelf.js,Objection.js

    模板引擎:基于模板配合数据构造出字符串输出的一个组件,能够编写几个HTML模板,并且用实际数据来渲染模板并获得最终的HTML输出,还可以避免输出恶意脚本。Jade,EJS,Swig,Nunjucks,doT.js

    测试框架、自动化构建工具:解决应用在浏览器的UI和功能上兼容性问题,并对网站资源进行优化,可以大大提高我们的工作效率。测试框架包括:Mocha,Expresso,Unit.js,Karma。构建工具有:Grunt,Gulp,Webpack。

    koa

    koa对httpm模块进行了封装。最新版本简化了异步的写法,结合Promise、async、箭头函数来实现异步。

    使用npm加载koa。

    使用koa来创建web服务:

    // 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
    
    const Koa = require('koa');
    
    // 创建一个Koa对象表示web app本身:
    const app = new Koa();
    
    app.use(async (ctx, next) => {
        
        console.log('第一1');
        await next();
        console.log('第一2');
    });
    
    app.use(async (ctx, next) => {
        console.log('第二1');
        await next();
        console.log('第二2');
    });
    
    // 对于任何请求,app将调用该异步函数处理请求:
    app.use(async (ctx, next) => {
        console.log('第三1 '  + ctx.request.URL);
        await next();
        ctx.response.type = 'text/html';
        ctx.response.body = '<h1>Hello, koa2!</h1>';
        console.log('第三2' );
    });
    
    // 在端口3000监听:
    app.listen(3000);
    console.log('app started at port 3000...');
    

    async函数await next()方法:使用app.ues()来注册async函数,将每一async函数称为middleware,将这些middleware组合起来形成一条链。使用await next()来调用下一个middleware,当没有调用await next()时下一个middleware是不会执行的。

    打印顺序:

    第一1
    第二1
    第三1 http://localhost:3000/
    第三2
    第二2
    第一2
    

    处理post请求:在package.json中引入koa-bodyparser依赖来解析request中的body,解析后会自动绑定到ctx.request.body中。

    koa-router

    对于任何请求都会走app.use()方法,处理不同的url访问,可能要写成这样:

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

    显然这种写法很心痛,koa-router库就是解决这个问题的,我们可以npm下把它引入到项目中。

    koa-router负责处理URL的映射。
    URL <===> controller。所有处理url的的异步函数 async (ctx, next) => {},都可以按照功能创建对应controller.js文件,并将这些controller.js放至controllesr文件夹下,就可以达到根据URL Router进行模块化。

    在app.js中的代码可以简化成:

    const router = require('koa-router')();
    
    // add url-route:
    router.get('/index', async (ctx, next) => {
        var name = ctx.params.name;
        ctx.response.body = 'index page';
    });
    
    router.get('/login', async (ctx, next) => {
        ctx.response.body = 'login page';
    });
    
    router.get('/login/success', async (ctx, next) => {
        ctx.response.body = 'login success';
    });
    
    app.use(router.routes());
    

    模板引擎

    模板引擎 + 输入的对象 => html

    // 模板引擎
    function render (name) {
        return `${name}, 生日快乐!`
    }
    
    // 生成的html
    var html = render({  name: '王大吉' });
    

    引擎模板的好处:转义
    、格式化、简单逻辑。

    Nunjucks模板引擎之一。

    基本使用:以上返回html字符串代码大致是这样的,以返回个人主页为例:

    const nunjucks = require('nunjucks');
    
    function createEnv(path, opts) {
        ...
        return env;
    }
    
    var env = createEnv('views', {
        ...
    });
    
    // 返回的html (需要绘制的界面,传入的对象)
    var s = env.render('hello.html', { name: ${name}});
    

    结合koa使用:在koa调用某一个异步函数来处理一个url时,使用Nunjucks输出需要显示的html,并赋值给response.body
    需要给ctx对象绑定一个render(view, model)方法,这样controller中就可以调用这个方法来渲染模板。

    Nunjucks提供的功能强大的tag,编写条件判断、循环等功能。

    模板的继承:网站的结构实际上是类似的,头部、尾部都是固定格式,只有中间页面部分内容不同。所以可以写一个基础的网页框架base.html

    <html><body>
    {% block header %} <h3>Unnamed</h3> {% endblock %}
    {% block body %} <div>No body</div> {% endblock %}
    {% block footer %} <div>copyright</div> {% endblock %}
    </body>
    

    子模块hello.html可以定义:

    <!-- 继承base.html -->
    {% extends 'base.html' %}
    
    <!-- header -->
    {% block header %}
    <body>
        <h1>{{ header }}</h1>
        <p>{{ name }}</p>
    </body>
    {% endblock %}
    
    <!-- body -->
    {% block body %}
    <body>
        <h1> body -- {{body}}</h1>
        {% for f in fruits %}
        <p>{{ f }}</p>
        {% endfor %}
    </body>
    {% endblock %}
    
    <!-- footer -->
    {% block footer %}
    <body>
        <h1> footer -- {{footer}} </h1>
        {% for f in fruits %}
        <p>{{ f }}</p>
        {% endfor %}
    </body>
    {% endblock %}
    

    如果model数据为:

    var renderdata = {
                 name: name ,
                  fruits: ['apple', 'o', '1'], 
                  header: '这是头部',
                   body: '这是内容', 
                   footer: '这是尾部'
                };
    

    执行env.render('hello.html', renderdata);后返回的html的代码为:

    <html><body>
    <body>
        <h1>这是头部</h1>
        <p>koa</p>
    </body>
    <body>
        <h1> body -- 这是内容</h1>
        <p>apple</p>
        <p>o</p>
        <p>1</p>
    </body>
    <body>
        <h1> footer -- 这是尾部 </h1>
        <p>apple</p>
        <p>o</p>
        <p>1</p>
    </body>
    </body>
    

    最终显示的效果图:

    通过Nunjucks将原来直接输出字符串的方式,改成通过指定参数通过赋值,用在指定的模板上,并渲染成HTML,然后输出给浏览器,用户就可以看到渲染后的页面。性能方面,Nunjucks是同步IO读取模板文件,但是有缓存机制,所以渲染返回字符串的效率是比较高的。

    MVC

    现在项目的目录结构:


    50231545298803_.pic_hd.jpg

    MVC分别代表的含义和作用:
    M:model,可以理解成js对象。
    V:view,通过简单的参数替换,输出html代码。
    C:controller,负责一些业务逻辑,网络请求、判断用户名是否存在,存储个人信息等。

    View是html,可以使用现成的Bootstrap的css框架,因为在生产和测试环境下加载css的方式是不一样的,要判断下环境:

    // 判断是否是生产环境
    const isProduction = process.env.NODE_ENV === 'production';
    if (! isProduction) {
        // 判断当前请求url是否是加载的是静态文件
        let staticFiles = require('./static-files');
        app.use(staticFiles('/static/', __dirname + '/static'));
    }
    

    使用static字符串来区分是否是静态文件的请求,使用Bootstrap的css框架:

    <!-- Bootstrap core CSS -->
    <link href="static/css/bootstrap.min.css" rel="stylesheet">
    

    在生产环境下,静态文件是由部署在最前面的反向代理服务器(如Nginx)处理的,Node程序不需要处理静态文件。而在开发环境下,我们希望koa能顺带处理静态文件,否则,就必须手动配置一个反向代理服务器,这样会导致开发环境非常复杂。

    /login登录界面:

    image.png

    登录成功或失败后,界面跳转至/signin界面:

    image.png

    demo地址

    相关文章

      网友评论

          本文标题:node.js笔记2

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