课程名称:web前端架构师
课程章节:第14周 第八章 添加 Mongoose 以及 egg.js 插件原理
主讲老师:张轩
课程内容: 将mongoose models 自动加在到 egg app 上
昨天最后实现了加载器,将mongoose models 挂载到了 App 上,那么现在通过代码来使用下
首先编写测试代码,创建一个 service
import { Service } from 'egg'; export default class UserController extends Service { public async getUser() { return this.app.model.User.find().limit(10); } }
上面代码就是我们想要的结果,通过 app.model 访问到 models下的 model
下面编写一个 UserModel
import { Application } from 'egg'; import { Schema } from 'mongoose'; const ObjectId = Schema.Types.ObjectId; const UserSchema = new Schema({ username: String, password: { type: String, select: false, }, hobbies: [ String ], date: Date, createAt: Date, age: Number, team: { type: ObjectId, ref: 'team', }, }, { collection: 'users', }); function UserModel(app: Application) { return app.mongoose.model('user', UserSchema); } export default UserModel;
此时我们还需要在 typings 生命app 下的 model, 因为我们在 service 下访问 app.model, ts 无法识别就会报错
import 'egg'; import { Model, type Connection } from 'mongoose' declare module 'egg' { type mongooseModels = { [k: string]: Model<any> } interface Application { model: mongooseModels mongoose: Connection } }
然后就可以运行代码就像测试了,就可以得到我们实现的结果
相关文档参考 https://www.eggjs.org/zh-CN/advanced/loader#加载器函数loader-api
之前我们完成了 mongose 的绑定到 app 对象上,如果我们有其他项目也想要这个功能,我们可能就需要进行拷贝,这样做肯定不是很好
这时,我们就需要了解 egg.js 到插件的开发 . 参考文档 https://www.eggjs.org/zh-CN/advanced/plugin
初始化插件项目
mkdir egg-hello && cd egg-hello npm init egg --type=plugin npm i npm test
一个插件其实就是一个『迷你的应用』,下面展示的是一个插件的目录结构,和应用(app)几乎一样。
{String} name
- 插件名(必须配置),具有唯一性,配置依赖关系时会指定依赖插件的 name。{Array} dependencies
- 当前插件强依赖的插件列表(如果依赖的插件没找到,应用启动失败)。{Array} optionalDependencies
- 当前插件的可选依赖插件列表(如果依赖的插件未开启,只会 warning,不会影响应用启动)。{Array} env
- 只有在指定运行环境才能开启,具体有哪些环境可以参考运行环境。此配置是可选的,一般情况下都不需要配置。"name": "egg-hismongoose", "eggPlugin": { "name": "hismongoose", "dependencies": ["registry"], "optionalDependencies": ["vip"], "env": ["local", "test", "unittest", "prod"] } }
在插件项目根目录下新建文件 app.js, 然后把我们之前编写的 app.ts 拿过来,改造成 nodejs 代码
const mongoose = require('mongoose'); const path = require('path'); const { createConnection } = mongoose class AppBook { constructor(app) { this.app = app; const { url } = this.app.config.mongoose; const db = createConnection(url); db.on('connected', () => { console.log('connected success'); }); this.app.mongoose = db; } configWillLoad() { const dir = path.join(this.app.config.baseDir, 'app/model'); this.app.loader.loadToApp(dir, 'model', { caseStyle: 'Upper', }); } async willReady(){ console.log(this.app.config.coreMiddleware); } } module.exports = AppBook
新建 index.d.ts 文件。用于声明类型。把我们之前声明的类型文件拿过来就可以了
同时还需要增加一个 config 提示,这样在我们的项目中config 文件中使用时就会有mongoose 提示
import 'egg'; import { Model, type Connection } from 'mongoose' declare module 'egg' { type mongooseModels = { [k: string]: Model<any> } interface Application { model: mongooseModels mongoose: Connection } interface EggAppConfig{ mongoose: { url?: string } } }
然后发布 npm 包就可以了.
然后安装我们发布的 npm 包,这里我发布的是 egg-hismongoose
npm i egg-hismongoose
把我们之前在 app.ts 文件中写的monoose代码删除掉,然后在config.default.js文件中配置mongoose
import { EggAppConfig, EggAppInfo, PowerPartial } from 'egg'; export default (appInfo: EggAppInfo) => { const config = {} as PowerPartial<EggAppConfig>; // 这里编写就会有mongoose提示 config.mongoose = { url: 'mongodb://user:password@localhost:27017', }; // add your special config in here const bizConfig = { sourceUrl: `https://github.com/eggjs/examples/tree/master/${appInfo.name}`, myLogger: { allowedMethod: [ 'POST' ], }, // mongoose: { // url: 'mongodb://user:password@localhost:27017', // }, }; // the return config will combines to EggAppConfig return { ...config as {}, ...bizConfig, }; };
这样我们编写的 mongoose 插件就可以在egg.js 项目中运行了