####我是主攻后端的开发人员,但是项目人手紧缺,我的经历刚好是做过node.js后端,所以我们前后端的分离工作就交到我的头上来了,这次我们采用node.js。前端的使用和后端果然还是很多不同的。
####node.js在系统中处的作用我的理解就是分离前后端,后端更多提供一个数据服务,传统的后端可能就是MVC,在我看来C就是控制器,主要的工作就是在参数的校验和数据与视图的整合。这个部分是可以交给前端去做的,让后端与视图分离开。
####现在项目中就是页面直接存放在tomcat的webapps下面,这样前端的稍微改动都要整个项目去上线,这样牵扯的东西太多。因此node.js也给前端更多的控制权。不用什么请求都落到后端应用服务器,很多请求在node.js就可以被过滤,因此也可以阻挡一些流量,保证了后端服务器的负载。
####搭建前端的node.js我使用了比较流行的框架,这两年Github上javascript的库层出不穷,npm包管理器给node.js的安装也提供了很多便利。我使用了express去提供路由,页面渲染也选择express支持较好的ejs。
####脚本语言就是文件的执行,解释执行是一个比较大的特点,node.js很好的把很多功能封装成模块,因为node.js对OO的支持并不是那么好,所以我尽量不去用一些utils.herits等等方法去实现原型链的继承。
####首先要建立好node.js目录,分为两个大的部分,静态资源和请求的路由处理。我分别起名route和view,有的叫controller或则public等等,route就是接收请求的处理,并把数据和网页模板等结合起来输出给用户,然后需要启动文件,初始化一些组件,我起名app.js.还有一些工具类或则配置。我用的utils和config,网上貌似也有工具直接可以初始化node.js目录。
####这就是我创建的目录:
####首先我们编写app.js加载整个项目需要的组件:
// 定义全局变量
global.root = __dirname
// 依赖模块
var express = require('express')
var body_parse = require('body-parser')
var path = require('path')
var router = require('./routes/route.js')
var cookies_parser = require('cookie-parser')
// 初始化句柄
var http = require('http')
var app = express()
var ejs = require('ejs')
// 配置
var conf = require('./config/api')
// 设置监听端口
app.set('port',conf.node_port || 3000)
app.set('views',__dirname + "/views/page")
// 模版引擎 这里指定默认文件后缀,如果不是html需要指定具体后缀
app.set('view engine','ejs')
//加载环境变量
app.use(body_parse.urlencoded({ extended: false }));
app.use(cookies_parser());
app.use(express.static(path.join(__dirname,'/views')));
//启动及端口
http.createServer(app).listen(app.get('port'),function(){
console.log('server started, listen port : ' + app.get('port'));
});
// 路由
router(app)
//加载错误处理解决办法
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
//导出app对象
module.exports = app;
####我在很多文件需要引用项目当中其他模块,当然写相对路径是没问题的,但是node.js提供了全局变量global,我打算放一个根目录的路径进去,照样可以实现功能的,__dirname是node.js内置的变量,是获取当前文件的执行路径。
路由部分
####express模块是封装了node.js原生的http请求,我希望的是一个逻辑对应一个子路由文件,例如用户逻辑,但是我希望app.js里引入路由是一个简单的“总“路由,因此采用这样的结构:
其中一个子路由:
var http = require('http')
var http_utils = require('../utils/http_utils')
var conf = require('../config/api')
var host = conf.java_server.host;
var port = conf.java_server.port;
module.exports = function (app) {
// get请求
app.get('/',function(req,res) {
// get请求
var get_params = req.query;
console.log(JSON.stringify(get_params));
// 第二种获取方式
console.log(JSON.stringify(req.params));
})
app.post('/',function(req,res) {
// post请求
var post_params = req.body;l
console.log(JSON.stringify(post_params));
res.render("users/demo", {title : "this is title data"});
})
}
####任何一个请求进来都会遍历所有路由像一个链路一样。路由就这样获取到请求,并且主要做两件事情,一是组织数据,无论是从后端服务器还是其他地方。第二就是找到页面并渲染。这里页面采用
res.render("page",{title : data});
####就是找到page页面,并且将title数据替换成data。title是模板中的占位,data是我们获取到的数据。至于page完整的路径是在app.js 中指定。
app.set('views',__dirname + "/views/page")
这样设置之后,框架会自动去寻找__dirname/views/page/下面的对应的页面。
静态资源部分
####这里放页面文件和静态的css和js文件。由于在app.js配置了路径:
app.use(express.static(path.join(__dirname,'/views')));
####在页面引用资源也可以写css/test.css。这样就可以不用去写相对路径。
####ejs模版展示部分网上也有相关的文档语法,就不废话了,据说根php的语法类似。
工具部分
####可以把公用的常用的东西封装成工具,例如获取后端服务器的地址。同步发送http请求等等,关于node.js的IO模型为异步非阻塞,我同步的发送http不知道会不会引起一些问题。我采用的sync-request模块。还有promise-request co等工具。有时间再去研究。这次本来打算用vue.js来处理页面相关的数据,但是时间紧迫没去研究。
相信把后端独立出来之后后面前端也可以单独的改造,后端更多关注业务逻辑的实现。前端更多关注视图的变化,这次的迁移也只要把请求后端的接口放在路由去,页面处理下展示即可,代码得到最大程度的复用。
看了此篇文章是不是感觉收获蛮大