前言
使用webstorm搭建Node.js应用更加方便。
1、下载WebStorm,并安装
2、创建Node + Express应用
(1)方法一:直接使用CMD命令提示符
创建步骤见上一篇博客:https://blog.csdn.net/kingshown_WZ/article/details/89286435。可以使用webstorm软件直接加载生成的工程目录根目录,即可将工程加载到该环境中。
(2)方法二:使用webstorm软件
3、Project目录结构
app.js:启动文件,或者说入口文件
package.json:存储着工程的信息及模块依赖,当在 dependencies 中添加依赖的模块时,运行 npm install ,npm 会检查当前目录下的 package.json,并自动安装所有指定的模块
node_modules:存放 package.json 中安装的模块,当你在 package.json 添加依赖的模块并安装后,存放在这个文件夹下
public:存放 image、css、js 等文件
routes:存放路由文件
views:存放视图文件或者说模版文件
bin:存放可执行文件(www)
4、各个主要文件的说明
(1)app.js
//加载模块
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 index = require('./routes/index');
var users = require('./routes/users');
// 生产一个express的实例
var app = express();
// view engine setup
/*
设置 views 文件夹为存放视图文件的目录,
即存放模板文件的地方,__dirname 为全局变量,
存储当前正在执行的脚本所在的目录。
*/
app.set('views', path.join(__dirname, 'views'));
//设置模板引擎为ejs
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
//加载日志中间件
app.use(logger('dev'));
//加载解析json的中间件
app.use(bodyParser.json());
//加载解析urlencoded请求体的中间件。 post请求
app.use(bodyParser.urlencoded({extended: false}));
//加载解析cookie的中间件
app.use(cookieParser());
//设置public文件夹为放置静态文件的目录
app.use(express.static(path.join(__dirname, 'public')));
// 路由控制器。
app.use('/', index); // http://localhost:3000
app.use('/users', users); //http://localhost:3000/users
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 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导出。 别的地方就可以通过 require("app") 获取到这个对象
module.exports = app;
(2)bin/www
#!/usr/bin/env node //表明是node可执行文件
/**
* Module dependencies.
*/
//引入我们在app.js中导出的app模块
var app = require('../app');
//引入debuger模块,打印调试日志
var debug = require('debug')('hello:server');
//引入http模块
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);
//监听error事件。 onError是发生错误的时候的回调函数
server.on('error', onError);
//监听listening事件
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.
*/
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);
}
(3)routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: '育知同创' });
});
module.exports = router;
/*
生成一个路由实例用来捕获访问主页的GET请求,
导出这个路由并在app.js中通过app.use('/', routes);
加载。这样,当访问主页时,就会调用res.render('index', { title: '育知同创' });
渲染views/index.ejs模版并显示到浏览器中。
*/
(4)对路由写法的优化
在前面的==app.js中==,每个模板都有添加一次路由比较麻烦,其实应该把添加路由的事情专门交给index.js来做。也就是可以把多个路由放在一个路由文件中。
//加载路由文件
var index = require('./routes/index'); //去掉
var users = require('./routes/users'); //去掉
// 路由控制器。
app.use('/', index); // http://localhost:3000 //去掉
app.use('/users', users); //http://localhost:3000/users //去掉
可以改成:
var routes = require('./routes/index');
routes(app);
==index.js==文件优化成: 这样管理起来就方便很多
module.exports = function (app) {
//一个get请求的路由 http://localhost:3000
app.get("/", function (req, res) {
res.render("index", {title:"育知同创abc"})
});
//又一个请求路由:http://localhost:3000/abc
app.get("/abc", function (req, res) {
res.render("index", {title:"育知同创" + req.path})
});
}
(5)ejs模板
模板引擎(Template Engine)是一个将页面模板和要显示的数据结合起来生成 HTML 页面的工具。如果说上面讲到的 express 中的路由控制方法相当于 MVC 中的控制器的话,那模板引擎就相当于 MVC 中的视图。
模板引擎的功能是将页面模板和要显示的数据结合起来生成 HTML 页面。它既可以运 行在服务器端又可以运行在客户端,大多数时候它都在服务器端直接被解析为 HTML,解析完成后再传输给客户端,因此客户端甚至无法判断页面是否是模板引擎生成的。有时候模板引擎也可以运行在客户端,即浏览器中,典型的代表就是 XSLT,它以 XML 为输入,在客户端生成 HTML 页面。但是由于浏览器兼容性问题,XSLT 并不是很流行。目前的主流还是由服务器运行模板引擎。
在 MVC 架构中,模板引擎包含在服务器端。控制器得到用户请求后,从模型获取数据,调用模板引擎。模板引擎以数据和页面模板为输入,生成 HTML 页面,然后返回给控制器,由控制器交回客户端。
==ejs 是模板引擎的一种,它使用起来十分简单,而且与 express 集成良好。==
我们通过以下两行代码设置了模板文件的存储位置和使用的模板引擎:(app.js文件中进行的设置)
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
<%= title %>
<%= title %>
Welcome to <%- title %>
说明
ejs 的标签系统非常简单,它只有以下三种标签:
<% code %>:JavaScript 代码。
<%= code %>:显示替换过 HTML 特殊字符的内容。(也就是说如果code中有标签,则会原样输出,不会让浏览器解析)
<%- code %>:显示原始 HTML 内容。(如果有a标签,在浏览器端这则会看到一个超链接)
路由代码:
router.get('/', function(req, res, next) {
res.render('index', { title: "百度 "});
});
// 则会用title的值去替换ejs中的相应的代码。
则生成的代码:
<a href='http://www.baidu.com'>百度 </a>
<a href='http://www.baidu.com'>百度 </a>
Welcome to 百度