egg js 搭建项目,教程

Egg.js

搭建工程

Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本。

官网

  • 使用脚手架搭建应用程序 快速初始化项目

npm init egg --type=simple
npm i
  • 此时目录结构如下

在app>controller>??.js中书写控制层
在app>router.js中书写路由匹配规则
egg-example
├── app
│   ├── controller
│   │   └── home.js
│   └── router.js
├── config
│   └── config.default.js
└── package.json
  • home.js代码如下

// app/controller/home.js
const Controller = require('egg').Controller;
class HomeController extends Controller {
  async index() {
    this.ctx.body = 'Hello world';
  }
}
module.exports = HomeController;
  • router.js代码如下

// app/router.js
module.exports = (app) => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
};

路由和控制器

路由(Router)

Router 主要用来描述请求 URL 和具体承担执行动作的 Controller 的对应关系, 框架约定了 app/router.js 文件用于统一所有路由规则。

内部重定向

// app/router.js
module.exports = (app) => {
  app.router.get('index', '/home/index', app.controller.home.index);
  app.router.redirect('/', '/home/index', 302);
};

太多路由映射

如上所述,我们并不建议把路由规则逻辑散落在多个地方,会给排查问题带来困扰。
'use strict';
const routers = {
  home(router, controller) {
    return router.get('/home', controller.home.index);
  },
}
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  // 路由配置
  Object.values(routers).forEach((item) => {
    item(router, controller)
  })
};

RESTful风格配置

RESTful

如果想通过 RESTful 的方式来定义路由, 我们提供了 app.router.resources('routerName', 'pathMatch', controller) 快速在一个路径上生成 CRUD 路由结构。
// app/router.js
module.exports = (app) => {
  const { router, controller } = app;
  router.resources('posts', '/api/posts', controller.posts);
  router.resources('users', '/api/v1/users', controller.v1.users); // app/controller/v1/users.js
};
上面代码就在 /posts 路径上部署了一组 CRUD 路径结构,对应的 Controller 为 app/controller/posts.js 接下来, 你只需要在 posts.js 里面实现对应的函数就可以了。
// app/controller/posts.js
const { Controller } = require('egg');
class Posts extends Controller {
    index() {
        this.ctx.body = '获取列表';
    };
    new() {
        this.ctx.body = '新增表单';
    };
    show() {
        this.ctx.body = '博客详情';
    };
    edit() {
        this.ctx.body = '编辑页面';
    };
    create() {
        this.ctx.body = '新增博客';
    };
    update() {
        this.ctx.body = '修改博客';
    };
    destroy() {
        this.ctx.body = '删除博客';
    };
}
module.exports = Posts;

静态资源

内部使用egg-static插件完成
app > public 目录下的所有文件
访问 http://localhost:7002/public/index.html
可以获取app/public/index.html文件信息

插件

插件

egg的插件命名规范为 egg-*
比如static插件名称为egg-static

插件的启用

安装完成后,并没有启用插件,需要在config/plugin.js中启用插件。
内置插件是会自动启动。
/** @type Egg 的插件 */
module.exports = {
  // 插件名称
  static: {
    enable: true,//是否启用
    package: "egg-static",//插件包名
    // path:"",//自定义插件 跟package只能出现一个
  },
};

插件配置

插件一般会包含自己的默认配置,应用开发者可以在 config.default.js 覆盖对应的配置:
// config/config.default.js
module.exports = appInfo => {
  const config = exports = {};
  // cookie签名
  config.keys = appInfo.name + '_1678169356863_9169';
  // 添加用户配置
  const userConfig = {
    // myAppName: 'egg',
  };
    // 配置static插件
  exports.static = {
    prefix: '/',
  };
  return {
    ...config,
    ...userConfig,
  };
};

egg-view-ejs 模板引擎

// {app_root}/config/plugin.js
exports.ejs = {
  enable: true,
  package: 'egg-view-ejs',
};

// {app_root}/config/config.default.js
exports.view = {
  mapping: {
    '.ejs': 'ejs',
  },
};

中间件

Egg 的中间件形式和 Koa 的中间件形式是一样的,都是基于洋葱圈模型。每次我们编写一个中间件,就相当于在洋葱外面包了一层。
中间件

koa中间件

// app/middleware/bodyparser.js
// koa-compress 暴露的接口(`(options) => middleware`)和框架对中间件要求一致
module.exports = require('koa-bodyparser');

//app/config/config.default.js
// 配置需要的中间件,数组顺序即为中间件的加载顺序
config.middleware = ['bodyparser'];     

全局中间件

// app/middleware/myMiddleware.js
//一个中间件
module.exports = (options) => {
  return async function myMiddleware(ctx, next) {
    await next();
  };
};   
//配置config.default.js
module.exports = {
  // 配置需要的中间件,数组顺序即为中间件的加载顺序
  middleware: ['myMiddleware'],
  // 配置 myMiddleware中间件的配置
  myMiddleware: {
      enable:boolean,//是否启用中间件
      match:"/login",//匹配为true才运行中间件
      ignore:"/api",//忽略那些路径
  }
};

路由中间件

路由中间件

正对某个路由控制器使用中间件
app/router.js
resources(router, controller, app) {
    const myMiddleware = app.middleware.myMiddleware({ a: 1024 });
    router.resources('blogs', '/api/blogs', myMiddleware, controller.blogs);
}

服务(Service)

简单来说,Service 就是在复杂业务场景下用于做业务逻辑封装的一个抽象层,提供这个抽象有以下几个好处:
保持 Controller 中的逻辑更加简洁。
保持业务逻辑的独立性,抽象出来的 Service 可以被多个 Controller 重复调用。
服务

定义 Service

// app/service/user.js
const Service = require('egg').Service;
class UserService extends Service {
  async find(uid) {
    const user = await this.ctx.db.query(
      'select * from user where uid = ?',
      uid,
    );
    return user;
  }
}
module.exports = UserService;

访问service

Service 文件必须放在 app/service 目录,可以支持多级目录,访问的时候可以通过目录名级联访问。
ctx.service.syncUser.func(params)
app/service/biz/user.js => ctx.service.biz.user
app/service/sync_user.js => ctx.service.syncUser
// app/controller/user.js 控制层访问
const Controller = require('egg').Controller;
class UserController extends Controller {
  async info() {
    const { ctx } = this;
    const userId = ctx.params.id;
    const userInfo = await ctx.service.syncUser.find(userId);
    ctx.body = userInfo;
  }
}
module.exports = UserController;

数据库

MySql数据库

egg-sequelize

在一些较为复杂的应用中,我们可能会需要一个 ORM 框架来帮助我们管理数据层的代码。而在 Node.js 社区中,sequelize 是一个广泛使用的 ORM 框架,它支持 MySQL、PostgreSQL、SQLite 和 MSSQL 等多个数据源。
Sequelize框架
  • 安装

npm install --save egg-sequelize mysql2

  • 在 config/plugin.js 中引入 egg-sequelize 插件 使用

exports.sequelize = {
  enable: true,
  package: 'egg-sequelize',
};
  • 在 config/config.default.js 中编写 sequelize 配置

  exports.sequelize = {
    logging: false,
    dialect: 'mysql',
    host: '127.0.0.1',
    port: 3306,
    database: 'myegg',
    username: "root",
    password: "5201314025ma",
    define: {
      timestamps: false, // 关键配置,默认为 true, 修改为 false 即可
      freezeTableName: false,
    }
  };

模型定义和模拟数据

模型定义,模型同步,模拟数据,建立表关系。

数据模拟

// app/model/user 模型

// const Mock = require("mockjs")
// const resultStu = Mock.mock({
//     "datas|200-300": [
//         {
//             "id|+1": 1,
//             name: "@cname",
//             loginId: "@id",
//             loginPwd: /\w{10}/,
//             created_at: "@date",
//             updated_at: "@date",
//             "auth|1": ['user', 'admin'],

//         }
//     ]
// }).datas;

module.exports = (app) => {
    const { STRING, INTEGER, DATE } = app.Sequelize;
    const User = app.model.define('user', {
        id: { type: INTEGER, primaryKey: true, autoIncrement: true },
        name: STRING(20),
        loginId: { type: STRING(20), allowNull: false },
        loginPwd: { type: STRING, allowNull: false },
        created_at: DATE,
        updated_at: DATE,
        auth: STRING(20),
    });

    User.associate = function () {
        app.model.sync({ alter: true }).then(() => {
            console.log(19, '所有同步完成');
        })
        app.model.Class.hasMany(app.model.Student);
        app.model.Student.belongsTo(app.model.Class);
        console.log(22, '关联表');
        // app.model.Student.bulkCreate(resultStu);
    };
    return User;
};

controller class

app/controller/class.js
//查询
const { Controller } = require('egg');
class Class extends Controller {
    async index() {
        const ctx = this.ctx;
        const query = ctx.query
        //调用service
        ctx.body = await ctx.service.class.find(query);
    }
}
module.exports = Class;

service class

app/service/class
const Service = require('egg').Service;
class UserService extends Service {
    async find(query) {
        const { page, limit } = query;
        const result = await this.ctx.model.Class.findAndCountAll({
            offset: (+page - 1) * +limit,
            limit: +limit,
            include: [this.ctx.model.Student],
        })
        return (result);
    }
}
module.exports = UserService;

egg-redis

redis

  • 安装

npm i egg-redis --save

//config/plugin.js
exports.redis = {
    enable: true,
    package: 'egg-redis',
}

//config.default.js
config.redis = {
    client: {
      port: 6379,          // Redis port
      host: '127.0.0.1',   // Redis host
      password: 'auth',    //必填
      db: 0,
    },
}
app/controller/user.js
const { Controller } = require('egg');
class Posts extends Controller {
  async index() {
    await this.app.redis.set('foo', 'bar11111111111');
    // get
    this.ctx.body = await this.app.redis.get('foo');
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_55508765/article/details/129413344