当前位置:   article > 正文

node+express 的前后端分离项目

node+express

        早就听说nodejs功能强大,前后端都涉及的到,尝试学习一下如何利用node去搭建后端项目。nodejs是express的基础,最好先去了解一下nodejs的大概功能。

一、Express项目搭建

        假设已经安装了node。
        搭建express后端项目有两种方式,第一种就是直接安装express然后去一步一步搭建,第二种则是最为简便的使用express项目生成器,就是express项目脚手架,他会为你自动创建后端所需要的内容,比如路由、http、path以及中间件。
先来了解一下第二种方法

Express-Generator项目生成器

        通过应用生成器工具 express-generator 可以快速创建一个应用的骨架。

//全局安装express项目生成器
npm install -g express-generator
//使用命令创建express项目
express --view=pug myapp
  • 1
  • 2
  • 3
  • 4

        express命令
        以下是项目目录结构

├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

运行项目

 set DEBUG=myemplyservice:*; npm start 
  • 1

        接下来就可以访问项目:localhost:3000
在这里插入图片描述

目录结构详情

bin/www文件

        文件 /bin/www 是应用入口,它做的主要内容就是 引入app.js 并创建HTTP服务器。
        下面摘自www文件

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('myemplyservice: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.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

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

....
  • 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

app.js

        此文件创建一个 express 应用对象,通过各种设置选项和中间件来设置这个应用,然后从该模块中导出。以下代码只展示了文件中创建和导出应用对象的部分

var express = require('express');
var app = express();
...
module.exports = app;
  • 1
  • 2
  • 3
  • 4

        上文的 www 入口文件中 require() 的 app 就是这里导出的 。

        我们来详细了解一下 app.js 文件。首先,它使用 require() 导入了一些实用 node 库,其中包括之前用 NPM 下载的 express,http-errors,morgan 和 cookie-parser,还有一个 path 库,它是用于解析文件和目录的核心 node 库。

var express = require('express');
var createError = require('http-errors');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var path = require('path');
  • 1
  • 2
  • 3
  • 4
  • 5

        下面的 require() 的是用户路由目录中的模块。这些模块/文件用于处理特定的“路由”(URL 路径)。可以通过添加新文件来扩展骨架应用,比如添加图书相关的路由来列出所有馆藏书目。

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
  • 1
  • 2

注意: 此时我们刚刚导入了模块;还没有真正使用过其中的路由。
现在把(之前导入的)路由处理器添加到请求处理链中。

app.use('/', indexRouter);
app.use('/users', usersRouter);
  • 1
  • 2

注意:这些路径(‘/’ 和 ‘/users’)将作为导入路由的前缀。如果导入的模块 users在/profile 定义了路由,则可以在 /users/profile 访问该路由。我们将在后面的文章中,详细讨论路由。

处理请求(有必要了解一下路由)

        这里就简单了解一下路由是做什么的,express路由是指应用程序的端点 (URI) 如何响应客户端请求。例如,app.get()处理 GET 请求和app.post处理 POST 请求。
        路由文档 /routes/users.js 如下所示(由于路由文件均使用类似结构,所以 index.js 略过不讲)。首先加载 express 模块​​并获取 express.Router 对象(命名为 router)。然后为 router 指定路由,最后导出 router(就可以导入 app.js 了)。
        下面的代码是一个非常基本的路由示例。

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

// respond with "hello world" when a GET request is made to the homepage
app.get('/', function (req, res) {
  res.send('hello world')
})

module.exports = router;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

views视图模板

        视图(模板)存保存在 /views 目录中( app.js 中指定),使用 .pug 扩展名。Response.render() 方法用某对象的某个变量值一同来渲染一个特定的模板,然后将结果作为响应发送。在 /routes/index.js 中可以看到,该路由使用 ‘index’ 模板和一个模板变量 title 来渲染响应。

/* GET home page. */
router.get('/', function(req, res) {
  res.render('index', { title: 'Express' });
});
  • 1
  • 2
  • 3
  • 4

        以下是上文代码中涉及到的模板(index.pug)。pug 语法稍后再详细讨论。现在只需要知道:title 变量将以 ‘Express’ 作为值插入模板的指定位置。

/*index.pug*/
extends layout

block content
  h1= title
  p Welcome to #{title}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

热部署

        本身express是没有热部署的,这里不再解释什么是热部署了哈,开搞~
nodemon 是最简便的自动化工具之一。通常将其全局安装(因为它是一个“工具”):

$ sudo npm install -g nodemon
  • 1

        这里还可以把它作为开发依赖将安装在本地,于是使用这个项目的开发人员只要安装这个应用就能自动获得。通过以下命令将其安装在骨架项目的根目录:

$ npm install --save-dev nodemon
  • 1

        项目的 package.json 文件将自动添加一个新的属性:

"devDependencies": {
    "nodemon": "^1.18.9"
}
  • 1
  • 2
  • 3

        如果没有全局安装该工具,就无法从命令行启动它(除非我们将其添加到路径中),但是可以在 NPM 脚本中调用它,因为 NPM 掌握所有已安装包的信息。找到 package.json 的 scripts 部分。在 “start” 一行的末尾添加逗号,并在新的一行中添加 “devstart”,如下所示:

 "scripts": {
    "start": "node ./bin/www",
    "devstart": "nodemon ./bin/www"
  },
  • 1
  • 2
  • 3
  • 4

        现在可以用新建的 devstart 命令启动服务器:

//我创建的项目名称为myemplyservice
$ set DEBUG=myemplyservice:*; npm run devstart
  • 1
  • 2

        现在,如果编辑项目中的任何文件,服务器将自动重启。查看更新后的页面需要点击浏览器的“刷新”按钮。

注:这里必须使用“npm run ”命令,而不是 npm start,因为 “start” 本质上是映射到脚本的一条 NPM 命令。我们可以在 start 脚本中替换它,但我们只想在开发期间使用 nodemon,因此有必要创建一条新的脚本命令。

以上内容参见mdn-web-doc Express网页框架(node/JavaScript)

二、添加路由和控制器

路由器(Router)和控制器(Controller)

        路由器:处理请求
        控制器:请求转发到合适的控制器,由控制器进行数据读取,视图转发或响应。

定义和使用单独路由模块

  • 定义路由
/*
	/routes/myRouter.js
*/
var express = require("express")
var router = express.Router()

//处理登录请求
/*
	req:{
		...
		body:{
			mes:"登录"
		}
		...
	}
*/
router.post("/login",(req,res)=>{
	req.json({
		mes:req.body.mes+"成功"
	})
})


//另外访问http://localhost:3000/users/34/books/8989,可以这样提取信息(使用 userId 和 bookId 路径参数):
router.get('/users/:userId/lib/:bookId', (req, res) => {
  // 通过 req.params.userId 访问 userId
  // 通过 req.params.bookId 访问 bookId
  res.send(req.params);
});



//导出router
module.exports = router;
  • 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
  • 使用路由
/*
	app.js
*/
//引入express和刚刚写的myRouter模块
var express = require("express")
var myRouter = require("./routes/myRouter.js")

var app = express();
//使用myRouter模块路由
app.use("/myRouter",myRouter)
//当用post方式访问localhost:3000/myRouter/login时携带mes参数即可
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 创建控制器
/*
	根目录下创建controllers/loginController.js
*/
//处理登录操作
exports.employee_login=(req,res)=>{
	res.json({
		mes:"登录成功"
	})
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

        在router处理Controller

/*myRouter*/
//引入控制器	
var loginController=require("../controllers/loginController.js")
//使用控制器
router.post("/login",loginController.emplyee_login)
  • 1
  • 2
  • 3
  • 4
  • 5

        基本操作大概就是这样,后端数据暂时使用模拟数据,从json文件中读取、添加、修改等方式,所以要用node的fs模块。

三、仿数据库之json

        到此为止呢,express基本操作已经完成(能跑起来并成功运行),那么就要开始涉及到数据库的内容了,既然是仿数据库,那么就没必要想太多,只要前端拿到数据就行,所以我采用文件读取的方式直接给前端返回想要的数据,所以必不可少使用node的fs模块。

fs的使用

        我只说怎么使用,具体情况具体分析,我现在只想读取json文件内容。

//loginController.js
var {readFileSync} = require("fs")

//读取用户信息
var readUsers = (userid) => {
	return new Promise((resolve,reject)=>{
		try {
			//读取所有用户数据
			var users = readFileSync('./entry/user/users.json', 'utf8')
			users = JSON.parse(users)
			//判断是否读取到
			if(users.data.length==0) resolve({}) 
			var user = users.data.filter(v=>v.userid==userid)[0]
			resolve(user )
		} catch (e) {
			//TODO handle the exception
			reject(e)
		}
	})
}

exports.employee_login=>(req,res){
	//...其他内容
	readUsers(req.body.userid).then(user=>{
		console.log(user)
	}).catch(err=>{
		console.log(err)
	})
	//...
}


  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/120284?site
推荐阅读
相关标签
  

闽ICP备14008679号