Express 学习笔记(3):创建Express应用程序

(注:部分示例摘自或修改自《Pro Node.js for Developers》)

Express提供了一个控制台工具,用来方便地创建一个Express文件结构。这个文件结构包含了一系列配置文件、路径文件等等,能够很好地规划由大量代码构建成的网站。

例如下面我们创建了一个叫做testapp的项目

    $ express testapp

        create : testapp
        create : testapp/package.json
        create : testapp/app.js
        create : testapp/public
        create : testapp/public/stylesheets
        create : testapp/public/stylesheets/style.css
        create : testapp/routes
        create : testapp/routes/index.js
        create : testapp/routes/user.js
        create : testapp/public/javascripts
        create : testapp/views
        create : testapp/views/layout.jade
        create : testapp/views/index.jade
        create : testapp/public/images

还可以安装这个项目中的一些依赖(例如jade等)

    $ cd testapp
    $ npm install

然后就可以启动这个项目

    $ node app

注:如果使用了IntelliJ IDEA等IDE创建的项目,以上过程会由IDE自动完成。

下面我们来分析一些这些由Express创建出的文件。在这个文件结构中,Express的核心文件是app.js。

下面就是这个文件的内容:

/**
 * Module dependencies.
 */

var express = require('express');  
var routes = require('./routes');  
var user = require('./routes/user');  
var http = require('http');  
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);  
app.set('views', path.join(__dirname, 'views'));  
app.set('view engine', 'jade');  
app.use(express.favicon());  
app.use(express.logger('dev'));  
app.use(express.json());  
app.use(express.urlencoded());  
app.use(express.methodOverride());  
app.use(app.router);  
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {  
    app.use(express.errorHandler());
}

app.get('/', routes.index);  
app.get('/users', user.list);

http.createServer(app).listen(app.get('port'), function(){  
    console.log('Express server listening on port ' + app.get('port'));
});

在这个文件中,首先通过require()包含了一系列用到的模块(httppathexpress等模块)。紧接着定义了一个名为app的变量,并通过express()为其赋值。这个app变量是整个系统中的核心,我们很多的操作都是围绕着它进行的。

紧接着,文件调用了appset方法。这个方法的功能就是去定义一些应用程序的设置信息。它的第一个参数是属性名称,第二个参数是属性值

第一个设置的信息port是指端口号,如果未指定端口号(process.env.PORT没有定义)则使用默认端口号3000

第二个设置信息是views,用来指定模板存放的文件夹,其中\_\_dirname是当前文件(app.js)所在的文件夹。所以\_\_dirname+'/views'则表示当前文件夹下的views子文件夹。

第三个设置信息是view engine,用来指定模板文件的解释引擎。

在设置信息之后,紧接着调用了一系列的use()函数。这个函数用来指定使用中间件。所谓中间件,就是一个能够在所有请求中都会被调用的组件。

favicon中间件用来指定一个“favicon.ico”文件。这个文件会被浏览器自动请求,以显示网站的favicon。当未指定这个图标时,使用这个中间件会让系统自动提供一个favicon。

logger中间件是用来在每个请求收到时,记录下相应的信息。如果指定了“dev”参数,则会记录下每一个请求的方法和URL,也包括响应的状态码、处理请求的时间和返回数据的大小等信息,并且将这些信息输出出来。

json中间件可以用来解析JSON格式的数据。并将数据转换成req.body中的对象。

urlencoded中间件是用来解析“x-www-form-urlencoded”请求体

methodOverride中间件用来防止一些浏览器限制只能以GET和POST方式提交表单。

app.router中间件是Express的路径模块,用来将请求映射到定义的路径上。

static中间件用来接受静态文件。所有的静态文件可以都存储在public这个文件夹下。

后面使用了app.get("env")判断了当前所处的环境,如果是development,则使用errorHandler中间件。这个中间件用来处理错误信息。

set()use()之后,使用了两个get方法。这里要注意,这个get不是set的反义词,而是http method中的get。

get()用来响应HTTP GET方法。其中第一个参数是URL,第二个参数则是一个函数。例如app.get('/', user.list);中,传递了“user.list”。我们可以代码前部看到user对象是通过require('./routes/user');获取到的。'/routes'是一个文件夹,在这个文件夹下有'user.js'。我们可以看看user.js的代码:

/*
 * GET users listing.
 */

exports.list = function(req, res){  
  res.send("respond with a resource");
};

在这段代码中,我们通过exports.list = function()的形式,导出了一个外部函数list。所以这个函数能够在app.js中被访问到。而这个函数的功能则是直接输出respond with a resource

而路径/就显得比较奇怪了,因为它所使用的route.index并未导入。实际上在Node.js中有这样的规定:如果require()中的路径是一个文件夹,就会自动导入这个文件夹下的index.js文件。也就是说require("./routes")就是require("./routes/index/js")

我们再来看看app.get('/', routes.index);这句话中,routes.index中的内容。这部分内容存储在了/routes/index.js中:

/*
 * GET home page.
 */
exports.index = function(req, res){  
    res.render('index', { title: 'Express' });
};

这段代码导出了一个叫做index的函数,这个函数在app.js中被使用到。函数的功能是调用response对象的render方法。render方法是模板系统中常用的一个方法,功能就是渲染一个指定的模板,并且将数据填充进去,将渲染结果填充到response报文中。

有关模板的使用方法,我会在下一次继续分析。

Friskit

继续阅读此作者的更多文章