初始Egg框架

栗路遥

前言

作为一名前端从业者不会点后端的知识怎么可以。node.js成为了前端了解后端的首选。工欲善其事,必先利其器本。一款好的框架。是提效的根本。这是一篇从0到1入门egg的文章。

三者区别与联系

Express是基于 Node.js平台,快速、开放、极简的 Web 开发框架,老牌框架,很多流行的框架的基石,简单且扩展性强,适合做个人项目,自身缺少约束。
Koa是基于Node.js平台的下一代web框架,由Express原班人马打造。特点:小巧灵活简单易用。作为企业级开发过于基础。
Egg为企业级框架和应用而生,奉行约定优于配置。Egg 继承于 Koa
特点:

  • 提供基于 Egg [定制上层框架]的能力
  • 高度可扩展的[插件机制]
  • 内置[多进程管理]
  • 基于 [Koa]开发,性能优异
  • 框架稳定,测试覆盖率高
  • [渐进式开发]

    起步

    初始化项目:(脚手架)

    $ mkdir project-name//创建一个空的文件夹
    $ npm init egg --type=simple//simple表示骨架类型

    骨架类型.png

    $ npm install || i //安装依赖

    初始化项目后结构目录如图所示
    egg初始化项目目录.png
    启动项目

    $ npm run dev//开发环境中使用
    $ npm run start//生产环境中使用

    文件目录介绍

    主要文件目录介绍

    |-app//主要开发的文件
    |   |-- controller//解析用户的输入,处理后返回相应的结果
    |   |-- db//启动mongodb数据库的dbpath路径(可选)
    |   |--extend//框架的扩展(内置对象扩展)
    |   |    |---application.js//(固定名称)
    |   |    |---context.js//(固定名称)
    |   |    |---request.js//(固定名称)
    |   |    |---response.js//(固定名称)
    |   |    |---helper.js//(固定名称)
    |   |--middleware//编写中间件
    |   |--model//数据库中表的模型
    |   |--publie//静态资源
    |   |--schedule//定时任务
    |   |--service//编写业务逻辑层
    |   |--view//模板文件
    |   |---router.js//配置 URL 路由
    |-config//存放配置文件
    |   |--config.default.js//用于编写配置文件
    |   |--plugin.js//配置需要加载的插件
    |-test//存放单元测试
    |-logs//日志文件
    |-package.json//项目描述

    内置对象

    Application//全局应用对象=》继承于koa
    Context//请求级别对象=》继承于koa
    Request//请求级别对象=》继承于koa
    Response//请求级别对象=》继承于koa
    Controller//基类
    Service//基类
    Helper//提供一些实用的 utility 函数,自身是一个类
    Config//配置
    Logger//功能强大的日志功能
    Subscription//基类定时任务

    路由(router)

    路由的作用:
    用来描述请求 URL 和具体承担执行动作的 Controller 的对应关系,用于统一所有路由规则。
    基本使用方法:
    在app/router.js中定义url的规则

    'use strict';
    module.exports = app => {
      const { router, controller } = app;
      //注册接口
      router.get('/logon', controller.logon.Logon);
    /**
    *路由参数说明
    *1.get请求
    *2.url为/logon
    *3.执行controller文件夹下的logon文件中的Logon方法
    **/ 
    };

    路由实战
    1.参数获取
    如果是get请求

    ctx.query
    //或
    ctx.params.xxx

    如果是post请求

    ctx.request.body

    2.中间件使用

    /*参数说明:
    verb表示请求方式例如get、post
    path-match表示路由url路径
    middleware1表示使用middleware1中间件可以添加多个中间件
    app.controller.action表示调用控制器中的方法
    */
    router.verb('path-match', middleware1, ..., middlewareN, app.controller.action);
    //例子
    'use strict';
    module.exports = app => {
      const { router, controller } = app;
    //获取中间件record=>app.middlewarel.xxx中xxx是middleware文件夹下对应的文件名
      const record=app.middlewarel.record();
      //注册接口使用中间件
      router.get('/logon',record, controller.logon.Logon);
    
    };

    3.多路由映射

    // app/router.js
    module.exports = app => {
      require('./router/news')(app);
      require('./router/admin')(app);
    };
    
    // app/router/news.js
    module.exports = app => {
      app.router.get('/news/list', app.controller.news.list);
      app.router.get('/news/detail', app.controller.news.detail);
    };
    
    // app/router/admin.js
    module.exports = app => {
      app.router.get('/admin/user', app.controller.admin.user);
      app.router.get('/admin/log', app.controller.admin.log);
    };

    控制器(controller)

    控制器的作用:
    负责解析用户的输入,处理后返回相应的结果
    基本使用方法:
    在app/controller/logon.js

    'use strict';
    const Controller = require('egg').Controller;
    class LogonController extends Controller {
      async Logon() {
    const { ctx } = this;
    const req=ctx.query;
    const res=await ctx.service.logonService.logonUser(req);
    ctx.body = {
        code:200,
        msg:res
    } 
      }
    }
    module.exports = LogonController;

    服务(service)

    服务的作用:
    复杂业务场景下用于做业务逻辑封装的一个抽象层
    基本使用方法:
    在app/service/logonService.js

    'use strict'
    const Service=require('egg').Service;
    class logonService extends Service {
    async logonUser(obj){
        const {ctx}=this;
        console.log(obj)
        const res=await ctx.model.UserModel.find(obj);
        console.log(res)
        if(res.length!=0){
            return "该用户名已存在"
        }else{
            //注意!!!!!!外部文件引用Model模块中ctx.model.xxx中xxx指的是对应模块文件文件名并且文件名首字母必须是大写的(这个就有点哔了个狗了)
            const _User = new ctx.model.UserModel({
                            UserName: obj.UserName,
                            PassWord: obj.PassWord,
                        });
                        // mongoose保存到数据库
                        _User.save();
                        return "注册成功"
        }            
    }
    }
    module.exports=logonService

    模块(model)

    模块的作用:
    定义数据表的内容
    基本使用方法:
    在app/model/UserModel.js

    module.exports=app=>{
    const {mongoose}=app;
    const {Schema}=mongoose;
    const UserSchema=new Schema({
            UserName:{type:String},
            PassWord:{type:String}
    });
    return mongoose.model('UserModel',UserSchema,'users')
    }

    插件

    基本使用方法:
    在config/plugin.js

    'use strict';
    module.exports = {
      mongoose:{
     enable:true,
     package:"egg-mongoose" 
      },
      cors:{
      enable: true,
      package: 'egg-cors'
      }
    };

    在confing/config.default.js

    'use strict';
    module.exports = appInfo => {
      /**
       * built-in config
       * @type {Egg.EggAppConfig}
       **/
      const config = exports = {};
      // use for cookie sign key, should change to your own and keep security
      config.keys = appInfo.name + '_1641975352438_173';
      // add your middleware config here
      config.middleware = [];
      // add your user config here
      const userConfig = {
    // myAppName: 'egg',
      };
      //跨域
      config.security={
      csrf:{
          enable:false
      },
      domainWhiteList:['*']
      }
      config.cors={
      origin:"*",
      allowMethods:"GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS"
      }
     //mongoose数据库配置
      config.mongoose={
      url:'mongodb://127.0.0.1:27021/VietNamVisa',
      options:{useNewUrlParser:true,useUnifiedTopology:true},//其他配置
      }
      return {
    ...config,
    ...userConfig,
      };
    };

    定时任务

    基本使用方法:
    在app/schedule

    const Subscription = require('egg').Subscription;
    class RemoveFile extends Subscription {
    // 通过 schedule 属性来设置定时任务的执行间隔等配置
    static get schedule() {
    return {
          interval: '1m', // 每1分钟
          type: 'all', /*参数有all和worker*/                   
        };
         }
    // subscribe 是真正定时任务执行时被运行的函数
     async subscribe() {
          //执行的方法
          }
      }
    module.exports =GetTime;

    简写

    module.exports = {
      schedule: {
       cron: '0 0 */3 * * *',//表示3小时执行
    type: 'all', // 指定所有的 worker 都需要执行
      },
      async task(ctx) {
    const res = await ctx.curl('http://www.api.com/cache', {
      dataType: 'json',
    });
    ctx.app.cache = res.data;
      },
    };

    框架扩展

    基本使用方法:
    在app/extend/application.js

    module.exports ={
    //方法扩展
        methodName(){
            const methodF=time()
            return methodF
                    }
    //属性扩展
    get attributeName(){
        return  "我是扩展属性"
        }
    function time(){
           方法内容。。。。
      }
      }

    使用application扩展的方法和属性

    const {app}=this
    //调用application扩展的方法
    app.methodName()
    ///调用application扩展的属性
    app.attributeName

    基本使用方法:
    在app/extend/context.js

    //扩展方法和属性同application相同

    使用application扩展的方法和属性

    const {ctx}=this
    //调用application扩展的方法
    ctx.methodName()
    ///调用application扩展的属性
    ctx.attributeName

    基本使用方法:
    在app/extend/request.js

    //同上

    访问方法:

    ctx.request.xxx

    基本使用方法:
    在app/extend/response.js

    //同上

    访问方法:

    ctx.response.xxx

    基本使用方法:
    在app/extend/helper.js

    //同上

    访问方法:

    ctx.helper.xxx

    以上就是egg基础知识的分享。

阅读 367
1 声望
0 粉丝
0 条评论
1 声望
0 粉丝
文章目录
宣传栏