Node框架Express源码

    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;
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node-RED 是一个基于 Node.js 构建的开源流程编排工具,它具有简单易用的特点,可以帮助用户快速搭建、管理和部署流程应用。Node-RED 的源码分析是指对其代码库进行深入剖析,以便了解其内部结构和工作原理。 首先,Node-RED 的源码主要由 JavaScript 编写,大部分代码都是围绕 Node.js 运行时环境展开。其核心功能是基于事件驱动的管道式数据处理,通过流程图的方式将各种节点(Node)串联起来,形成一个数据处理流程。因此,在源码分析中,需要重点关注事件驱动机制、节点的定义与扩展、消息传递机制等方面的实现细节。 其次,Node-RED 采用了 Express 框架来搭建 Web 服务,并通过 WebSocket 实现了实时通信。在源码分析中,需要深入了解其 Web 服务的实现方式,以及与客户端的交互方式和消息传递机制。此外,还需要对其对外部插件和节点的支持机制进行分析,以便了解其扩展性和定制化能力。 最后,在源码分析中还需要深入了解 Node-RED 的核心模块以及各种节点的实现方式,比如文件操作、网络请求、数据库操作等,以及其对于不同数据格式的处理能力。同时,还需要关注其错误处理、安全机制、性能优化等方面的实现方式。 总的来说,Node-RED 的源码分析是一个复杂而全面的工作,需要对 JavaScript 和 Node.js 相关技术有深入的了解,以便更好地理解其内部结构和工作原理,为进一步的定制和扩展工作提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值