手记

【金秋打卡】第9天 Egg.js 结合 Mongoose (二)

课程名称:web前端架构师

课程章节:第14周 第八章 添加 Mongoose 以及 egg.js 插件原理

主讲老师:张轩

课程内容: 将mongoose models 自动加在到 egg app 上

将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
  }
}

然后就可以运行代码就像测试了,就可以得到我们实现的结果

将逻辑抽象为 egg.js 插件

之前我们完成了 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)几乎一样。

插件和应用的区别

插件没有独立的 router 和 controller

插件需要在 package.json 中的 eggPlugin 节点指定插件特有的信息

  • {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"]
  }
}

插件没有 plugin.js

插件规范

  • 命名规范
    • npm 包名以 egg- 开头,且为全小写,例如:egg-xx。比较长的词组用中划线:egg-foo-bar
    • 对应的插件名使用小驼峰,小驼峰转换规则以 npm 包名的中划线为准 egg-foo-bar => fooBar
    • 对于可以中划线也可以不用的情况,不做强制约定,例如:userservice(egg-userservice) 还是 user-service(egg-user-service) 都可以
  • package.json 书写规范
    • 按照上面的说明添加 eggPlugin 节点
    • 在 keywords 里加上 egg、egg-plugin、eggPlugin 等关键字,便于索引

编写发布 egg mongoose 插件

在插件项目根目录下新建文件 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 项目中运行了

0人推荐
随时随地看视频
慕课网APP