nodejs express 框架解密2-如何创建一个app
本文是基于express 3.4.6 的
1.在我们的app.js 文件里面有这么几行
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
这个其实是调用http模块 的 createServer 函数创建一个服务,然后监听端口的。
2. 我们再去看看express 的入口文件
/**
* Module dependencies.
*/ var connect = require('connect')
, proto = require('./application')
, Route = require('./router/route')
, Router = require('./router')
, req = require('./request')
, res = require('./response')
, utils = connect.utils; /**
* Expose `createApplication()`.
*/ exports = module.exports = createApplication; /**
* Expose mime.
*/ exports.mime = connect.mime; /**
* Create an express application.
*
* @return {Function}
* @api public
*/ function createApplication() {
var app = connect();
//将application中的方法全部拷贝到connect对象上去。
utils.merge(app, proto);
//设置app 的request对象的原型为req,本身的属性为connect对象
app.request = { __proto__: req, app: app };
//设置app的response对象原型为res ,本身的属性为connect对象
app.response = { __proto__: res, app: app };
//调用application中的方法init
app.init();
return app;
} /**
* Expose connect.middleware as express.*
* for example `express.logger` etc.
*/
/**
* 加载connect模块中得所有中间件
*/
for (var key in connect.middleware) {
Object.defineProperty(
exports
, key
, Object.getOwnPropertyDescriptor(connect.middleware, key));
} /**
* Error on createServer().
*/
/**
* 将创建服务器的方法输出
* @returns {Function}
*/
exports.createServer = function(){
console.warn('Warning: express.createServer() is deprecated, express');
console.warn('applications no longer inherit from http.Server,');
console.warn('please use:');
console.warn('');
console.warn(' var express = require("express");');
console.warn(' var app = express();');
console.warn('');
//加载创建应用程序的方法,开始创建application
return createApplication();
}; /**
* Expose the prototypes.
*/ exports.application = proto;
exports.request = req;
exports.response = res; /**
* Expose constructors.
*/ exports.Route = Route;
exports.Router = Router; // Error handler title exports.errorHandler.title = 'Express';
可以看到exports = module.exports = createApplication;将这个作为模块导出了,作为一个构造函数。
这个函数是:
function createApplication() {
var app = connect();
//将application中的方法全部拷贝到connect对象上去。
utils.merge(app, proto);
//设置app 的request对象的原型为req,本身的属性为connect对象
app.request = { __proto__: req, app: app };
//设置app的response对象原型为res ,本身的属性为connect对象
app.response = { __proto__: res, app: app };
//调用application中的方法init
app.init();
return app;
}
首先调用connect 组件app,于是将proto 上该有的方法都拷贝到app上去。proto是神马么?它就是 proto = require('./application') application.js 输出的“app” 对象 所有得函数,
接着将req,res 作为 组件app 的request,response 的原型,同时将app作为他们的一个属性,为什么要这么做呢?后面就会看到。最后调用app.init()方法,这个其实是调用application
中的init方法。
3.application.js
app.init = function(){
this.cache = {};
this.settings = {};
this.engines = {};
//默认配置
this.defaultConfiguration();
};
我们看到他是直接调用defaultConfiguration 方法的。我们再去看看defaultConfiguration方法的实现
app.defaultConfiguration = function(){
// default settings
this.enable('x-powered-by');
this.enable('etag');
this.set('env', process.env.NODE_ENV || 'development');
this.set('subdomain offset', 2);
debug('booting in %s mode', this.get('env'));
// implicit middleware
//调用中间件
this.use(connect.query());
this.use(middleware.init(this));
// inherit protos
//继承原型
this.on('mount', function(parent){
this.request.__proto__ = parent.request;
this.response.__proto__ = parent.response;
this.engines.__proto__ = parent.engines;
this.settings.__proto__ = parent.settings;
});
//router
//路由
this._router = new Router(this);
this.routes = this._router.map;
this.__defineGetter__('router', function(){
this._usedRouter = true;
this._router.caseSensitive = this.enabled('case sensitive routing');
this._router.strict = this.enabled('strict routing');
return this._router.middleware;
});
// setup locals
this.locals = locals(this);
// default locals
this.locals.settings = this.settings;
// default configuration
this.set('view', View);
this.set('views', process.cwd() + '/views');
this.set('jsonp callback name', 'callback');
this.configure('development', function(){
this.set('json spaces', 2);
});
this.configure('production', function(){
this.enable('view cache');
});
};
从代码中可以看到,它首先调用中间件,中间件的作用主要是改写改写request,response 请求的。将这2个请求导出,方便后面的模板渲染。然后再调用路由模块。路由模块只要是根据path
调用路由分发函数分发路由,执行callback,最后调用view 模块,渲染我们的模板。
nodejs express 框架解密2-如何创建一个app的更多相关文章
- nodejs express 框架解密4-路由
本文档是基于express3.4.6 express 的路由是自己去实现的,没有使用connect中的路由中间件模块. 1.在如何创建一个app那篇中,我们提到了路由, //router //路由 t ...
- nodejs express 框架解密1-总体结构
本文是基于express3.4.6的. 1.express 代码结构为: bin/express 是在命令行下的生成express 框架目录文件用的 lib/express 是框架的入口文件 lib/ ...
- nodejs express 框架解密3-中间件模块
本文档是基于express 3.4.6 的 在上篇中我们提到了中间件,这篇主要解释这个模块,middleware.js 为: var utils = require('./utils'); /** * ...
- nodejs express 框架解密5-视图
本文档是基于express 3.4.6 的 在我们的代码中,渲染模板大致是这样写的 exports.index = function(req, res){ res.render('index', { ...
- Express 的基本使用(创建一个简单的服务器)
Express 的基本使用(创建一个简单的服务器) const express = require('express') // 创建服务器应用程序 // 相当于 http.creatServer co ...
- diango创建一个app
创建一个app terminal里执行命令 python manage.py startapp app名称 注册 settings配置 INSTALLED_APPS = [ 'app01', 'app ...
- nodeJS express框架 中文乱码解决办法
最近在研究javascript 的服务端应用 node,之所以想要研究node,是因为前几个月一直在前端挣扎,从javascript入门到在项目中实际使用javascript,确实感悟颇深.javas ...
- React第一篇: 搭建React + nodejs + express框架
前提: 需要安装Node.js (>6)版本 1.cmd进到本地某个目录, 逐行输入以下指令(以下括号为注释) npm install -g create-react-app (全局安装cr ...
- NodeJS express框架的使用
首先,可以通过npm或者淘宝镜像cnpm全局安装epress框架,这里不具体说了 npm install -g expressnpm install -g express-generator 新建一个 ...
随机推荐
- matlab微分方程dsolve使用
y=dsolve('Dy=exp(-x-y-2)','y(0)=-2','x') dy/dx 写成Dy (注意大小写) y(0)=-2 表示初始条件 'x'表示积分变量
- C语言extern作用(全局变量)
用C语言编写程序的时候,我们经常会遇到这样一种情况:希望在头文件中定义一个全局变量,然后包含到两个不同的c文件中,希望这个全局变量能在两个文件中共用. 举例说明:项目文件夹project下有main. ...
- Install Solr+tomcat
1. chose the release you want: http://archive.apache.org/dist/lucene/solr/. 1) copy [solr_home]/dist ...
- oracle psql 调优
1 不一定sql越长反倒性能越差,尽量多where条件使得初始结果集最小,然后再和其他表相连 2 使用patition 3 同一个结果集被多次使用,可以使用with table
- Xamarin.Android之下拉刷新
一.前言 当今任何一个App中只要存在列表,基本上都会使用下拉刷新,而身为Xamarin一族的我们自然也不会落后,下面笔者将带领大家在Xamarin下实现Android中的下拉刷新的效果. 二.准备工 ...
- Java 中的反射机制
JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...
- Html5文件
HTML5 file api 读取文件MD5码 http://www.zhuwenlong.com/blog/52d6769f93dcae3050000003
- 浅谈压缩感知(三十一):压缩感知重构算法之定点连续法FPC
主要内容: FPC的算法流程 FPC的MATLAB实现 一维信号的实验与结果 基于凸优化的重构算法 基于凸优化的压缩感知重构算法. 约束的凸优化问题: 去约束的凸优化问题: 在压缩感知中,J函数和H函 ...
- Java-JDK配环境,eclipse工具认识
一.JDK配环境: 1.JDK思维导图 2.测试代码: 需要注意点位类名大小写的区分,符号为英式输入法下的, ; . class Hello{ public static void main(Stri ...
- PHP将XML转成数组
如果你使用 curl 获取的 xml data$xml = simplexml_load_string($data);$data['tk'] = json_decode(json_encode($xm ...