let http = require('http');
let url = require('url');
let methods = require('methods');
let fs = require('fs');
// 主文件
function application() {
function app(req, res) {
let { pathname } = url.parse(req.url, true);
let requestMethod = req.method.toLowerCase();
let i = 0
function next(err) {
if (i === app.routes.length) return res.end(`Cannot ${requestMethod} ${pathname}`);
let layer = app.routes[i++];
let { path, method, callback } = layer; // 取出来的路径 可能是正则类型
if (err) { // 有没有错误 是不是错误处理中间件
if (method === 'middleware' && callback.length === 4) { // 是中间件
callback(err, req, res, next);
} else { // 如果有错误 把错误继续传递,找错误处理中间件
next(err);
}
} else {
if (method === 'middleware') {
// 中间件 /hello/ /hello/123123
// 是/ 或者 路径相等 以中间件路径开头
if (path === '/' || path === pathname || pathname.startsWith(path + '/')) {
callback(req, res, next);
} else {
next();
}
} else {
if (path instanceof RegExp) { // 路径参数
if (path.test(pathname)) { // /article/([^\/]) /article/1
let [, ...others] = pathname.match(path); // 匹配出来对用的路径参数
req.params = path.params.reduce((memo, next, index) => (memo[next] = others[index], memo), {}); // 把两个数组合并成一个对象
return callback(req, res);
} else {
next();
}
} else {
if ((path == pathname || path == '*') && (method == requestMethod || method === 'all')) {
callback(req, res);
} else {
next();
}
}
}
}
}
next();
}
app.routes = []; // 路由的关系存放处
app.listen = function (...args) {
let server = http.createServer(app);
server.listen(...args);
};
// 中间件
app.use = function (path, callback) {
// 中间件第一个路径参数未传默认
if (typeof callback !== 'function') {
callback = path; // 没有传递路径 那么路径就是callback
path = '/' //路径默认为/ 全部匹配
}
let layer = {
path,
callback,
method: 'middleware' // 表示这个layer是一个中间件
}
app.routes.push(layer);
};
// 请求get、post...
[...methods, 'all'].forEach(method => {
app[method] = function (path, callback) {
// 路径参数
if (path.includes(':')) { // 是路径参数 /article/([^\/]*)
let params = []; // id
path = path.replace(/:([^\/]*)/g, function () {
params.push(arguments[1]);
return '([^\/]*)'
});
path = new RegExp(path);
path.params = params; // 把匹配到的数组 存在路径上
}
let layer = {
method,
path, // path如果是字符串我就认为是普通的路由
callback
}
app.routes.push(layer);
}
})
// 添加默认的一些请求和响应属性
app.use(function (req, res, next) {
let { query, pathname } = require('url').parse(req.url, true);
req.query = query;
req.path = pathname;
res.send = function (value) {
if (Buffer.isBuffer(value) || typeof value === 'string') {
res.end(value)
} else if (typeof value === 'object') {
res.setHeader('Content-Type', 'text/html;charset=utf8');
res.end(JSON.stringify(value))
}
}
next();
})
return app;
}
// 静态服务
application.static = function (dir) {
let path = require('path');
return function (req, res, next) {
let p = req.path;
let realPath = path.join(dir, p);
fs.stat(realPath, function (err, statObj) {
if (err) {
next();
} else {
if (statObj.isDirectory()) {
} else {
fs.readFile(realPath, 'utf8', function (err, data) {
if (err) {
next();
}else{
res.end(data);
}
})
}
}
})
}
}
module.exports = application;
复制代码
Node框架Express源码
最新推荐文章于 2024-07-24 11:38:03 发布