前后端分离简介

对Web开发的效率和质量要求越来越高,专业的人士做专业的事情越来越重要。前后端分离的工程实践几乎成为一种标配。

以下代码均是为了说明实现思路而简单写就的,不可以作为实际生产环境使用。请酌情修改。

目标

前后端分离的目标是最大化专业开发人员的生产效率,减少不必要的沟通和协调。通过工具将各自的劳动成果粘合到一起。

问题

不同团队需要解决的具体问题可能不尽相同,不过总体上不外乎这三个部分。

  1. 前端独立开发环境。完全不需要后端介入,就可以自己在本地开发调试,预览。

  2. 后端独立开发环境。同样的不需要前端同学的介入即可完成接口测试等工作。

  3. 前后端构建产物关联在一起。

前端独立开发环境

前端独立开发需要解决几个基本的问题。

  1. 如何预览HTML页面。一般会启动一个静态服务器来处理HTML页面(比如这个 )。当然也可以通过文件的方式来打开页面预览。

  2. 如何mock接口数据。页面大多数需要根据接口返回的数据来动态拼装。能够mock接口,利用假数据来测试页面和前端逻辑至关重要。这方面的工具也很多比如这个

  3. 如何打包生成产物。代码写好要打成包以供部署使用。

简单方案

从上面需要解决的问题看,至少需要一个http服务器,用来提供html和接口服务。我们可以用node来实现一个简化版本的开发服务器。另外还需要一个构建打包工具。

功能点:

  1. 能够提供http服务,预览html效果。

  2. 能够提供接口mock服务,预览动态效果。

  3. Javascript 支持到es5,不支持模块系统;css 只允许写原声的css;可以用简单的脚本搞定这一切。

开发服务器简单实现的示例代码:

  1. 利用express 实现简单的开发服务器。
var express = require('express')
var bodyParser = require('body-parser')
var fs = require('fs')
var http = require('http')

var app = express()
var httpServer = http.createServer(app)
app.use(express.static('./'))
app.use(bodyParser.json())

app.use(function(req, res, next) {
    // 默认返回json数据结构
    res.header('content-type', 'application/json;charset=utf-8')
    // 解决cors跨域问题
    res.header('access-control-allow-credentials', 'true')
    res.header('access-control-allow-headers', 'content-type,cookieorigin,x-requested-with')
    res.header('access-control-allow-methods', 'POST, GET, OPTIONS')
    res.header('access-control-allow-origin', req.get('origin'))

    if(req.method === 'OPTIONS') {
        res.end()
    } else {
        next()
    }
})
// url 返回规则配置
app.use(function(req, res, next) {
    if(new RegExp('/api/order/list', 'i').test(req.url)) {
        res.end(fs.readFileSync('./mock/order_center/list.json'))
    } else {
        next()
    }
})

httpServer.listen(8088);

console.log('http server at 8088');

server.js中实现了一个简单的开发服务器。可以把具体的规则部分抽出到单独的文件中,实现更加复杂的逻辑。使用的时候,只需要把server.js copy到项目目录下,安装所需要的依赖即可。

image.png

如果不考虑采用较高的es6特性,模块化方案,sass等特性,纯手撸代码,那么可以简单的把所有的文件拼合成一个文件即可。

// 用namespace的方式来防止变量冲突
// namespace.js
function namespace(packageName, implementation) {
    if(packageName) {
        var nm = window
        packageName.split('.').forEach(function(name) {
            if(name) {
                nm[name] = nm[name] || {}
                nm = nm[name]
            }
        })
        if(implementation) {
            for(var k in implementation) {
                nm[k] = implementation[k]
            }
        }
        return nm
    }
}

namespace('cn.honchy.utils', {
    namespace: namespace
})

假设我们pages下面用来存放页面代码,其他的工具函数都放在utils里面,打包的需要是合并成为一个js文件,那么可以简单的这么干。当然如下代码也仅仅考虑合并在一起。其他的比如依赖分析等暂不考虑

// buid.js 用来合并代码用
// 假设我们src下所有的文件
var fs = require('fs')
var path = require('path')
var execSync = require('child_process').execSync

var files = fs.readdirSync(path.resolve(__dirname , './src'))
// 读取到文件之后需要拍下顺序,把pages放到最后面
files.sort(function(a, b) {
    if(a === 'pages') {
        return 1
    } else if(b === 'pages') {
        return -1
    } else {
        return a.localeCompare(b)
    }
})

var build = path.resolve(__dirname, './build')
execSync('rm -rf ' + build) 
execSync('mkdir -p ' + build)
var bundle = path.resolve(build, './bundle.js')
execSync('touch ' + bundle)

function appendFile(fp) {
    var content = fs.readFileSync(fp).toString()
    content = '!(function() {' + content + '})();'
    fs.appendFileSync(bundle, "/* " + fp + " */\r\n")
    fs.appendFileSync(bundle,  content + "\r\n")
}

function processFile(fp) {
    var stat = fs.lstatSync(fp)
    if(stat.isFile()) {
        appendFile(fp)
    } else if(stat.isDirectory()) {
        var children = fs.readdirSync(fp)
        children.forEach(function(child) {
            var cfp = path.resolve(fp, child)
            processFile(cfp)
        })
    }
}

// 优先注入namespace
var namespacepath = path.resolve(__dirname, './namespace.js')
appendFile(namespacepath)

// 然后把读取到的文件包装成为立即执行表达式
files.forEach(function(file) {
    var fp = path.resolve(__dirname, './src', file)
    processFile(fp)
})

现在的目录结构如下:

image

详细的代码在https://github.com/honchy/mock-server/tree/simple_impl

后端独立开发环境

笔者对后端的工程化理解不深,在我看来,前后端分离后有几个问题需要解决。

  1. 开发环境,生产环境等的区分和灵活切换。
    前后端分离之后,开发节奏也相对解耦了。那么就有可能出现,多个前端对一套后端,或者多个后端对一套前端的情况。这就要求有比较灵活的环境切换能力。
  2. 接口模拟测试工具。
    因为不需要前端页面来生成测试数据了,所以需要另外的一个工具来模拟接口请求和生成测试数据。

此方面涉及比较多的运维知识,对笔者来说太复杂了。另起文章来介绍好了。先埋个坑。

前后端重新关联

前后端关联就是把前端和后端的构建产物结合在一起。一般来说把前端资源copy到后端指定的目录中即可。需要解决的问题是:

  1. 约定。
    前端的构建产物,以约定的路径和文件名放到指定的服务器上。后端根据前端开发人员提供的版本号等去服务器上下载下来,并且解压到指定的文件夹下。这块可以借助maven的私服来实现,也可以简单的通过文件存储来解决。
  2. 资源引用路径的协调。
    前端目录结构和后端的目录结构的层次可能不一样,对有可能出现的路径不一致的情况需要考虑如何处理。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,287评论 25 707
  • 每个周五都浑然不知,总是有人提醒才想起来第二天是周末,这样的日子已有三周。 想想过去的半年,每天都慵懒的生活,叹息...
    amykaku阅读 119评论 0 0
  • 本来应该先有这篇文章,后有如何提高ElasticSearch 索引速度才对。不过当时觉得后面一篇文章会更有实际意义...
    祝威廉阅读 7,158评论 5 6
  • 惆悵書集惆悵客 相思语录尽痴心 众人烹得癫狂泪 几许人清暗自吟? 一生一代一双人 ?难得才子情挚深 奈何爾年无骚事...
    璐狗尔阅读 187评论 0 0
  • 当时李彦宏创业的时候,中国就没几个搜索引擎,所以他开了百度公司;比尔盖茨还在哈佛大学当学生的时候,世界上第一台个人...
    呱哩哗啦阅读 1,049评论 0 0