Huevo.js
proyecto de construccion
Egg.js nació para marcos y aplicaciones de nivel empresarial. Esperamos que Egg.js genere más marcos de trabajo de nivel superior para ayudar a los equipos de desarrollo y a los desarrolladores a reducir los costos de desarrollo y mantenimiento.
Use Scaffolding para construir la aplicación para inicializar rápidamente el proyecto
npm init egg --type=simple
npm i
En este punto la estructura del directorio es la siguiente
Escriba la capa de control en app>controller>??.js
Escriba las reglas de coincidencia de enrutamiento en app>router.js
egg-example
├── app
│ ├── controller
│ │ └── home.js
│ └── router.js
├── config
│ └── config.default.js
└── package.json
El código home.js es el siguiente
// app/controller/home.js
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
this.ctx.body = 'Hello world';
}
}
module.exports = HomeController;
El código router.js es el siguiente
// app/router.js
module.exports = (app) => {
const { router, controller } = app;
router.get('/', controller.home.index);
};
Enrutamiento y controladores
enrutador
El enrutador se usa principalmente para describir la relación correspondiente entre la URL de la solicitud y el controlador responsable de ejecutar la acción. El marco estipula que el archivo app/router.js se usa para unificar todas las reglas de enrutamiento.
redireccionamiento interno
// app/router.js
module.exports = (app) => {
app.router.get('index', '/home/index', app.controller.home.index);
app.router.redirect('/', '/home/index', 302);
};
demasiados mapas de ruta
Como se mencionó anteriormente, no recomendamos que la lógica de la regla de enrutamiento se disperse en varios lugares, lo que causará problemas para la resolución de problemas.
'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)
})
};
Configuración de estilo RESTful
Si desea definir el enrutamiento de forma REST, proporcionamos app.router.resources('routerName', 'pathMatch', controller) para generar rápidamente una estructura de enrutamiento CRUD en una ruta.
// 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
};
El código anterior implementa un conjunto de estructuras de ruta CRUD en la ruta /posts, y el controlador correspondiente es app/controller/posts.js A continuación, solo necesita implementar las funciones correspondientes en 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;
recursos estáticos
El complemento egg-static se usa internamente para completar
todos los archivos en el directorio app > public
Visite http://localhost:7002/public/index.html
para obtener información sobre el archivo app/public/index.html
enchufar
La convención de nomenclatura del plug-in egg es egg-*
Por ejemplo, el nombre del plug-in estático es egg-static
Activación del complemento
Una vez completada la instalación, el complemento no está habilitado y debe habilitarse en config/plugin.js.
Los complementos integrados se inician automáticamente.
/** @type Egg 的插件 */
module.exports = {
// 插件名称
static: {
enable: true,//是否启用
package: "egg-static",//插件包名
// path:"",//自定义插件 跟package只能出现一个
},
};
configuración de complementos
Los complementos generalmente contienen su propia configuración predeterminada y los desarrolladores de aplicaciones pueden anular la configuración correspondiente en 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,
};
};
motor de plantillas 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',
},
};
software intermedio
La forma de middleware de Egg es la misma que la de Koa, ambas basadas en el modelo de aro de cebolla. Cada vez que escribimos un middleware, es equivalente a envolver una capa fuera de la cebolla.
software intermedio
software intermedio de koa
// app/middleware/bodyparser.js
// koa-compress 暴露的接口(`(options) => middleware`)和框架对中间件要求一致
module.exports = require('koa-bodyparser');
//app/config/config.default.js
// 配置需要的中间件,数组顺序即为中间件的加载顺序
config.middleware = ['bodyparser'];
software intermedio mundial
// 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",//忽略那些路径
}
};
software intermedio de enrutamiento
software intermedio de enrutamiento
Uso de middleware para un controlador de ruta
app/router.js
resources(router, controller, app) {
const myMiddleware = app.middleware.myMiddleware({ a: 1024 });
router.resources('blogs', '/api/blogs', myMiddleware, controller.blogs);
}
Servicio
En pocas palabras, el servicio es una capa de abstracción para la encapsulación de la lógica empresarial en escenarios empresariales complejos. Proporcionar esta abstracción tiene las siguientes ventajas:
Mantener la lógica en el controlador más concisa.
Para mantener la independencia de la lógica empresarial, varios Controladores pueden llamar repetidamente al Servicio abstraído.
Atender
Definir servicio
// 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;
servicio de acceso
Los archivos de servicio se deben colocar en el directorio de aplicaciones/servicios, que puede admitir directorios de varios niveles y se pueden conectar en cascada a través de los nombres de los directorios al acceder.
ctx.service.syncUser.func(parámetros)
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;
base de datos
Base de datos MySQL
secuela de huevo
En algunas aplicaciones más complejas, es posible que necesitemos un marco ORM que nos ayude a administrar el código de la capa de datos. En la comunidad de Node.js, sequelize es un marco ORM ampliamente utilizado que admite múltiples fuentes de datos, como MySQL, PostgreSQL, SQLite y MSSQL.
Secuela marco
Instalar
npm install --save egg-secuele mysql2
Introduzca el complemento egg-sequelize en config/plugin.js
exports.sequelize = {
enable: true,
package: 'egg-sequelize',
};
Escriba la configuración de secuencia en config/config.default.js
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,
}
};
Definición del modelo y datos de simulación
Definición de modelos, sincronización de modelos, simulación de datos, establecimiento de relaciones de tablas.
simulación de datos
// 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;
};
clase de controlador
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;
clase de servicio
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;
huevo-redis
Instalar
npm i huevo-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');
}
}