NodeJS安装配置及Express基本介绍

Node.js简介

简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。

1
2
3
安装环境
本机系统:Windows 7
NODEJS版本:node-v10.14.0-x64

步骤

1
2
3
4
1、下载对应你系统的Node.js版本:https://nodejs.org/en/download/
2、选安装目录进行安装
3、环境配置
4、测试

下载

安装

Windows上安装时务必选择全部组件,包括勾选Add to Path,更改自己需要的安装目录。

安装完成后安装目录有nodejs的文件:

测试安装是否成功了:【win+R】键,输入cmd,然后回车,打开cmd窗口。

分别输入:

1
2
node -v
npm -v

显示出版本信息,说明安装成功!

NPM

npm是什么?

npm是Node.js的包管理工具(package manager)。npm的作用就是对Node.js依赖的包进行管理,也可以理解为用来安装/卸载Node.js需要装的东西,在Node.js上开发时,会用到很多别人写的JavaScript代码包。如果我们要使用别人的包,每次都要去搜索——下载——解压——使用,这样非常麻烦。于是出现了这个集中管理的工具,大家都把自己开发的模块打包后放到npm官网上,如果别人需要,直接通过npm安装就可以使用了。
npm还可以根据包的依赖关系,把所有依赖的包都下载并管理起来。新版的Node.js已自带npm,安装Node.js时会一起安装。

配置

主要配置的是npm安装的全局模块所在的路径,以及缓存cache的路径。是因为以后在执行类似:npm install express [-g](后面的可选参数-g,g代表global全局安装的意思)的安装语句时,会将安装的模块安装到【C:\Users\用户名\AppData\Roaming\npm】默认路径中。

将全模块所在路径和缓存路径放在我node.js安装的文件夹中,再安装目录下创建两个文件夹【node_global】及【node_cache】:

创建完两个空文件夹之后,打开cmd命令窗口,输入:

1
2
npm config set prefix "XXXXXX\nodejs\node_global
npm config set cache "XXXXX\nodejs\node_cache

XXXXX是你nodejs文件路径

设置环境变量

  window7等老版本windows的编辑环境变量的方式,很麻烦,一不小心,漏了个分号,都会弄得自己怀疑人生。

  下载了 Rapid Environment Editor 这个小工具,就可以很方便的在window7及以下版本编辑环境变量了。

  下载地址:https://www.rapidee.com/en/download 按计算机是32还是64位下载对应版本

打开软件

【系统变量】下右键新建一个变量【NODE_PATH】,值为C:\AdministratorProgramFiles\nodejs\node_modules

【用户变量】下的【Path】中的这一项C:\Users\用户名\AppData\Roaming\npm 修改为C:\AdministratorProgramFiles\nodejs\node_global

配置完后,安装个module测试下,我们就安装最常用的express模块,打开cmd窗口,
输入如下命令进行模块的全局安装:

npm install express -g# -g是全局安装的意思

安装完成后可以看到C:\AdministratorProgramFiles\nodejs\node_global\node_modules下有express模块

测试

此时,nodejs安装环境配置完毕,由于nodejs是运行在服务端的,所以编写的JavaScript代码将不能在浏览器环境中执行了,而是在Node环境中执行。

因此,JavaScript代码将直接在你的计算机上以命令行的方式运行,所以,我们要先选择一个文本编辑器来编写JavaScript代码,并且把它保存到本地硬盘的某个目录,才能够执行。

 用电脑上安装的编辑器编写代码测试。我用Notepad++,注意用UTF-8格式保存。

输入以下代码:

1
console.log('Hello, world!');

第一行写上'use strict',是因为我们总是以严格模式运行JavaScript代码,避免各种潜在陷阱。

然后,选择一个目录保存为helloworld.js,必须要以.js结尾,就可以打开命令行窗口,把当前目录切换到helloworld.js所在目录,运行这个程序:

1
2
G:\NodeJs node helloworld.js
Hello, world!

至此,NodeJS下载安装配置环境,测试都完成。

Express

Express是基于Nodejs的官方Web开发库,每年升级一个大版本,在Express4时,替换掉中件间库connect,而改用多个更细粒度的库来取代。
首先,我们需要安装express库。在Express3.6.x之前的版本,Express需要全局安装的,项目构建器模块是合并在Express项目中的,后来这个构建器被拆分出来,独立成为了一个项目express-generator,现在我们只需要全局安装express-generator项目就行了。

1
npm install -g express-generator@4  #全局安装-g

安装后可以看到全局模块:

IDE工程结构

使用WebStorm创建一个基于Express项目:

目录结构:

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

package.json项目配置

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"name": "express-study",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1",
"pug": "2.0.0-beta11"
}
}

app.js核心文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 加载依赖库,原来这个类库都封装在connect中,现在需地注单独加载
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

// 加载路由控制
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

// 创建项目实例
var app = express();

// 定义pug模板引擎和模板文件位置,也可以使用ejs或其他模型引擎
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

// 定义日志和输出级别
app.use(logger('dev'));
// 定义数据解析器
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// 定义cookie解析器
app.use(cookieParser());
// 定义静态文件目录
app.use(express.static(path.join(__dirname, 'public')));

// 匹配路径和路由
app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});


// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

// 输出模型app
module.exports = app;

www文件也是一个node的脚本,用于分离配置和启动程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env node

/**
* Module dependencies.
* 加载依赖
*/

var app = require('../app');
var debug = require('debug')('express-study:server');
var http = require('http');

/**
* Get port from environment and store in Express.
* 定义启动端口
*/

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* Create HTTP server.
* 创建HTTP服务器实例
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
* 启动网络服务监听端口
*/

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
* 端口标准化函数
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
* 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;
}
}

/**
* Event listener for HTTP server "listening" event.
* 事件绑定函数
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

运行浏览:

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

header.ejs, 为页面的头部区域

1
2
3
4
5
6
7
8
<!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>

index.ejs, 为内容显示区域

1
2
3
4
5
6
7
8
<% include header.ejs %>

<div class="well jumbotron">
<h1><%= title %></h1>
<p>hello</p>
</div>

<% include footer.ejs %>

footer.ejs,为页面底部区域

1
2
3
4
<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>

路由功能

路由功能,是Express4以后全面改版的功能。在应用程序加载隐含路由中间件.

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

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

1
2
3
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’));