背景
前不久把项目中用了很久的一个伪中间件撸成了一个 npm 包发布了出去.
为什么叫伪中间件? 正常的中间件的引用方式, 就拿 body-parser 为例.
- var Koa = require('koa');
- var bodyParser = require('koa-bodyparser');
- var app = new Koa();
- app.use(bodyParser());
- app.use(async ctx => {
- // the parsed body will store in ctx.request.body
- // if nothing was parsed, body will be an empty object {}
- ctx.body = ctx.request.body;
- });
反观我撸的伪中间件的引用方式.
- const response = require('../uitls/Response');
- const data = {};
- response.success(ctx, data);
为什么要这么干呢... 纯粹是因为这个伪中间件与现有项目的耦合度太高了,
为 (就) 了(是)方 (懒) 便在项目里面把这个伪中间件的引用方式从本地工具组件换成从 node_modules 里引用.
例如这样.
- const response = require('koa2-response');
- const data = {};
- response.success(ctx, data);
经过一番折腾, 项目中的引用方式全部替换完了. 然后我的学弟就看不下去了... 提了一个 pullrequest 给我. 把这个着实封装成了一个中间件
优化
首先是改变了引用方式, 之前的方式是直接导出了一个对象, 这个对象有两个方法, 分别是 success 和 error. 使用这种方式, 就必须要在每个 controller 中都引用一次, 如下.
const response = require('../utils/Response');
优化之后, 只需要在 node 的入口文件中做如下操作就好
- const koa = require('koa');
- const app = new koa();
- const router = require('koa-router')();
- const response = require('koa2-response');
- const code = {
- UNKNOWN_ERROR: [1, 'Sorry, you seem to have encountered some unknown errors.']
- }
- router
- .get('/', (ctx, next) => {
- ctx.success({
- name: 'test'
- })
- })
- .get('/error_test', (ctx, next) => {
- ctx.error(code.UNKNOWN_ERROR);
- })
- app.use(router.routes());
- app.use(router.allowedMethods());
- app.listen(3000);
- console.log(`Server is running on port 3000`);
对比两种方式可能有有些疑问, 第一种方式, 需要传入 ctx, 而改良之后的方式没有了 ctx. 那是因为在中间件中做了如下处理.
- const { success, error } = require('./util');
- module.exports = async (ctx, next) => {
- ctx.success = success.bind(null, ctx);
- ctx.error = error.bind(null, ctx);
- await next();
- }
这样一来, koa 的上下文 ctx 就会被当作 ctx.success 的默认第一个参数. 针对不同模块的 controller, 不需要再去单独引用一次依赖包, 可以直接通过 ctx 对中间件进行调用. 相对于最初的版本, 这样大大的提高了开发的效率.
写在后面
对于这个, 还是有些顾虑. 如果 koa 之后更新的时候, 也出现了 success 和 error 的方法, 再引入这个包, 就会覆盖掉 koa 方法.
来源: https://www.cnblogs.com/detectiveHLH/p/9356361.html