EGGJS学习

版权声明: https://blog.csdn.net/weixin_33768153/article/details/84798155
  • 提供基于 Egg 定制上层框架的能力
  • 高度可扩展的插件机制
  • 内置多进程管理
  • 基于 Koa 开发,性能优异
  • 框架稳定,测试覆盖率高
  • 渐进式开发

目录结构

├── package.json
├── app.js (app.js 和 agent.js 用于自定义启动时的初始化工作)
├── agent.js (可选)
├── app
|   ├── router.js(用于配置 URL 路由规则)
│   ├── controller(用于解析用户的输入,处理后返回相应的结果)
│   |   └── home.js
│   ├── service (用于编写业务逻辑层,可选)
│   |   └── user.js
│   ├── middleware (用于编写中间件,可选)
│   |   └── response_time.js
│   ├── schedule (用于定时任务,可选)
│   |   └── my_task.js
│   ├── public (用于放置静态资源,可选)
│   |   └── reset.css
│   ├── extend (用于框架的扩展,可选)
│   |   └── application.js app 对象指的是 Koa 的全局应用对象,全局只有一个,在应用启动时被创建。
│       ├── context.js (Context 指的是 Koa 的请求上下文,这是 请求级别 的对象)
│       ├── request.js (Request 对象和 Koa 的 Request 对象相同,是 请求级别 的对象)
│       ├── response.js (Response 对象和 Koa 的 Response 对象相同,是 请求级别 的对象)
│       ├── helper.js (Helper 函数用来提供一些实用的 utility 函数)
│   ├── view (用于放置模板文件)
│   |   └── home.tpl
├── |── model (用于放置领域模型)
│   |   └── home.tpl
│   └── extend (用于框架的扩展)
│       ├── helper.js (可选)
│       ├── request.js (可选)
│       ├── response.js (可选)
│       ├── context.js (可选)
│       ├── application.js (可选)
│       └── agent.js (可选)
├── config(用于编写配置文件)
|   ├── plugin.js(用于配置需要加载的插件)
|   ├── config.default.js
│   ├── config.prod.js
|   ├── config.test.js (可选)
|   ├── config.local.js (可选)
|   └── config.unittest.js (可选)
└── test(用于单元测试)
    ├── middleware
    |   └── response_time.test.js
    └── controller
        └── home.test.js

访问

文件 app ctx service config logger helper
Controller this.app this.ctx this.service this.config this.logger this.app.helper
Service this.app this.ctx this.service this.config this.logger this.app.helper

初始化项目

mkdir egg-news
cd egg-news
npm init -y
cnpm i egg --save
cnpm i egg-bin --save-dev
  • 添加 npm scripts 到 package.json:
    “scripts”: {
    “dev”: “egg-bin dev”
    }

  • 跑通路由
    ├─app
    │ │─router.js
    │ ├─controller
    │ │ news.js
    ├─config
    │ config.default.js
    |─package.json

  • 配置路由
    // app/router.js

    module.exports = app => {
        const { router, controller } = app;
        router.get('/news', controller.news.index);
    }
    
  • 编写控制器
    //- app\controller\news.js

    const { Controller } = require('egg');
    class NewsController extends Controller {
        async index() {
            this.ctx.body = 'hello world';
        }
    }
    module.exports = NewsController;
    
  • 编写配置文件
    exports.keys = ‘zfpx’;

静态文件中间件

  • Egg 内置了 static 插件
    static 插件默认映射 /public/ -> app/public/ 目录
    把静态资源都放到 app/public 目录即可
    bootcss

  • 使用模板引擎
    ├─app
    │ │─router.js
    │ ├─controller
    │ │ news.js
    │ ├─public
    │ │ ├─css
    │ │ │ bootstrap.css
    │ │ └─js
    │ │ bootstrap.js
    │ └─view
    │ news.ejs
    ├─config
    │ config.default.js
    │ plugin.js

  • 安装依赖的插件
    cnpm install egg-view-nunjucks --save

  • 启用插件
    //- {ROOT}\config\plugin.js

    exports.nunjucks = {
        enable: true,
        package: 'egg-view-nunjucks'
    }
    
  • 配置模板

    // - {ROOT}\config\config.default.js

    module.exports=app => {
    let config={};

    config.keys=‘zfpx’;

    config.view={
    defaultExtension: ‘.html’,
    defaultViewEngine: ‘nunjucks’,
    mapping: {
    ‘.html’:‘nunjucks’
    }
    }
    return config;

}

  • 编写模板

    {{title}}
    {% for news in list%} {% endfor %}
    6.5 编写控制器 const {Controller}=require('egg'); class NewsController extends Controller{ async index() { const {ctx}=this; const list=[ { id: '45154322_0', title: '世界首富早晚是这个人,坐拥7家独角兽公司,估值破数万!', url: 'http://tech.ifeng.com/a/20180904/45154322_0.shtml', image:'http://p0.ifengimg.com/pmop/2018/0905/CFFF918B94D561D2A61FB434ADA81589E8972025_size41_w640_h479.jpeg' }, { id: '16491630_0', title: '支付宝们来了!将来人民币会消失吗?', url: 'http://finance.ifeng.com/a/20180907/16491630_0.shtml', image:'http://p0.ifengimg.com/pmop/2018/0907/2AF684C2EC49B7E3C17FCB13D6DEEF08401D4567_size27_w530_h369.jpeg' }, { id: '2451982', title: '《福布斯》专访贝索斯:无业务边界的亚马逊 令对手生畏的CEO', url: 'https://www.jiemian.com/article/2451982.html', image:'https://img1.jiemian.com/101/original/20180907/153628523948814900_a580x330.jpg' } ]; await ctx.render('index',{list}); } } module.exports=NewsController;

读取远程接口服务

在实际应用中,Controller 一般不会自己产出数据,也不会包含复杂的逻辑,复杂的过程应抽象为业务逻辑层 Service。

  • 添加配置
    // - config.default.js

    config.news={
            newsListUrl: 'https://www.easy-mock.com/mock/5b923eb2321f1076a4fc13f4/api/news',
    }
    
  • 编写Service
    // - const {Service}=require(‘egg’);
    class NewsService extends Service {
    async list(pageNum,pageSize) {
    const {ctx}=this;
    const {newsListUrl}=this.config.news;
    const result=await ctx.curl(newsListUrl,{
    method: ‘GET’,
    data: {
    pageNum,pageSize
    },
    dataType:‘json’
    });
    return result.data.data;
    }
    }
    module.exports=NewsService;

  • 编写控制层
    app/controller/news.js

    const {Controller}=require('egg');
    class NewsController extends Controller{
        async index() {
            const {ctx,service}=this;
            let {pageNum=1,pageSize=this.config.news.pageSize}=ctx.query;
            const list=await service.news.list(pageNum,pageSize);
            await ctx.render('index',{list});
        }
    }
    module.exports=NewsController;
    

扩展工具方法

  • egg最重要的5个对象
    1. app 代表整个应用对象
    2. ctx 代表上下文对象
    3. request 代表请求对象
    4. response 对象
    5. helper 工具方法
  • 框架提供了一种快速扩展的方式,只需在app/extend目录下提供扩展脚本即可
  • Helper 函数用来提供一些实用的 utility 函数。
  • 访问方式 通过 ctx.helper 访问到 helper 对象

app\extend\helper.js

const moment=require('moment');
moment.locale('zh-cn');
exports.fromNow=dateTime => moment(new Date(dateTime)).fromNow();

news.js

list.forEach(item => {
            item.createAt=ctx.helper.fromNow(item.createAt);
            return item;
});

index.html

时间: {{helper.fromNow(news.createAt)}}

中间件

app/middleware/robot.js

module.exports=(options,app) => {
    return async function(ctx,next) {
        const source=ctx.get('user-agent')||'';
        const matched=options.ua.some(ua => ua.test(source));
        if (matched) {
            ctx.status=403;
            ctx.body='你没有访问权限';
        } else {
            await next();
        }
    }
}

config.default.js

    config.middleware=[
        'robot'
    ]
    config.robot={
        ua: [
            /Chrome/
        ]
    }

运行环境

框架有两种方式指定运行环境:

  • 通过 config/env 文件指定,该文件的内容就是运行环境,如 prod。

  • 通过 EGG_SERVER_ENV 环境变量指定。

  • 框架提供了变量 app.config.env 来表示应用当前的运行环境。

  • 支持按环境变量加载不同的配置文件,如 config.local.js, config.prod.js 等等

    EGG_SERVER_ENV 说明
    local 本地开发环境
    prod 生产环境

    npm install cross-env --save-dev
    “scripts”: {
    “start”: “cross-env EGG_SERVER_ENV=local egg-bin dev”,
    “debug”: “egg-bin debug”
    }

单元测试

猜你喜欢

转载自blog.csdn.net/weixin_33768153/article/details/84798155