(故事纯属虚构,若有雷同,纯属巧合)传说在好久好久之前,咱们有志之士有了个创业的想法,因而乎开始了本身的创业之梦,可是人手不足啊,因而乎全部角色老子一我的全包了:javascript
咱们用 express 应用生成器来模拟一下传统开发(由于本人早已忘记java是怎么写的了,这里只是为了方便演示)php
$ npm install express-generator -g # 安装 express-generator $ express progressive # 初始化项目 $ cd progressive # 进入目录 $ npm install # 安装依赖 $ npm start # 启动项目
而后咱们愉快的打开了 localhost:3000 看到了咱们的页面:html
接着,我看是研究代码:
发现个人模板引擎用的是 jade 是经过 nodejs 服务端进行动态渲染:前端
// app.js app.set('view engine', 'jade');
而后当我访问 localhost:3000 的时候,开始了界面渲染:vue
// routers/index.js router.get('/', function(req, res, next) { // 假设这里我为了获取 title 的值,对 sql 进行了查询,而后把title的值插入到模板引擎中 ... res.render('index', { title: 'Express' }); });
而后我又研究了一下 jade 语法,准备后续的开发:java
// index.jade extends layout block content h1= title p Welcome to #{title}
紧接着咱们开始了后续的开发....通过几个月,咱们写了sql,写了 jade, 写了node .... 。作了PM,作了DBA, RD ....终于一个项目搞完了。而后我愉快的拿到了投资人的投资,有钱了,项目迭代总不能什么事情都是我一我的干吧?我能够找几我的一块儿来开发嘛,因而乎,我招聘了前端,招了后端,招了 PM ....
后面的开发愉快且开心的打开了个人代码:node
...... WTF 是谁把手套放进锅子里面煮...jquery
在发现问题以后,为了更好的脱离这种前端强依赖后端的关系,咱们想要把数据层的接口给分离出来,以 ajax 的形式进行交互,让服务端只负责渲染逻辑,不负责数据填充。页面的数据部分经过 ajax json 的形式形式进行交互,因此咱们的结构多是这样子:ios
因此如今个人页面请求逻辑是这样子的:git
// routers/index.js router.get('/', function(req, res, next) { res.render('index'); }); router.get('/getTitle', function(req, res, next) { res.json({ code: 0, msg: 'success', data: 'express' }) });
在页面新建 index.js:
ajaxGet('/getTitle', function (err, res) { $('#title').text('welcome to ' + res.data); });
重构 index.jade
extends layout block content h1= title p#title append scripts script(src='/javascripts/jquery.min.js') script(src='/javascripts/index.js')
这样便完成了先后端数据交互层的问题。but:先后端的界限是按照浏览器和服务器的划分。那么咱们常常会发现一些问题:
那么,做为前端开发的咱们在实际的开发场景中又会遇到如下问题:
出现影响开发效率的事情,就说明现有的模式仍是存在问题,显然问题的解题思路须要咱们从新思考“先后端”的定义。
为了更高的提升开发效率,咱们的前端 MV* 时代开始到来:
先后端数据经过JSON进行交互,彼此互相不关联,接口分离,后端提供数据便可,前端本身搞。MODEL层 - JAVASCRIPT OBJECT,VIEW层 - JAVASCRIPT TEMPLATE。业界也充满了新的解决方案好比: Backbone, EmberJS, KnockoutJS, AngularJS, React, Vue...
因而乎咱们开始了新的旅途:MVVM 的单页面开发:
咱们把服务层抽出来,最终造成的目录结构多是这样的:
咱们的服务端提供接口和前端进行交互:
// routers/users.js let express = require('express'); let router = express.Router(); let usersCtrl = require('../controllers/usersCtrl') router.post('/login', usersCtrl.login) router.post('/sign', usersCtrl.sign) router.get('/getUserInfo', usersCtrl.getUserInfo) module.exports = router
此时,前端使用 vue-cli 生成脚手架,经过安装 axios 进行 ajax 数据请求即可以获得返回的数据。先后端彼此互不关联。
but:新的需求来了,咱们要定义先后端的数据接口了,这时候前端须要等到服务端接口开发完才能进行开发吗?说好的先后端分离呢?
这个时候,前端可能会采起 mock 的形式进行数据模拟,须要先后端共同定义好接口规范,因而乎咱们开心的在本地写了一大堆mock文件。有一天接口忽然要变个字段,并无及时的通知前端,完了.... 或者团队成员之间协同开发,咱们须要同步 mock 数据,须要不断地进行 git 提交.... 随着项目的的复杂度增长,mock 数据如何管理?
这个时候,咱们须要一台 mock 服务器,最好能同步服务端接口的 mock。固然,如今网上也已经有了成熟的解决方案,好比 easy-mock 。他能够很好地支持Swagger,这是一个重磅级特性,经过 Swagger 只需1秒就能建立好项目全部的 Mock 接口。
说到这里,咱们完成了一个最基本的先后端分离的方案,后面我会接着介绍中间层 nodejs 应用和前端自动化发布以及脚手架的相关问题。若是您对本文有不一样的意见也欢迎一块儿探讨。
关于:
做者:monkeyWang
本文部分图片断落参考文章:实践中的先后端分离。 淘宝先后端分离实践
本文源码详见:服务端代码。前端代码。基于 vue 和 easy-mock 搭建的脚手架
微信公众号,欢迎关注,会不按期推送相关前端技术文章:
后面有时间再接着介绍我会接着介绍中间层 nodejs 应用和前端自动化发布以及脚手架的相关问题....