前言

Nodejs是一个年轻的编程框架,充满了活力和无限激情,一直都在保持着快速更新。基于Nodejs的官方Web开发库Express也在同步发展着,每年升级一个大版本,甚至对框架底层都做了大手术。在Express4时,替换掉中件间库connect,而改用多个更细粒度的库来取代。带来的好处是明显地,这些中间件能更自由的更新和发布,不会受到Express发布周期的影响;但问题也是很的棘手,不兼容于之前的版本,升级就意味着要修改代码。

之前写过一篇文章“Nodejs开发框架Express3.0开发手记–从零开始”,很多新学Node的朋友都在参考,但由于Express已经升级,文章中有部分的代码已经不能使用,所以就有了这篇介绍Express4.x的文章。

目录

  1. 建立工程
  2. 目录结构
  3. package.json项目配置
  4. app.js核心文件
  5. Bootstrap界面框架
  6. 路由功能
  7. 程序代码
  8. Express3.x和Express4.x的改动列表

1. 建立项目

让我们从头开始Express4.x的安装和使用吧,安装Node和NPM在本文就不多说了。Linux环境安装请参考文章,准备Nodejs开发环境Ubuntu,Window环境安装直接下载Node的安装文件,双击安装就行了。

我的系统环境

  • Win7 64bit
  • Nodejs:v0.10.31
  • Npm:1.4.23

首先,我们需要安装express库。在Express3.6.x之前的版本,Express需要全局安装的,项目构建器模块是合并在Express项目中的,后来这个构建器被拆分出来,独立成为了一个项目express-generator,现在我们只需要全局安装express-generator项目就行了。


~ npm install -g express-generator@4 #全局安装-g
C:\Users\Administrator\AppData\Roaming\npm\express -> C:\Users\Administrator\AppData\Roaming\npm\node_modules\express-ge
nerator\bin\express express-generator@4.11.2 C:\Users\Administrator\AppData\Roaming\npm\node_modules\express-generator
├── sorted-object@1.0.0
├── commander@2.6.0
└── mkdirp@0.5.0 (minimist@0.0.8)

安装好express-generator包后,我们在命令行就可以使用express命令了。


~ express -V # 检查express的版本
4.11.2 ~ express -h # 检查看express的帮助命令
Usage: express [options] [dir]
Options:
-h, --help output usage information
-V, --version output the version number
-e, --ejs add ejs engine support (defaults to jade)
--hbs add handlebars engine support
-H, --hogan add hogan.js engine support
-c, --css add stylesheet support (less|stylus|compass) (defaults to plain css)
--git add .gitignore
-f, --force force on non-empty directory

接下来,我们使用express的命令,来创建项目了。


~ cd D:\workspace\javascript # 进入工作目录 ~ D:\workspace\javascript>express -e nodejs-demo # 创建项目
create : nodejs-demo
create : nodejs-demo/package.json
create : nodejs-demo/app.js
create : nodejs-demo/public/javascripts
create : nodejs-demo/public/images
create : nodejs-demo/public
create : nodejs-demo/public/stylesheets
create : nodejs-demo/public/stylesheets/style.css
create : nodejs-demo/views
create : nodejs-demo/views/index.ejs
create : nodejs-demo/views/error.ejs
create : nodejs-demo/routes
create : nodejs-demo/routes/index.js
create : nodejs-demo/routes/users.js
create : nodejs-demo/bin
create : nodejs-demo/bin/www install dependencies:
$ cd nodejs-demo && npm install
run the app:
$ DEBUG=nodejs-demo:* ./bin/www

进入项目目录,下载依赖库,构建项目。


~ D:\workspace\javascript>cd nodejs-demo && npm install

启动项目。


~ D:\workspace\javascript\nodejs-demo>npm start > express4-demo@0.0.0 start D:\workspace\javascript\nodejs-demo
> node ./bin/www module.js:338
throw err;
^
Error: Cannot find module './routes/users'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (D:\workspace\javascript\nodejs-demo\app.js:9:13)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)

第一次启动发生了错误,可能是express-generator和express不匹配造成的,找到问题在app.js文件中,注释第9行和第26行。


..
//var users = require('./routes/users');
..
//app.use('/users', users);
..

再次启动项目。


D:\workspace\javascript\nodejs-demo>npm start
> express4-demo@0.0.0 start D:\workspace\javascript\nodejs-demo
> node ./bin/www

项目启动成功,打开浏览器 http://localhost:3000,就可以看到显示的页面了。

这样非常简单地,我们就把一个最基本的Web应用做好了,就是几条命令而已。

2. 目录结构

接下来,我们详细看一下Express4项目的结构、配置和使用。

  • bin, 存放启动项目的脚本文件
  • node_modules, 存放所有的项目依赖库。
  • public,静态文件(css,js,img)
  • routes,路由文件(MVC中的C,controller)
  • views,页面文件(Ejs模板)
  • package.json,项目依赖配置及开发者信息
  • app.js,应用核心配置文件

3. package.json项目配置

package.json用于项目依赖配置及开发者信息,scripts属性是用于定义操作命令的,可以非常方便的增加启动命令,比如默认的start,用npm start代表执行node ./bin/www命令。

查看package.json文件。


{
"name": "express4-demo",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.10.2",
"cookie-parser": "~1.3.3",
"debug": "~2.1.1",
"ejs": "~2.2.3",
"express": "~4.11.1",
"morgan": "~1.5.1",
"serve-favicon": "~2.2.0"
}
}

4. app.js核心文件

从Express3.x升级到Express4.x,主要的变化就在app.js文件中。查看app.js文件,我已经增加注释说明。


// 加载依赖库,原来这个类库都封装在connect中,现在需地注单独加载
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser'); // 加载路由控制
var routes = require('./routes/index');
//var users = require('./routes/users'); // 创建项目实例
var app = express(); // 定义EJS模板引擎和模板文件位置,也可以使用jade或其他模型引擎
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs'); // 定义icon图标
app.use(favicon(__dirname + '/public/favicon.ico'));
// 定义日志和输出级别
app.use(logger('dev'));
// 定义数据解析器
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 定义cookie解析器
app.use(cookieParser());
// 定义静态文件目录
app.use(express.static(path.join(__dirname, 'public'))); // 匹配路径和路由
app.use('/', routes);
//app.use('/users', users); // 404错误处理
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
}); // 开发环境,500错误处理和错误堆栈跟踪
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
} // 生产环境,500错误处理
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
}); // 输出模型app
module.exports = app;

我们看到在app.js中,原来调用connect库的部分都被其他的库所代替,serve-favicon、morgan、cookie-parser、body-parser,默认项目中,只用到了最基本的几个库,还没有其他需要替换的库,在本文最后有详细列出。

另外,原来用于项目启动代码也被移到./bin/www的文件,www文件也是一个node的脚本,用于分离配置和启动程序。

查看./bin/www文件。


#!/usr/bin/env node /**
* 依赖加载
*/
var app = require('../app');
var debug = require('debug')('nodejs-demo:server');
var http = require('http'); /**
* 定义启动端口
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port); /**
* 创建HTTP服务器实例
*/
var server = http.createServer(app); /**
* 启动网络服务监听端口
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening); /**
* 端口标准化函数
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
} /**
* HTTP异常事件处理函数
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
} var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port // handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
} /**
* 事件绑定函数
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

5. Bootstrap界面框架

创建Bootstrap界面框架,直接在index.ejs文件上面做修改。可以手动下载Bootstrap库放到项目中对应的位置引用,也可以通过bower来管理前端的Javascript库,参考文章 bower解决js的依赖管理。另外还可以直接使用免费的CDN源加载Bootstrap的css和js文件。下面我就直接使用Bootcss社区提供的CDN源加载Bootstrap。

编辑views/index.ejs文件


<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title><%= title %></title>
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<div class="well jumbotron">
<h1><%= title %></h1>
<p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</body>
</html>

效果如下,已经加入了bootstrap的样式了。

接下来,我们把index.ejs页面切分成3个部分:header.ejs, index.ejs, footer.ejs,用于网站页面的模块化。

  • header.ejs, 为页面的头部区域
  • index.ejs, 为内容显示区域
  • footer.ejs,为页面底部区域

编辑header.ejs。


<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title><%= title %></title>
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>

编辑footer.ejs。


<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</body>
</html>

编辑index.ejs。


<% include header.ejs %> <div class="well jumbotron">
<h1><%= title %></h1>
<p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div> <% include footer.ejs %>

把页表和页底的代码分离后,让index.ejs页面的核心代码更少,更容易维护。

6. 路由功能

路由功能,是Express4以后全面改版的功能。在应用程序加载隐含路由中间件,不用担心在中间件被装载相对于路由器中间件的顺序。定义路由的方式是不变的,路由系统中增加2个新的功能。

  • app.route()函数,创建可链接的途径处理程序的路由路径。
  • express.Router类,创建模块化安装路径的处理程序。

app.route方法会返回一个Route实例,它可以继续使用所有的HTTP方法,包括get,post,all,put,delete,head等。


app.route('/users')
.get(function(req, res, next) {})
.post(function(req, res, next) {})

express.Router类,则可以帮助我们更好的组织代码结构。在app.js文件中,定义了app.use(‘/’, routes); routes是指向了routes目录下的index.js文件,./routes/index.js文件中,express.Router被定义使用,路径/*处理都会由routes/index.js文件里的Router来处理。如果我们要管理不同的路径,那么可以直接配置为多个不同的Router。


app.use('/user', require('./routes/user').user);
app.use('/admin', require('./routes/admin').admin);
app.use('/', require('./routes'));

7. 程序代码

对于刚接触Express4.x的朋友,可以直接从Github上面下载本文项目中的源代码,按照片文章中的介绍学习Express4,下载地址:https://github.com/bsspirit/nodejs-demo/tree/express4

也可以直接用github命令行来下载:


~ git clone git@github.com:bsspirit/nodejs-demo.git # 下载github项目
~ cd nodejs-demo # 进入下载目录
~ git checkout express4 # 切换到express4的分支
~ npm install # 下载依赖库
~ npm start # 启动服务器

注:Github上本项目有3分支,express3和master分支都是express3的例子,express4分支是本文的例子。

当然,本文对express4的介绍其实还远远不够,除了文中说到的express改动的部分,其他的部分都express3类似,所以更详细的使用说明,还请大家同时参考文章,Nodejs开发框架Express3.0开发手记–从零开始 来一起学习。

nodejs+express开发blog(1)的更多相关文章

  1. nodejs+express开发blog(2)

    npm install -g nodemon 1,把ejs文件修改为html文件 app.engine('.html', require('ejs').__express);app.set('view ...

  2. nodejs express开发

    用NodeJS+Express开发WEB应用---第一篇 大漠穷秋2014-03-28 预热 为了对后面的内容理解更加透彻,推荐首先阅读下面这篇很好的文章: http://www.nodebeginn ...

  3. NodeJS+Express开发web,为什么中文显示为乱码

    把你的文件另存为下,格式为utf-8的试下就行!

  4. NodeJS+Express+mySQL服务端开发详解

    随着NodeJS的发展,现在已经被很多人熟知,NodeJS已经成为了前端开发人员必备的技能.本文不会对NodeJS过多介绍 如果你感兴趣可以访问NodeJS 官网, 维基百科 本文是利用NodeJS+ ...

  5. 像asp.net Mvc一样开发nodejs+express Mvc站点

    像asp.net Mvc一样开发nodejs+express Mvc站点 首先,我是个c#码农.从事Mvc开发已然4个年头了,这两年前端MVC的兴起,我也跟风学了一些,对前端的框架也了解一些,angu ...

  6. NodeJS+Express+MySQL开发小记(2):服务器部署

    http://borninsummer.com/2015/06/17/notes-on-developing-nodejs-webapp/ NodeJS+Express+MySQL开发小记(1)里讲过 ...

  7. nodejs+express blog项目分享

    项目简介:项目采用nodejs+express+typescript+mongodb技术搭建 主要功能: 1.用户注册 2.用户登录 3.文章管理模块 4.图片管理模块 5.token认证 6.密码加 ...

  8. 用nodejs,express,ejs,mongo,extjs实现了简单了网站后台管理系统

    源代码下载地址:http://download.csdn.net/detail/guoyongrong/6498611 这个系统其实是出于学习nodejs的目的而改写的系统. 原来的系统前端使用了ex ...

  9. Nodejs express、html5实现拖拽上传

    一.前言 文件上传是一个比较常见的功能,传统的选择方式的上传比较麻烦,需要先点击上传按钮,然后再找到文件的路径,然后上传.给用户体验带来很大问题.html5开始支持拖拽上传的需要的api.nodejs ...

随机推荐

  1. linux修改文件权限命令(chmod)

    chmod命令是用于改变文件或目录的访问权限.用户用它控制文件或目录的访问权限. 该命令有两种用法.一种是包含字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. 1.文字设定法 chmod ...

  2. 洛谷P3177 [HAOI2015]树上染色(树上背包)

    题意 题目链接 Sol 比较套路吧,设\(f[i][j]\)表示以\(i\)为根的子树中选了\(j\)个黑点对答案的贡献 然后考虑每条边的贡献,边的两边的答案都是可以算出来的 转移的时候背包一下. # ...

  3. 对HTML的大致了解

    HTML的全称是Hyper Text Markup Language(超文本标记语言),是一种标记语言.其中,HTML文档一个重要的.广泛使用的标准HTML4.01是在1999年12月24日由W3C组 ...

  4. LAMP专业术语的规范书写格式

    DIV+CSS(技术) MySQL(数据库) Sphinx(中文分词技术) JavaScript(语言) MySQLi(MySQL数据库连接方式) MongoDB(NoSQL数据库) Ajax(Jav ...

  5. pcharm激活

    服务器搭建命令:(一直默认即可) wget http://home.ustc.edu.cn/~mmmwhy/jetbrain.sh && sh ./jetbrain.sh 我搭建的服务 ...

  6. Python 基于固定 IP 来命名 ARM 虚拟机的实现

    问题描述 希望通过 Python 批量创建 ARM 虚拟机,并且在虚拟机命名时加入固定 IP 信息,方便管理维护. 问题分析 在创建 ARM 虚拟机之前,先创建固定 IP,然后获取固定 IP 地址,创 ...

  7. Dynamics CRM 批量新建域用户

    好久没写了,今天大牛教了我偷懒的批量新建域用户的方法 是不是觉得  控制面板 =>管理工具=>用户和计算机=>Users=>新建用户,一个个建,很烦是不是,而且耗时,我上个项目 ...

  8. day014-反射、注解

    1. Junit 1.1什么是Junit Junit是Java语言编写的第三方单元测试框架(工具). 1.2单元测试 在Java中,一个类就是一个单元. 单元测试:开发中编写的一小段代码,用来检测类中 ...

  9. IEEP-网络规划

    HCNP-R&S证书是公认人具备中小型企业网络构建和管理能力的专业人士   IEEP包含五个方面内容 1.网络规划与设计 2.网络实施与维护 3.网络排障 4.网络优化 5.网络割接     ...

  10. 查看锁定的session信息脚本

    查看当前被阻塞的对象和锁信息SELECT DISTINCT       s1.inst_id BlockingInst,       s1.sid BlockingSid,       s1.seri ...