Author: ICBU Qian Hang

Write at the front: welcome to Alibaba ICBU interactive & end technology front end team column, we will share quality front end technology articles with you, welcome to pay attention to & exchange yo!

While Web frameworks that do too little can lead to poor usability and too much can lead to customization, Egg is a framework for frameworks, helping the technical lead on the team customize the upper-level business framework for a particular business scenario. The name egg.js means exactly that, spawning a Web framework like an egg

The previous section described how to use egg.js for business development and custom plug-ins. These are used as a Web framework. This section describes the ability of using egg.js as a framework to customize a web framework for business

Design goals

The basic functions implemented in the previous section can be used as the default functions of the Demo framework and provided to the team after encapsulation

  1. Comes with Handlebars template rendering capabilities
  2. The time required for all requests is automatically counted
  3. Enum, util Mounts tothis.app

Configuration framework

Initialization code

Initialize the framework code using the framework scaffolding provided by egg.js

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

The directory structure should be familiar, the extra lib/framework.js is the entry point to the framework

Framework - demo ├ ─ ─ app │ ├ ─ ─ the extend │ └ ─ ─ service ├ ─ ─ the config │ ├ ─ ─ config. The default. The js │ └ ─ ─ plugin. Js ├ ─ ─ lib │ └ ─ ─ ├─ download.txt ├─ download.txt ├─ download.txt ├─ download.txtCopy the code

Handlebars template engine support

The section used in egg.js explains how to configure the template engine

To install an egg – view – the handlebars

$ npm i egg-view-handlebars --save
Copy the code

To enable the plugin

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

Configure the View render TAB

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

This gives handlebars rendering capability by default when using the framework

Built-in request time consuming middleware

Middleware is written with the same rules as it is used directly in egg.js, but is added to the framework differently

Add Cost Middleware

// 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`);
  };
};
Copy the code

Application middleware

The config file cannot be modified. You need to modify it in app.js under the root directory of the project

/ / app. Js module. Exports = app = > {/ / in the front middleware statistical request time app. Config. CoreMiddleware. Unshift (' cost '); };Copy the code

Enum, util Mounting

In the framework, there are a lot of business field enumeration or general tool classes, generally defined unified folder management, manual require during development and use, using egg.js can be the convention built-in framework, after the specified directory is written automatically loaded into the framework

File to add

Add files app/enum/error.js and app/util/ to.js

Framework - demo ├ ─ ─ app │ ├ ─ ─ the extend │ ├ ─ ─ service │ ├ ─ ─ enum │ │ └ ─ ─ the error. The js │ └ ─ ─ util │ │ └ ─ ─ dto. Js └ ─ ─ package. The 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;Copy the code

Configure the loader

Declare the path and injected objects for the folder in the configuration file. Refer to the EggJS loader for more details

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

Automatic prompt

Since eggs are dynamically mounted, they need to be automatically mapped through egg-TS-Helper if TS and smart hint support is required

First modify the package.json file declaration

// 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"
        }
      }
    }
  }
}
Copy the code

Egg-bin provides built-in support for automatically generating typings folders, but framework developers usually don’t use egg-bin dev to configure commands to generate Typeings in scripts for framework development

"scripts": {
  "typing": "npx ets"
},
Copy the code

use

Testing & Release

In this way, the framework customization is completed. Since the framework involves multiple users, it needs perfect testing to ensure its usability. Egg.js provides complete testing support, and after the testing is completed, the release process can be entered

  1. Use the appropriate version according to the semantic version number rules
  2. Beta releasenpm publish --tag=beta
  3. Release the official version after testing OKnpm publish

Using a framework

Using a framework in an egg.js application is simple, with minor modifications to the egg scaffolding generated application package.json

{" name ":" an egg - demo ", "version" : "1.0.0", "egg" : {" declarations ": true," framework ": "Egg - framework - demo"}, "dependencies" : {" egg - framework - demo ":" ^ 1 ", "an egg - scripts" : "^ 2.11.0"}}Copy the code

After package.json declares the framework, NPM run Dev can see that the framework has been started using egg-Demo-Framework and cost middleware is working properly

INFO 76333 [master] egg- Framework -demo started on http://127.0.0.1:7001 (1901ms)Copy the code

Full code: github.com/Samaritan89…

reference

  1. How to customize the EggJS directory mount specification for your team

  2. Customize your own Node.js framework for the team based on EggJS

❤️ Thank you for seeing the end ~

Alibaba international website (ICBU, Alibaba.com) is the world’s largest cross-border trade and service platform. We have new technical challenges all the time, enough interesting challenges to satisfy all your curiosity and thirst for knowledge, and well-known foreign partners (Google & OpenSky).

If you want to come to ICBU to develop the front end with me, please send your resume to [email protected] and we will respond to your interview arrangement quickly. : -)