给小白的Expressjs4教程

本教程是给nodejs和Expressjs的小白们写的。Expressjs是一个基于nodejs的开发框架,现在大热的MEAN站点开发技术栈,的E就是Expressjs。说到Expressjs就不能不说这个在nodejs界影响巨大的框架的作者TJ Holowaychuk。几乎三成以上的nodejs社区代码都是这位仁兄贡献的,甚至有人怀疑他不是一个人在战斗。。。但是,无论如何,要用nodejs写web站点都离不开他的拥有或参与的nodejs库。实在是一位值得膜拜的代码英雄。这位英雄酷爱摄影,这里是他的影展站点。

本来nodejs做站点很多都是用jade作为生成html页面的模板。这里为了简单,并且突出主要内容expressjs,就直接使用html页面了。

现在开始

最开始莫过于是安装nodejs了。毕竟,expressjs是运行在nodejs之上的,没有nodejs什么都无从谈起。nodejs在这里下载。只需要下载并安装对应于你的系统的版本就可以。之后安装。

开发工具具体用什么,有很大的空间。本人比较喜爱使用Sublime。也有人使用Intellij的WebStorm,这个比较重型一些,但是也在某些地方方便很多。还有其他比较轻量级的Visual Code。都可以使用,看个人的爱好。

一、合适的目录结构

在正式开始编写代码以前,需要有一个结构良好的项目目录结构。这非常重要,如果你不知道运行什么功能的代码存放在什么地方,什么时候这个文件的什么方法会被调用到,那么你对项目的理解就非常的欠缺了。那么首先创建一个存放你的应用的文件夹,并跳转到这个目录下

这里有一个项目的目录结构:

|__node_modules
|__routers
        |__main.js
|__views
       |__index.html
       |__about.html
|__package.json
|__app.js

你可能会问,这些我都要创建吗?也是,也不是。接续往下读你就会清楚了。

二、创建package.json文件

在这个文件中会包含你expressjs应用的全部信息。比如,这个应用的名称、版本、描述等内容,项目不同这些也会有些不同。

这些内容中最重要的就是依赖项(dependencies)。这些依赖项是应用运行起来所不可或缺的。但是package.json文件并不用我们去手动创建。打开终端,并跳转到你刚刚为这个应用创建的目录下。运行命令:

$ npm init

命令中会跳出很多的需要你输入的东西。依次输入,或者对于我们的教程来说直接回车也可以。但是,有一点例外,在出现

entry point: (index.js)

的时候把文件名改为app.js,或者随便你喜欢的名字都可以。或者你觉得index.js也可以的话,就直接回车。但是我们在后面用到的这个文件都叫做app.js。

对于我们今天的主角expressjs来说,可以使用nodejs提供的包管理工具来完成安装。只需要一个命令就可以完成,非常的简单。

$ npm install express --save

命令之后打开package.json文件看看:

{
  "name": "express-web-app",
  "version": "1.0.0",
  "description": "Just a blogging platform.",
  "author": "uncle charlie",
  "dependencies": {
    "express": "^4.13.4"
  }
}

注意:在填写名称的时候不能包含空白,比如“express web app”。即使是“express-web-app”或者“express_web_app"这样也是可以的。还有一点,在依赖项的版本号前面的那些特殊的符号除了^还有其他。我们来看看这些特殊符号的含义:

  • “^” 是指匹配全部4.x.x的版本,一直到5.0.0(不包括)。
  • “~” 是指匹配全部2.4.x的版本,一直到2.5.0(不包括)。
    更多内容对于版本的指定,可以参考官网

我们继续使用npm安装其他的依赖项,ejsmysql

$npm install mysql --save

$npm install ejs --save

最后等待全部的依赖项都安装完成。还有一种完全没有什么必要的安装依赖项的方法,就是在npm init命令生成package.json文件之后,自己编辑这个文件,添加依赖项。最后执行npm install命令。不过这样没有什么必要。npm才是管理依赖包的,我们去手动编辑package.json文件就违背了nodejs使用npm包管理工具的初衷。只有在项目下已经存在package.json文件,而对应的依赖项还没有下载到本地的情况下才直接使用npm install安装

三、创建Express的服务器(server)

我们需要的依赖项都已经安装好了,也创建了package.json文件。现在就该正式的进入正题,创建一个Express的server来响应各种用户请求了。前文中在执行npm init命令的时候已经生成了app.js文件。现在打开这个文件。输入如下的代码:

var express = require("express");
var app = express();
var server = app.listen(5566, function(){
    console.log("Server is running on http://localhost:5566");
});

在终端中执行命令node app.js。这里node后面跟你使用的文件的名称。在浏览器中输入地址http://localhost:5566并回车,你会发现已经可以访问这个server了,虽然还是一点小小的瑕疵。这个瑕疵主要是因为我们还没有在server里没有提供路由(router)的功能。

四、添加路由

我们的server已经准备好了。现在我们就来处理路由(router)的问题。

var express = require("express");
var app = express();
// *
app.get('/', function(req, res){
    res.send("Hello World!");
});

var server = app.listen(5566, function(){
    console.log("Server is running on http://localhost:5566");
});

加星注释的那句就是我们添加的路由功能的代码。方法get表明处理的是用户的GET请求。后面的function(req, res){res.send("Hello World!"}输出响应的内容,这里是一个全世界最著名的计算机字符串“Hello World”。

用户的响应只是一个字符串是远远不够的,按照上文中介绍目录结构的时候提到的,给views目录添加文件index.html和about.html。并分别给这两个文件添加内容:

<!-- index.html -->
<html>
    <head>
    </head>
    <body>
        <header>
            <h3>HOME</h3>
        </header>
    
    </body>
</html>

<!-- about.html -->
<html>
    <head>
    </head>
    <body>
        <header>
            <h3>ABOUT</h3>
        </header>
    
    </body>
</html>

添加的内容非常简单,只是为了区分是哪个页面被打开了。

如何显示这两个页面呢?这就回到刚刚我们讨论的问题上了,修改路由。

app.get('/', function(req, res){
    res.render('index.html');
});

app.get('/about', function(req, res){
    res.render('about.html');
});

用上面的代码替换掉最开始使用的示例路由代码,然后重新运行node app.js命令。额……你会发现会报错。是的,以后这样的事情还会经常发生的。查看报错的内容:

Error: Cannot find module 'html'
    at Function.Module._resolveFilename (module.js:337:15)
    at Function.Module._load (module.js:287:25)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at new View (/Users/uncle_charlie/Documents/Dev/Test/js_test/js_server/node_modules/express/lib/view.js:78:30)

主要是因为没有对应的处理模块,所以无法正确的render渲染html文件。这时候就需要用到处理视图的模块ejs了。增加ejs的设置代码:

var express = require("express");
// 1
var ejs = require('ejs');  

var app = express();

// 2
app.set('view engine', 'ejs');
// 3
app.engine('html', ejs.renderFile);

// 以下代码不动,这里省略……

上面的修改主要有:

  1. 引入了ejs模块。
  2. 设定应用的视图引擎(view engine)为ejs
  3. 设定在处理HTML文件的时候使用ejs来渲染文件。

run起来我们的应用。效果如下:


在浏览器中输入地址http://localhost:5566/about你看到的就是ABOUT页面了。

五、重构代码

看起来是so far so good了。但是这是不够的。对于产品级的Express应用来说会有很多的代码。其中只路由的部分的代码就会非常之多。对于后期添加或者删除功能,修改bug都会造成很大的问题。所以,从现在开始我们就应该养成一个保持代码整洁的好习惯。这样是编程水平的反应。

下面我们就把路由的代码从app.js文件中移出去。在上文提到的目录结构中添加一个mainRouter.js的问题件来存放我们从app.js中移出来的路由部分代码:

var router = function(app){
    app.get('/', function(req, res){
        res.render('../views/index.html');
    });

    app.get('/about', function(req, res){
        res.render('../views/about.html');
    });
};

exports.router = router;

最后的一句是说,这部分的代码是要作为模块给其他部分的代码使用的,所以需要使用系统提供的exports对象来“发布”这里的代码。在app.js中使用require关键字来引入路由模块的代码。

var routers = require('./routers/mainRouter');

引入一个本地模块只需要知道路径就可以了。使用npm安装到本地的,或者nodejs系统内置的模块只需要require方法中使用模块本身的名字就可以,不需要路径。完整代码:


var express = require("express");
var ejs = require('ejs');
var routers = require('./routers/mainRouter');

var app = express();

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

// routers
routers.router(app);
// app.get('/', function(req, res){
//     res.render('index.html');
// });

// app.get('/about', function(req, res){
//     res.render('about.html');
// });

// server
var server = app.listen(5566, function(){
    console.log("Server is running on http://localhost:5566");
});

实践是检验真理的唯一标准。运行一下看看吧。

stay tunned to my next episode

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容

  • 搭建开发环境并模拟交互数据 一、实验说明 下述介绍为实验楼默认环境,如果您使用的是定制环境,请修改成您自己的环境介...
    玄月府的小妖在debug阅读 2,122评论 0 15
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,988评论 25 707
  • Express是Node社区里的超级明星,他的作者TJ Holowaychuk也因此成为了社区里大红大紫的开发者。...
    2MuchT阅读 2,997评论 1 30
  • Twitch 商城网站 介绍: 1、Node.js搭建的网站,采用Mongodb数据库2、后台框架 借用了 exp...
    Junting阅读 908评论 0 0
  • 过年前就定(chui)下了目(niu)标(bi),今年要学习一下Scala和Spark赶一下潮流。谁叫落后就要挨打...
    fengzhizi715阅读 3,810评论 1 2