最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 使用 egg.js 定制业务 web 框架

    正文概述 掘金(ICBU互动及端技术团队)   2021-02-08   721

    作者:ICBU 谦行

    前面章节介绍了如何使用 egg.js 完成业务开发、定制插件,这些是把 egg.js 当做一个 web 框架使用,本章节介绍下 egg.js 做为框架的框架为业务定制一个 web 框架的能力

    设计目标

    可以把前面章节实现的基础功能做为 demo 框架的默认功能,封装完成后提供给团队使用

    1. 自带 handlebars 模板渲染能力
    2. 所有请求自动统计耗时
    3. enum、util 挂载到 this.app

    配置框架

    初始化代码

    使用 egg.js 提供的 framework 脚手架初始化框架代码

    $ mkdir framework-demo && cd framework-demo
    $ npm init egg --type=framework
    

    目录结构应该很熟悉了,多出来的lib/framework.js 是框架的入口

    framework-demo
    ├── app
    │   ├── extend
    │   └── service
    ├── config
    │   ├── config.default.js
    │   └── plugin.js
    ├── lib
    │   └── framework.js
    ├── test
    ├── README.md
    ├── index.js
    └── package.json
    

    handlebars 模板引擎支持

    egg.js 使用的章节介绍过 如何配置模板引擎,定制框架的时候步骤一样

    安装 egg-view-handlebars

    $ npm i egg-view-handlebars --save
    

    启用插件

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

    配置 view 渲染项

    // config/config.default.js
    config.view = {
      defaultViewEngine: 'handlebars',
      defaultExtension: '.hbs',
      mapping: {
        '.hbs': 'handlebars',
      },
    };
    

    这样使用该框架就默认具备了 handlebars 渲染能力

    内置请求耗时中间件

    中间件的编写规则和在 egg.js 中直接使用一致,不过添加到框架的方式有所不同

    添加 cost 中间件

    // app/middleware/cost.js
    module.exports = options => {
      const header = options.header || 'X-Response-Time';
    
      return async function cost(ctx, next) {
        const now = Date.now();
        await next();
        ctx.set(header, `${Date.now() - now}ms`);
      };
    };
    

    应用中间件

    框架和插间添加中间件和直接在应用中使用不同,不支持修改 config 文件,需要在项目根目录下的 app.js 修改

    // app.js
    module.exports = app => {
      // 在中间件最前面统计请求时间
      app.config.coreMiddleware.unshift('cost');
    };
    

    enum、util 挂载

    在框架中有很多业务的字段枚举或者通用的工具类,一般是定义了文件夹统一管理,开发使用的时候手工 require,使用 egg.js 后可以把约定内置框架,在指定目录编写后自动加载到框架

    文件添加

    添加文件 app/enum/error.jsapp/util/dto.js

    framework-demo
    ├── app
    │   ├── extend
    │   ├── service
    │   ├── enum
    │   │       └── error.js
    │   └── util
    │   │       └── dto.js
    └── package.json
    
    // app/enum/error.js
    'use strict';
    
    exports.ERR_AUTH = {
      code: '403',
      msg: 'not perm',
    };
    
    exports.ERR_NOTFOUND = {
      code: '404',
      msg: 'not found',
    };
    
    exports.ERR_SERVER = {
      code: '500',
      msg: 'internal server error',
    };
    
    // app/util/dto.js
    'use strict';
    
    const assert = require('assert');
    
    function isObject(obj) {
      const objType = Object.prototype.toString.call(obj);
      return objType === '[object Object]' || objType === '[object Array]' || objType === '[object Null]';
    }
    
    class ResultDto {
      constructor(result, code = 200, errorMsg = '', errorStack = null) {
        assert(isObject(result), '[ResultDto:constructor]: arg[0] must be an object or null!');
    
        this.result = result;
        this.success = code === 200;
        this.code = code;
        if (code !== 200) {
          this.errorMsg = errorMsg;
          this.errorStack = errorStack;
        }
      }
    }
    
    exports.ResultDto = ResultDto;
    

    配置 loader

    在配置文件中为文件夹声明路径和注入的对象,更多细节参考 EggJS 加载器

    // config/config.default.js
    config.customLoader = {
      enum: {
        directory: 'app/enum',
        inject: 'app',
        loadunit: true,
      },
      util: {
        directory: 'app/util',
        inject: 'app',
        loadunit: true,
      },
    };
    

    自动提示

    由于 Egg 是动态挂载的,如需 TS 和智能提示支持,需要通过 egg-ts-helper 来自动生成映射

    首先修改 package.json 文件声明

    // package.json
    {
      "name": "framework-demo",
      "egg": {
        "declaration": true,
        "tsHelper": {
          "watchDirs": {
            "enum": {
              "enabled": true,
              "directory": "app/enum",
              "declareTo": "Application.enum"
            },
            "util": {
              "enabled": true,
              "directory": "app/util",
              "declareTo": "Application.util"
            }
          }
        }
      }
    }
    

    egg-bin 内置支持了自动生成 typings 文件夹,但框架开发通常不会使用 egg-bin dev 为了方便框架开发可以在 scripts 配置生成 typeings 的命令

    "scripts": {
      "typing": "npx ets"
    },
    

    使用

    使用 egg.js 定制业务 web 框架

    测试 & 发布

    这样就完成了框架定制,框架因为涉及多人使用,需要有完善的测试保证可用性,egg.js 提供了完备的测试支持,测试工作完成后可以进入发布流程

    1. 根据语义化版本号规则使用合适的版本
    2. 发布 beta 版本 npm publish --tag=beta
    3. 测试 OK 后发布正式版本 npm publish

    使用框架

    在 egg.js 应用中使用框架很简单,把 egg 脚手架生成的应用 package.json 稍作修改即可

    {
      "name": "egg-demo",
      "version": "1.0.0",
      "egg": {
        "declarations": true,
        "framework": "egg-framework-demo"
      },
      "dependencies": {
        "egg-framework-demo": "^1",
        "egg-scripts": "^2.11.0"
      }
    }
    

    package.json 声明框架后 npm run dev 可以看到已经使用 egg-demo-framework 启动框架了,cost 中间件也正常工作

    INFO 76333 [master] egg-framework-demo started on http://127.0.0.1:7001 (1901ms)
    

    使用 egg.js 定制业务 web 框架

    完整代码:github.com/Samaritan89…

    参考

    1. 如何为团队量身定制 EggJS 目录挂载规范
    2. 基于 EggJS 为团队定制自己的 Node.js 框架

    起源地下载网 » 使用 egg.js 定制业务 web 框架

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元