eggjs 创建应用知识点

创建egg应用

安装egg
npm init egg --type=simple
进入项目
cd myegg
安装依赖
npm install
启动应用
npm run dev

安装egg-mongoose

npm install egg-mongoose --save

config 文件夹修改 config.default.js

// 配置链接mongodb路径参数
config.mongoose = {
    client: {
      url: 'mongodb://123:123@168.1.0.1/dcw',
      options: {},
    },
  };

需修改plugin.js

module.exports = {
  // had enabled by egg
  // static: {
  //   enable: true,
  // }
  // 启用mongodb
  mongoose: {
    enable: true,
    package: 'egg-mongoose',
  },
  // keys: 'dcw',
};
创建controle server modle router

controller 文件夹创建 user.js

'use strict';

// 从egg 取controller 实例
const Controller = require('egg').Controller;

class UserController extends Controller {
  async getUserList() {
    const { ctx, service } = this;
    // 获取service 业务逻辑数据
    const mockList = await service.user.find();
    ctx.body = {
      code: 1,
      msg: 'success',
      data: mockList,
    };
  }
}

module.exports = UserController;

service 文件夹创建user.js

'use strict';

const Service = require('egg').Service;

class UserService extends Service {
  async find() {
    // 从数据库模型拿取查询数据
    const mockList = await this.ctx.model.User.find({}, (d, s) => {
      // console.log(d, s);
    });
    return Object.assign({}, {
      pageNum: 1,
      pageSize: 10,
      list: mockList,
    });
  }
}

module.exports = UserService;

model 文件夹创建user.js

'use strict';

module.exports = app => {
  // 创建mongoose实例 创建Ausers 表
  const mongoose = app.mongoose;
  const Schema = mongoose.Schema;
  // 创建表字段及类型
  const UserSchema = new Schema({
    userName: { type: String },
    passWord: { type: String },
  });
  const User = mongoose.model('Ausers', UserSchema);
  
  return User;
};
本地开发

需要把 egg-bin 模块作为 devDependencies 引入

npm i egg-bin --save-dev

启动应用

添加 npm scripts 到 package.json

{
  "scripts": {
    "dev": "egg-bin dev"
  }
}

可以通过 npm run dev 命令启动应用

环境配置

本地启动的应用是以 env: local 启动的,读取的配置也是 config.default.js 和 config.local.js 合并的结果

config 配置

egg提供5种配置文件:
- config.default.js:默认配置文件;
- config.local.js:开发环境下的配置,与默认配置合并,同名则覆盖默认配置;
- config.prod.js:生产环境下的配置,与默认配置合并,同名则覆盖默认配置;
- config.test.js:测试环境下的配置,与默认配置合并,同名则覆盖默认配置;
- config.unittest.js:单元测试环境下的配置,与默认配置合并,同名则覆盖默认配置;

指定端口

本地启动应用默认监听 7001 端口,可指定其他端口,例如:

{
  "scripts": {
    "dev": "egg-bin dev --port 7002"
  }
}

router 创建知识点

router.resources(‘users’, ‘/api/users’, controller.users)好处相当于定义了一组RESTful的路由: 如下面7个路由

router.get("/api/users", controller.users.index);
router.get("/api/users/new", controller.users.new);
router.get("/api/users/:id", controller.users.show);
router.get("/api/users/:id/edit", controller.users.edit);
router.post("/api/users", controller.users.create);
router.put("/api/users/:id", controller.users.update);
router.delete("/api/users/:id", controller.users.destroy);

中间件(Middleware)洋葱模型

20180714140316832.jpeg

编写两个测试中间件middleware1和middleware2

// middleware/middleware1.js
module.exports = (options, app) => {
    return async function middleware1(ctx, next) {
        console.log("==request one==");
        await next();
        console.log("==response one==");
    }
};

// middleware/middleware2.js
module.exports = (options, app) => {
    return async function middleware2(ctx, next) {
        console.log("==request two==");
        await next();
        console.log("==response two==");
    }
};

options:中间件的参数,可在Config中配置;
app和ctx上面也说过了,有这两个对象在中间件中可以搞好多事,比如可以拿到ctx.request对参数进行修改等;
next为一个函数,下面会说作用。

写完中间件之后是需要在config.default.js中进行配置:

// config/config.default.js
exports.middleware = ['middleware1', 'middleware2']; // 数组的顺序为中间件执行的顺序
exports.middleware1 = { // 中间件参数(即options)
    msg: "extra message"
}

扩展(Extend)文件夹

image.png

框架的很多对象都是支持扩展的,我们可以在很多对象上扩展自定义的属性和方法,可扩展的对象有:Application、Context、helper、Request和Response。
编写扩展的方法就是创建对应的文件,之后会与原对象进行合并对象的prototype上,以此实现了扩展的功能,在extend文件夹下创建扩展 application.js application.prod.js 为什么application会有2个扩展文件呢?看到这个命名应该就能猜到了,实际上egg也支持按照环境扩展,所以我们可以在特定的环境下扩展需要的功能。

日志

image.png

在Controller、Service中使用日志时,可直接使用,this.logger,有none,warn,info,debug,error等方法。默认目录在项目下logs,其结构为:demo/logs/demo/…,默认以eggjs开头的日志后跟日志的生成者。日志的生成路径及大小可以在demo/app/config/config.${env}.js中进行配置,配置内容如下:

exports.logger = {
    dir:'',//配置日志生成路径
    level:'DEBUG',//日志级别
    //....其它
}

定时发布器

定时任务所在文件夹:/app/schedule

const Subscription = require('egg').Subscription;

class schedule1 extends Subscription{
    //设置定时任务信息
    static get schedule(){
        return {
            interval:'1m',//设置时间间隔
            type:'all'//所有worker都执行
        }
    }

    //要执行的内容
    async subscirbe(){
        this.logger.info(123);
    }
}

Cookie

通过 ctx.cookies,我们可以在 controller 中便捷、安全的设置和读取 Cookie

class UserController extends Controller {
  async add() {
    const ctx = this.ctx;
    let count = ctx.cookies.get('count');
    count = count ? Number(count) : 0;
    ctx.cookies.set('count', ++count);
    ctx.body = count;
  }
  async remove() {
    const ctx = this.ctx;
    ctx.cookies.set('count', null);
    ctx.status = 204;
  }
}

ctx.cookies.set(key, value, options)

设置 Cookie 其实是通过在 HTTP 响应中设置 set-cookie 头完成的,每一个 set-cookie 都会让浏览器在 Cookie 中存一个键值对。在设置 Cookie 值的同时,协议还支持许多参数来配置这个 Cookie 的传输、存储和权限

  • {Number} maxAge: 设置这个键值对在浏览器的最长保存时间。是一个从服务器当前时刻开始的毫秒数

  • {Date} expires: 设置这个键值对的失效时间,如果设置了 maxAge,expires 将会被覆盖。如果 maxAge 和 expires 都没设置,Cookie 将会在浏览器的会话失效(一般是关闭浏览器时)的时候失效

  • {String} path: 设置键值对生效的 URL 路径,默认设置在根路径上(/),也就是当前域名下的所有 URL 都可以访问这个 Cookie

  • {String} domain: 设置键值对生效的域名,默认没有配置,可以配置成只在指定域名才能访问

  • {Boolean} httpOnly: 设置键值对是否可以被 js 访问,默认为 true,不允许被 js 访问

  • {Boolean} secure: 设置键值对只在 HTTPS 连接上传输,框架会帮我们判断当前是否在 HTTPS 连接上自动设置 secure 的值

  • {Boolean} overwrite:设置 key 相同的键值对如何处理,如果设置为 true,则后设置的值会覆盖前面设置的,否则将会发送两个 set-cookie 响应头

  • {Boolean} signed:设置是否对 Cookie 进行签名,如果设置为 true,则设置键值对的时候会同时对这个键值对的值进行签名,后面取的时候做校验,可以防止前端对这个值进行篡改。默认为 true

  • {Boolean} encrypt:设置是否对 Cookie 进行加密,如果设置为 true,则在发送 Cookie 前会对这个键值对的值进行加密,客户端无法读取到 Cookie 的明文值。默认为 false

// 设置样例
ctx.cookies.set(key, value, {
  httpOnly: false,
  signed: false,
});

// 获取样例

ctx.cookies.get(key, options)

Cookie 秘钥

由于我们在 Cookie 中需要用到加解密和验签,所以需要配置一个秘钥供加密使用。在 config/config.default.js 中

module.exports = {
  keys: 'key1,key2',
};

keys 配置成一个字符串,可以按照逗号分隔配置多个 key。Cookie 在使用这个配置进行加解密时:

  • 加密和加签时只会使用第一个秘钥。

  • 解密和验签时会遍历 keys 进行解密。

如果我们想要更新 Cookie 的秘钥,但是又不希望之前设置到用户浏览器上的 Cookie 失效,可以将新的秘钥配置到 keys 最前面,等过一段时间之后再删去不需要的秘钥即可。

Session

框架内置了 Session 插件,给我们提供了 ctx.session 来访问或者修改当前用户 Session

class UserController extends Controller {
  async getPosts() {
    const ctx = this.ctx;
    // 获取 Session 上的内容
    const userId = ctx.session.userId;
    const posts = await ctx.service.post.fetch(userId);
    // 修改 Session 的值
    ctx.session.visited = ctx.session.visited ? (ctx.session.visited + 1) : 1;
    ctx.body = {
      success: true,
      posts,
    };
  }
}

修改session, 如果要删除它,直接将它赋值为 null

// 设置
ctx.session.user ='xiaodoubao'
// 删除
ctx.session = null;

设置session 注意事项

  • 不要以 _ 开头

  • 不能为 isNew

// ❌ 错误的用法
ctx.session._visited = 1;   //    --> 该字段会在下一次请求时丢失
ctx.session.isNew = 'HeHe'; //    --> 为内部关键字, 不应该去更改

更多内容请到小豆包》

扫码关注小豆包公众号

小豆包公众号.jpg

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值