设为首页 收藏本站
查看: 1799|回复: 0

[经验分享] Express使用手记:核心入门

[复制链接]

尚未签到

发表于 2017-2-25 10:43:29 | 显示全部楼层 |阅读模式
入门简介
  Express是基于nodejs的web开发框架。优点是易上手、高性能、扩展性强。


  • 易上手:nodejs最初就是为了开发高性能web服务器而被设计出来的,然而相对底层的API会让不少新手望而却步。express对web开发相关的模块进行了适度的封装,屏蔽了大量复杂繁琐的技术细节,让开发者只需要专注于业务逻辑的开发,极大的降低了入门和学习的成本。
  • 高性能:express仅在web应用相关的nodejs模块上进行了适度的封装和扩展,较大程度避免了过度封装导致的性能损耗。
  • 扩展性强:基于中间件的开发模式,使得express应用的扩展、模块拆分非常简单,既灵活,扩展性又强。
环境准备
  首先,需要安装nodejs,这一步请自行解决。接着,安装express的脚手架工具express-generator,这对于我们学习express很有帮助。
  

npm install -g express-generator  

第一个demo
  利用之前安装的脚手架工具,初始化我们的demo项目。
  

  /tmp mkdir express-demo  /tmp cd express-demo
  express-demo express
  

  create : .
  create : ./package.json
  create : ./app.js
  create : ./public
  create : ./public/javascripts
  create : ./public/images
  create : ./public/stylesheets
  create : ./public/stylesheets/style.css
  create : ./routes
  create : ./routes/index.js
  create : ./routes/users.js
  create : ./views
  create : ./views/index.jade
  create : ./views/layout.jade
  create : ./views/error.jade
  create : ./bin
  create : ./bin/www
  

  install dependencies:
  $ cd . && npm install
  

  run the app:
  $ DEBUG=express-demo:* npm start
  

  按照指引,安装依赖。并启动服务
  

npm install  

  然后,启动服务器。
  

  express-demo  npm start  

  
> ex1@0.0.0 start /private/tmp/ex1
  
> node ./bin/www
  

  访问浏览器,迈出成功的第一步。


目录结构介绍
  看下demo应用的目录结构。大部分时候,我们的应用目录结构跟这个保持一致就可以了。也可以根据需要自行调整,express并没有对目录结构进行限制。
  从目录结构可以大致看出,express应用的核心概念主要包括:路由、中间件、模板引擎。
  

  express-demo tree -L 1  
.
  
├── app.js # 应用的主入口
  
├── bin  # 启动脚本
  
├── node_modules # 依赖的模块
  
├── package.json # node模块的配置文件
  
├── public # 静态资源,如css、js等存放的目录
  
├── routes # 路由规则存放的目录
  
└── views # 模板文件存放的目录
  

  
5 directories, 2 files
  

核心概念简介
  上面提到,express主要包含三个核心概念:路由、中间件、模板引擎。

  注意,笔者这里用的是核心概念这样的字眼,而不是核心模块,为什么呢?这是因为,虽然express的中间件有它的定义规范,但是express的内核源码中,其实是没有所谓的中间件这样的模块的。

  言归正传,三者简要的来说就是。


  • 中间件:可以毫不夸张的说,在express应用中,一切皆中间件。各种应用逻辑,如cookie解析、会话处理、日志记录、权限校验等,都是通过中间件来完成的。
  • 路由:地球人都知道,负责寻址的。比如用户发送了个http请求,该定位到哪个资源,就是路由说了算。
  • 模板引擎:负责视图动态渲染。下面会介绍相关配置,以及如何开发自己的模板引擎。
核心概念:路由

路由分类
  粗略来说,express主要支持四种类型的路由,下面会分别举例进行说明


  • 字符串类型
  • 字符串模式类型
  • 正则表达式类型
  • 参数类型
  分别举例如下,细节可参考官方文档。
var express = require('express');  
var app = express();
  

  
// 路由:字符串类型
  
app.get('/book', function(req, res, next){
  res.send('book');
  
});
  

  
// 路由:字符串模式
  
app.get('/user/*man', function(req, res, next){
  res.send('user');  // 比如: /user/man, /user/woman
  
});
  

  
// 路由:正则表达式
  
app.get(/animals?$/, function(req, res, next){
  res.send('animal');  // 比如: /animal, /animals
  
});
  

  
// 路由:命名参数
  
app.get('/employee/:uid/:age', function(req, res, next){
  res.json(req.params);  // 比如:/111/30,返回 {"uid": 111, "age": 30}
  
});
  

  
app.listen(3000);

路由拆分
  当你用的应用越来越复杂,不可避免的,路由规则也会越来越复杂。这个时候,对路由进行拆分是个不错的选择。
  我们分别看下两段代码,路由拆分的好处就直观的体现出来了。
  路由拆分前
  

var express = require('express');  
var app = express();
  

  
app.get('/user/list', function(req, res, next){
  res.send('/list');
  
});
  

  
app.get('/user/detail', function(req, res, next){
  res.send('/detail');
  
});
  

  
app.listen(3000);
  

  这样的代码会带来什么问题呢?无论是新增还是修改路由,都要带着/user前缀,这对于代码的可维护性来说是大忌。这对小应用来说问题不大,但应用复杂度一上来就会是个噩梦。
  路由拆分后
  可以看到,通过express.Router()进行了路由拆分,新增、修改路由都变得极为便利。
  

var express = require('express');  
var app = express();
  

  
var user = express.Router();
  

  
user.get('/list', function(req, res, next){
  res.send('/list');
  
});
  

  
user.get('/detail', function(req, res, next){
  res.send('/detail');
  
});
  

  
app.use('/user', user); // mini app,通常做应用拆分
  

  
app.listen(3000);
  

核心概念:中间件
  一般学习js的时候,我们都会听到一句话:一切皆对象。而在学习express的过程中,很深的一个感受就是:一切皆中间件。比如常见的请求参数解析、cookie解析、gzip等,都可以通过中间件来完成。

工作机制
  贴上官网的一张图镇楼,图中所示就是传说中的中间件了。

  首先,我们自己编写一个极简的中间件。虽然没什么实用价值,但中间件就长这样子。


  • 参数:三个参数,熟悉http.createServer()的同学应该比较眼熟,其实就是req(客户端请求实例)、res(服务端返回实例),只不过进行了扩展,添加了一些使用方法。
  • next:回调方法,当next()被调用时,就进入下一个中间件。
function logger(req, res, next){  console.log('here comes request');
  next();
  
}
  来看下实际例子:
var express = require('express');  
var app = express();
  

  
app.use(function(req, res, next) {
  console.log('1');
  next();
  
});
  

  
app.use(function(req, res, next) {
  console.log('2');
  next();
  
});
  

  
app.use(function(req, res, next) {
  console.log('3');
  res.send('hello');
  
});
  

  
app.listen(3000);
  请求 http://127.0.0.1:3000,看下控制台输出,以及浏览器返回内容。
  

  middleware git:(master)  node chains.js  
1
  
2
  
3
  



应用级中间件 vs 路由级中间件
  根据作用范围,中间件分为两大类:


  • 应用级中间件
  • 路由级中间件。
  两者的区别不容易说清楚,因为从本质来讲,两类中间件是完全等同的,只是使用场景不同。同一个中间件,既可以是应用级中间件、也可以是路由级中间件。
  直接上代码可能更直观。参考下面代码,可以简单粗暴的认为:


  • 应用级中间件:app.use()、app.METHODS()接口中使用的中间件。
  • 路由级中间件:router.use()、router.METHODS()接口中使用的中间件。
  

var express = require('express');  
var app = express();
  
var user = express.Router();
  

  
// 应用级
  
app.use(function(req, res, next){
  console.log('收到请求,地址为:' + req.url);
  next();
  
});
  

  
// 应用级
  
app.get('/profile', function(req, res, next){
  res.send('profile');
  
});
  

  
// 路由级
  
user.use('/list', function(req, res, next){
  res.send('/user/list');
  
});
  

  
// 路由级
  
user.get('/detail', function(req, res, next){
  res.send('/user/detail');
  
});
  

  
app.use('/user', user);
  

  
app.listen(3000);
  

开发中间件
  上面也提到了,中间件的开发是是分分钟的事情,不赘述。
function logger(req, res, next){  doSomeBusinessLogic(); // 业务逻辑处理,比如权限校验、数据库操作、设置cookie等
  next();  // 如果需要进入下一个中间件进行处理,则调用next();
  
}

常用中间件
  包括但不限于如下。更多常用中间件,可以点击 这里


  • body-parser
  • compression
  • serve-static
  • session
  • cookie-parser
  • morgan
核心概念:模板引擎
  模板引擎大家不陌生了,关于express模板引擎的介绍可以参考官方文档。
  下面主要讲下使用配置、选型等方面的内容。

可选的模版引擎
  包括但不限于如下模板引擎


  • jade
  • ejs
  • dust.js
  • dot
  • mustache
  • handlerbar
  • nunjunks
配置说明
  先看代码。
// view engine setup  
app.set('views', path.join(__dirname, 'views'));
  
app.set('view engine', 'jade');
  有两个关于模版引擎的配置:


  • views:模版文件放在哪里,默认是在项目根目录下。举个例子:app.set('views', './views')
  • view engine:使用什么模版引擎,举例:app.set('view engine', 'jade')
  可以看到,默认是用jade做模版的。如果不想用jade怎么办呢?下面会提供一些模板引擎选择的思路。

选择标准
  需要考虑两点:实际业务需求、个人偏好。
  首先考虑业务需求,需要支持以下几点特性。


  • 支持模版继承(extend)
  • 支持模版扩展(block)
  • 支持模版组合(include)
  • 支持预编译
  对比了下,jade、nunjunks都满足要求。个人更习惯nunjunks的风格,于是敲定。那么,怎么样使用呢?

支持nunjucks
  首先,安装依赖
npm install --save nunjucks  然后,添加如下配置
  

var nunjucks = require('nunjucks');  

  
nunjucks.configure('views', {
  autoescape: true,
  express: app
  
});
  

  
app.set('view engine', 'html');
  

  看下views/layout.html
<!DOCTYPE html>  
<html>
  
<head>
  <title>

  {% block>
  layout>  {% endblock %}
  </title>
  
</head>
  
<body>
  
<h1>
  {% block appTitle %}

  layout app>  {% endblock %}
  
</h1>
  
<p>正文</p>
  

  
</body>
  
</html>
  看下views/index.html
{% extends &quot;layout.html&quot; %}
  
{% block>  
{% block appTitle %}首页{% endblock %}

开发模板引擎
  通过app.engine(engineExt, engineFunc)来注册模板引擎。其中


  • engineExt:模板文件后缀名。比如jade。
  • engineFunc:模板引擎核心逻辑的定义,一个带三个参数的函数(如下)
// filepath: 模板文件的路径  
// options:渲染模板所用的参数
  
// callback:渲染完成回调
  
app.engine(engineExt, function(filepath, options, callback){
  

  // 参数一:渲染过程的错误,如成功,则为null
  // 参数二:渲染出来的字符串
  return callback(null, 'Hello World');
  
});
  比如下面例子,注册模板引擎 + 修改配置一起,于是就可以愉快的使用后缀为tmpl的模板引擎了。
app.engine('tmpl', function(filepath, options, callback){  

  // 参数一:渲染过程的错误,如成功,则为null
  // 参数二:渲染出来的字符串
  return callback(null, 'Hello World');
  
});
  
app.set('views', './views');
  
app.set('view engine', 'tmpl');

相关链接
  模板引擎对比:点击这里
  express模版引擎介绍:点击这里
  开发模版引擎:点击这里

更多内容
  前面讲了一些express的入门基础,感兴趣的同学可以查看官方文档。篇幅所限,有些内容在后续文章展开,比如下面列出来的内容等。


  • 进程管理
  • 会话管理
  • 日志管理
  • 性能优化
  • 调试
  • 错误处理
  • 负载均衡
  • 数据库支持
  • HTTPS支持
  • 业务实践
  • 。。。
相关链接
  express官网:http://expressjs.com/
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-346960-1-1.html 上篇帖子: Nwjs从入门到精通 菜鸟实践笔记【1】 下篇帖子: 彻底弄懂CommonJS和AMD/CMD!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表