背景

最近对我的项目里的老代码进行了一些优化和整改,其中一个便是对mock的优化。

老代码

计划

将mock代码先应用babel从es6编译为es5,再本人写了一个中间件mockApiMiddleware(理论就是一个办法接管解决reques,response,next),依据request从mock中获取到数据再response给前端。
browsersync示例:

const webpackDevMiddleware = require('webpack-dev-middleware')const webpackHotMiddleware = require('webpack-hot-middleware')module.exports = function() {    ...    middleware: [        mockApiMiddleware(), // 自定义mock服务中间件        webpackDevMiddleware(params), // webpack中间件,params是webapck编译后相干门路等参数        webpackHotMiddleware(params),]}

弊病

  1. 当mock的代码扭转后,须要重启(即从新babel编译原来的mock)能力刷新mock数据。
  2. mock中若依赖我的项目代码的一些常量等文件,babel还须要减少援用了的我的项目代码的编译,否则会报错(不反对我的项目的es6代码)。

新代码

计划

为了解决如上问题,决定将架构批改为:

  1. 解决弊病2 ==> 应用node server作为mock的服务器,和browsersync不共用服务端口,新的mock server应用4000端口(browsersync应用8080)。
  2. 解决弊病1 ==> 应用nodemon监听到文件批改主动重启mock服务。
  3. 因为当初mock服务和browsersync不在同一个端口启动,前端通过browsersync启动后发送的mock申请仍旧是申请8080端口,因而新增http-proxy-middleware进行转发,将8080端口(原申请)的申请转发到4000端口(mock服务端口)。
  4. 根据上述计划,发现如果这样设计咱们须要同时启用2个cmd窗口,为了开发不便,咱们想要一条命令npm start即可。concurrently 和 npm-run-all能够解决这个问题,不须要开新的cmd窗口并行执行多条cmd命令。

实现

新建mock server

新建node服务器时,应用express、koa等能缩小很多工作。因为在本次我的项目中,原来的mockApiMiddleware代码是能够复用的,因而简略应用node新建服务即可。

// createProxyMiddleware没有传递next,这里只是为了兼容老代码const next = () => {  info(`can not find in mock data.`)}// 获取mock数据的业务代码const mockApiMiddleware = function (req, res) {  info(`Request Method-> ${req.method}, URL -> ${req.url}`)  const mockArray = mocker.getMocks()  if (req.method.toUpperCase() === 'GET') {    handleGetRequest(req, res, next, mockArray)  } else if (req.method.toUpperCase() === 'POST' || req.method.toUpperCase() === 'PUT') {    handlePostRequest(req, res, next, mockArray)  } else if (req.method.toUpperCase() === 'PATCH') {    handlePatchRequest(req, res, next, mockArray)  }}const server = http.createServer((req, res) => {  mockApiMiddleware(req, res)})server.listen(4000)info(`mock server start on port 4000. \r\n\r\n`)

nodemon启动mock

在package.json的scripts中新增如下配置,npm run mock启动服务后,watch的文件扭转时,主动重启。

-w 配置监听的文件,监听多个文件时用多个-w示意。./mock/server.js 是启动服务的文件--exec配置为应用babel-node运行(es6文件能够间接执行,不必babel预编译)
"mock": "nodemon --legacy-watch -w ./mock -w [other watch files] ./mock/server.js --exec babel-node"

browsersync示例

http-proxy-middleware 1.0+版本中,应用createProxyMiddleware办法新建转发中间件。

const webpackDevMiddleware = require('webpack-dev-middleware')const webpackHotMiddleware = require('webpack-hot-middleware')const { createProxyMiddleware } = require('http-proxy-middleware')module.exports = function() {    ...    middleware: [        webpackDevMiddleware(params), // webpack中间件,params是webapck编译后相干门路等参数        webpackHotMiddleware(params),        createProxyMiddleware('/api/v1', { // 门路匹配              target: 'http://localhost:4000', // 要转发的指标地址              changeOrigin: true, // for vhosted sites, changes host header to match to target's host            }),    ]}

npm run同时执行多个

concurrently 和 npm-run-all同样有用,我的项目中曾经有npm-run-all,因而抉择了它。
--parallel参数示意并发执行
gulp-dev能够是任何启动前端的命令

"start":"npm-run-all  --parallel mock gulp-dev"

后果

当初只须要运行npm run start,就能够同时启动2个服务啦,并且mock数据批改后立马失效,再也不必重启了。