> 因项目需要使用koa模拟服务器返回接口,研究下koa加载过程
1、nodejs下的require, 一切node模块的加载都是从node_modules开始的,打开koa模块package.json ,仅关注入口main属性对应的启动项,和dependencies 属性的依赖项,npm模块的依赖会检查如果dependencies下对应的文件是否存在,如果不存在则加载,参考朴灵深入浅出nodejs
{
"main": "lib/application.js",
"dependencies": {
"accepts": "^1.3.5",
"cache-content-type": "^1.0.0",
"content-disposition": "~0.5.2",
"content-type": "^1.0.4",
"cookies": "~0.7.1",
"debug": "^3.1.0",
"delegates": "^1.0.0",
"depd": "^1.1.2",
"destroy": "^1.0.4",
"error-inject": "^1.0.0",
"escape-html": "^1.0.3",
"fresh": "~0.5.2",
"http-assert": "^1.3.0",
"http-errors": "^1.6.3",
"is-generator-function": "^1.0.7",
"koa-compose": "^4.1.0",
"koa-convert": "^1.2.0",
"koa-is-json": "^1.0.0",
"on-finished": "^2.3.0",
"only": "~0.0.2",
"parseurl": "^1.3.2",
"statuses": "^1.5.0",
"type-is": "^1.6.16",
"vary": "^1.1.2"
},
"devDependencies": {
"eslint": "^3.17.1",
"eslint-config-koa": "^2.0.0",
"eslint-config-standard": "^7.0.1",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^2.1.1",
"jest": "^20.0.0",
"supertest": "^3.1.0"
}
}
2、app.use 中间件, 其实就是做了个记录,把传入会掉push到middleware,callback函数会在http.createServer中以高阶函数的形式返回,注入ctx和之前push到middleware中的回调。所以当改变url触发了http.createServer ,会执行use中的函数。
//中间件
use(fn) {
if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
if (isGeneratorFunction(fn)) {
deprecate('Support for generators will be removed in v3. ' +
'See the documentation for examples of how to convert old middleware ' +
'https://github.com/koajs/koa/blob/master/docs/migration.md');
fn = convert(fn);
}
debug('use %s', fn._name || fn.name || '-');
this.middleware.push(fn);
return this;
}
//监听
listen(...args) {
debug('listen');
const server = http.createServer(this.callback());
return server.listen(...args);
}
//监听回调
callback() {
const fn = compose(this.middleware);
if (!this.listenerCount('error')) this.on('error', this.onerror);
const handleRequest = (req, res) => {
const ctx = this.createContext(req, res);
return this.handleRequest(ctx, fn);
};
return handleRequest;
}
3、自己开发use
//class router
let data = {}
class router {
constructor(str,fun){
Object.defineProperty(router,"data",{value:{}})
}
get(str,fun){
router.data[str] = fun;
}
async main(params,next){
await next();
let reg = /\/.*/g;
let {path} = params;
router.data[path](params);
}
}
module.exports=new router;
//执行
const Koa = require('koa');
const app = new Koa();
const router = require("./router");
router.get("/getData",async arg=>{
arg.body="hello world"
})
app.use(router.main); //响应
app.listen(3000);
网友评论