最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 韬光敛彩:用 nginx + express 无痛实现前端项目本地 mock

    正文概述 掘金(江米小枣tonylua)   2020-12-24   551

    韬光敛彩:用 nginx + express 无痛实现前端项目本地 mock

    自从用单页应用(SPA)风靡以降,对于 web 前端项目来说 -- 无论是目前绝大多数的基于 webpack 的项目,还是既有的 grunt/gulp 项目来说,其基本开发流程大都如下:

    1. npm start 等启动开发时环境,自动监控源文件改变并对浏览器热更新
    2. 依赖后端接口返回的数据渲染页面逻辑,或将结构化的数据提交给后端接口
    3. 完成阶段性或全部开发,以各种方式实现部署

    这其中,最能体现“前后端分离”特征的就是第 2 步,即比之于传统上直接传输 HTML,代以轻量的局部 JSON 通信。

    然而从另一个角度来看,在开发过程中,前端对后端的依赖某种程度上是更紧密更重了的。很多时候当后端接口服务出错,或尚未开发完成时,前端开发者立即就会面临无米下炊的窘境。

    没错,本文要谈论的就是 mock 数据的问题。

    几种常见的自建 mock 数据的方法如下:

    1. 由企业/组织自建一个专门的 mock 站点,开发者可以自动维护模拟接口并控制返回值
    2. 利用 web 上公开的 mock 网站
    3. 安装 mockjs 等第三方依赖包,在代码中按其约定编写假数据
    4. 直接在业务源码中硬编码自定义的假数据

    以上方法一定程度上能暂时满足开发需求,但都需要在项目中硬编码,有些还要反复注释或删除,甚至还有可能泄露业务数据。因此除非是企业/团队的开发规范要求,否则都说不上是最方便的方法。

    用 express 楔入本地 mock

    在之前的一些项目中,我实践过这样的一种方案:

    韬光敛彩:用 nginx + express 无痛实现前端项目本地 mock

    这种方案 A 用起来还不错,利用本地额外启动的一个 express 服务(可在 npm scripts 中和 dev 整合成一条命令),“拦截”住某些的异步请求,同时也能放过本地未实现的请求,实现针对性的 mock 开发,同时又不用重写所有接口,在自主控制和“正式”接口间取得平衡和灵活度。

    但这样一来对项目的改动还是稍嫌麻烦,是对原有结构一种附着性的改造,若是利用相应的脚手架从头搭建的新项目还好,对改造既有项目、临时经手的各式项目来说,每次这样配置一番仍有些烧脑和麻烦;另一个小问题是,对于比较特殊复杂的请求,其转发步骤也难以保证完全的健壮性。

    用 nginx 转发本地 mock

    由此发展出的方案 B 是对方案 A 的改进,也是本文主要谈论的方法。其思路更简单直接,那就是借助 nginx,实现一种完全无侵入性的 mock 套壳开发:

    韬光敛彩:用 nginx + express 无痛实现前端项目本地 mock

    该方案主要配置方法如下。

    nginx.conf

    确保本机安装了 nginx 后,在 nginx.conf 中配置相关本地请求路径的 location:

    #user  nobody;
    events {
        worker_connections  1024;
    }
    
    http {
        resolver 8.8.8.8;
        default_type  application/octet-stream;
        sendfile      on;
        keepalive_timeout  65;
        server {
            listen       8081;
            # hosts 中做相应的设置 127.0.0.1 localhost.foo.com
            server_name  localhost.foo.com;
            charset	     UTF-8;
    
            location / {
                proxy_pass http://localhost.foo.com:8080;
            }
    
    		# 要代理的路由
            location /foo-api/bar {
                proxy_set_header Host $host;
                # express 服务地址
                proxy_pass http://localhost:8090;
            }
    		
            # ... 若干相似的代理配置
            
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }
    }
    

    mock.server.js

    用 express 编写本地 mock 服务:

    const express = require('express')
    const bodyParser = require('body-parser')
    const walk = require('klaw-sync')
    const ON_DEATH = require('death')
    const { execSync } = require('child_process')
    
    process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0 // eslint-disable-line
    
    const app = express()
    app.use(
      bodyParser.urlencoded({
        extended: false
      })
    )
    app.use(bodyParser.json())
    app.use((req, res, next) => {
      res.header('Access-Control-Allow-Origin', argsMap.mockorigin || '*')
      res.header(
        'Access-Control-Allow-Headers',
        'Origin, X-Requested-With, Content-Type, Accept, hci-secret-key, x-api-key'
      )
      res.header('Access-Control-Allow-Methods', 'POST, OPTIONS, GET')
      res.header('Access-Control-Allow-Credentials', true)
      next()
    })
    
    // 遍历 xxx.api.js 文件
    walk(__dirname)
      .filter(p => /\.api\.js$/.test(p.path))
      .map(p => p.path)
      .forEach(part => require(part)(app))
    
    const p1 = 8090
    const h1 = 'localhost'
    const server = app.listen(p1, h1, () => {
      console.log(`\n\n Local server running at: http://${h1}:${p1} \n\n`)
    })
    
    // 确保退出时停止所有服务
    ON_DEATH((signal, err) => {
      server.close()
      try {
        execSync('nginx -s stop')
      } catch (ex) {}
      console.log(signal, 'nginx has stopped.')
    })
    

    同目录下的若干 xxx.api.js:

    module.exports = function(app) {
      app.post("/foo-api/bar/query", (req, res) => {
        res.json({
          code: 1,
          msg: null,
          data: [0, 1, 3],
        });
      });
    };
    

    package.json 和启动命令

    最后配置相应的 npm scripts 即可:

    "startlocal": "shell-exec \"npm run start --local\" \"npm run express\"",
    "express": "nodemon mock/mock.server.js",
    
    • nginx -c <nginx.conf绝对路径> && npm run startlocal 取代 npm start 启动开发服务
    • express 启动文件同目录下所有 <模块名>.api.js 的文件都会被自动加入 mock 服务中
    • 在浏览器中,将自动打开的页面 url 中 8080 部分改为 8081 即可


    --End--

    查看更多前端好文
    请搜索 云前端 或 fewelife 关注公众号

    转载请注明出处


    起源地下载网 » 韬光敛彩:用 nginx + express 无痛实现前端项目本地 mock

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元