jackieli123723 / jackieli123723.github.io

✅lilidong 个人博客

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

koa的框架迷你版

jackieli123723 opened this issue · comments

const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
const mime = {
"html": "text/html",
"css": "text/css",
"js": "text/javascript",
"json": "application/json",
"gif": "image/gif",
"ico": "image/x-icon",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png"
};
//静态资源处理
function handleStatic(res, pathname, ext) {
fs.exists(pathname, (exists) => {
if(!exists) {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.write('The request url' + pathname + 'was not found on this server');
res.end()
} else {
fs.readFile(pathname, (err, file) => {
if(err) {
res.writeHead(500, {'Content-Type': 'text/plain'});
res.end(err)
} else {
const contentType = mime[ext] || 'text/plain';
res.writeHead(200, {'Content-Type': contentType});
res.write(file);
res.end()
}
})
}
})
}
//用generator函数实现routes数组的遍历
const lazy = function* (arr) {
yield* arr;
};
const passRouter = (routes, method, path) => (req, res) => {
let ctx = {
req,
res
};
const replaceParams = (path) => new RegExp(`\^${path.replace(/:\w[^\/]+/g, '\\w[^\/]+')}\$`);
const lazyRoutes = lazy(routes);
//闭包实现函数递归
(function next () {
const it = lazyRoutes.next().value;
if (!it) {
res.end(`Cannot ${method} ${pathname}`);
return;
} else if (it.method === 'use'
&& (it.path === '/'
|| it.path === path
|| path.startsWith(it.path.concat('/')))) {
it.fn(ctx, next);
} else if ((it.method === method
|| it.method === 'all')
&& (it.path === path
|| it.path === '*')) {
it.fn(ctx,next);
} else if ( it.path.includes(':')
&& (it.method === method
|| it.method === 'all')
&& (replaceParams(it.path).test(path))) {
let index = 0;
const param2Array = it.path.split('/');
const path2Array = path.split('/');
const params = {};
param2Array.forEach((path) => {
if(/\:/.test(path)) {
params[path.slice(1)] = path2Array[index]
}
index++
});
req.params = params;
it.fn(ctx,next);
} else {
next();
}
}());
};
function core() {
//默认静态文件目录
let _static = 'static';
let app = (req, res) => {
const method = req.method.toLowerCase();
const urlObj = url.parse(req.url, true);
const pathname = urlObj.pathname;
const ext = path.extname(pathname).slice(1);
if(ext) {
handleStatic(res, _static + pathname, ext)
} else {
passRouter(app.routes, method, pathname)(req, res)
}
};
app.setStatic = (path) => {
_static = path
};
app.routes = [];
const methods = ['get', 'post', 'put', 'options', 'delete', 'all', 'use'];
methods.forEach((method) => {
app[method] = (path, fn) => {
app.routes.push({
method: method,
path: path,
fn: fn
})
}
});
app.listen = (port=3000, host='localhost') => {
http.createServer(app).listen(port, host, () => {
console.log(`Server running at ${host}\:${port}.`);
process.setMaxListeners(0);
process.on('uncaughtException', function(err) {
console.log(err.stack)
});
process.stdin.resume();
process.on('SIGINT', function() {
console.log('\n');
console.log('Good Day!');
process.exit(2)
})
})
};
return app
}
module.exports = core;