美文网首页
前后端分离简介

前后端分离简介

作者: 半ma | 来源:发表于2017-11-12 23:35 被阅读50次

对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. 资源引用路径的协调。
    前端目录结构和后端的目录结构的层次可能不一样,对有可能出现的路径不一致的情况需要考虑如何处理。

相关文章

  • 前后端分离-独立于后端的前端开发

    题目:前后端分离-独立于后端的前端开发简介:如何构建 Web 前端 Mock Server 前后端分离真实数据模拟...

  • 前后端分离简介

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

  • swagger

    swagger简介 前后端分离 Vue+SpringBoot后端时代:前端只用管理静态页面;html-->后端。模...

  • 如何构建 Web 前端 Mock Server

    简介:如何构建 Web 前端 Mock Server 前后端分离真实数据模拟接口测试 前后端分离让前端攻城师独立于...

  • springboot RestController传参 demo

    简介 前后端分离下,前后端通讯的各种方法 Git地址 https://gitee.com/wqrzsy/lp-de...

  • Java进阶之Swagger工具

    Swagger简介 前后端分离,主流框架用的是Vue+SpringBoot,前端负责写前端页面,后端写具体的业务,...

  • 2019-01-11前后端分离

    什么是前后端分离? 为什么前后端分离? 前后端分离的优势? 未分离时期 MVC: 早期JSP+SERVLET中的结...

  • 前后端分离

    什么是前后端分离 前后端分离中前端负责页面路由控制,页面展示,后端处理数据,通过json进行传输。前后端分离并非仅...

  • vivo 商城前端架构升级—前后端分离篇

    本文主要以 vivo 商城项目的前后端分离经验,总结前后端分离思路,整理前后端分离方案,以及分离过程中遇到的问题及...

  • Spring Boot+Vue概述(一)

    前后端分离 前后端分离就是将⼀个应⽤的前端代码和后端代码分开写,为什么要这样做?如果不使⽤前后端分离的⽅式,会有哪...

网友评论

      本文标题:前后端分离简介

      本文链接:https://www.haomeiwen.com/subject/oiwomxtx.html