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;复制代码