babel-plugin-with-middleware
v0.1.3
Published
该插件通过在函数上方添加特定注释的方式为函数添加类似于 koa 中间件的功能 (其实就是内置了[email protected])
Downloads
6
Readme
该插件通过在函数上方添加特定注释的方式为函数添加类似于 koa 中间件的功能 (其实就是内置了[email protected])
配置方法
安装插件
yarn add -D @babel/[email protected] babel-plugin-with-middleware
npm install @babel/[email protected] babel-plugin-with-middleware --save-dev
配置 babel
在 babel 配置文件的 plugins 中添加插件的名称
以.babelrc 为例
{
"plugins": ["babel-plugin-with-middleware"]
}
一个例子
const timing = async(ctx, next) => {
let cost = Date.now()
const rst = await next()
cost = Date.now() - cost
ctx.cost = cost
return rst
}
const label = functionName => (ctx, next) => {
ctx.label = functionName
return next()
}
const print = async (ctx, next) => {
const rst = await next()
console.log(`${ctx.label || ""} 耗时:${ctx.cost}ms`)
console.log(`入参:${JSON.stringify(ctx.params)}`)
console.log(`返回值:${JSON.stringify(rst)}`)
return rst
}
// with-middleware label('登录')
// with-middleware print
// with-middleware timing
const login = async (username, password) => {
const succ = db.user.count({username, password})
return succ ? '登录成功' : '登录失败'
}
login('tony','ohyeah')
/**
* 登录 耗时:23ms
* 入参:["tony","ohyeah"]
* 返回值:"登录成功"
* /
上面这个例子中的代码经插件处理后内容如下
function __mdw__compose(middleware) {
if (!Array.isArray(middleware))
throw new TypeError("Middleware stack must be an array!")
for (const fn of middleware) {
if (typeof fn !== "function")
throw new TypeError("Middleware must be composed of functions!")
}
return function (context, next) {
let index = -1
return dispatch(0)
function dispatch(i) {
if (i <= index)
return Promise.reject(new Error("next() called multiple times"))
index = i
let fn = middleware[i]
if (i === middleware.length) fn = next
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)))
} catch (err) {
return Promise.reject(err)
}
}
}
}
function __mdw__ctxToParams(fn) {
const _this = this
return function (ctx) {
return fn.apply(_this, ctx.params)
}
}
function __mdw__packing(middlewares) {
const _this = this
const composed = __mdw__compose(middlewares)
return function (...args) {
return composed.call(_this, {
params: args,
})
}
}
const timing = async (ctx, next) => {
let cost = Date.now()
const rst = await next()
cost = Date.now() - cost
ctx.cost = cost
return rst
}
const label = (functionName) => (ctx, next) => {
ctx.label = functionName
return next()
}
const print = async (ctx, next) => {
const rst = await next()
console.log(`${ctx.label || ""} 耗时:${ctx.cost}ms`)
console.log(`入参:${JSON.stringify(ctx.params)}`)
console.log(`返回值:${JSON.stringify(rst)}`)
return rst
} // with-middleware label('登录')
// with-middleware print
// with-middleware timing
const login = __mdw__packing([
label("登录"),
print,
timing,
__mdw__ctxToParams(async (username, password) => {
const succ = db.user.count({
username,
password,
})
return succ ? "登录成功" : "登录失败"
}),
])
login("tony", "ohyeah")
下面这些情况可以适用
// with-middleware test
const hello = async () => {}
// with-middleware test
async function hello() {}
// with-middleware test
Greeting.hello = async () => {}
call(
// with-middleware test
async function () {}
)
{
// with-middleware test
hello: () => {}
}
class Greeting {
// with-middleware test
hello() {}
// with-middleware test
hello = () => {}
}
// with-middleware test
export const hello = () => {}
// with-middleware test
export const hello = function () {}
// with-middleware test
export default () => {}
依赖
- @babel/core 7.+
注意
- 由于经插件处理后的函数总是返回 Promise,所以不应被用于同步函数。
- 目前仅支持通过单行注释的形式对函数进行包装。
- 未在 Typescript 环境下测试。
- 由于是通过注释的形式调用的中间件,所以在打包工具开启了 tree-shaking 时,需要针对性的配置;如 webpack 需要配置 sideEffects(暂未经测试)
- 不支持生成器函数