在线商城项目03-启用mock服务

作者: love丁酥酥 | 来源:发表于2018-04-07 15:10 被阅读53次

    简介

    对于前后端分离的开发,在后台接口还未就绪时,前端需要使用mock数据进行开发。最容易想到的办法,当然是把mock数据写在页面里,但是这会让我们的页面代码很臃肿,而且也不能还原请求和响应的场景。所以,我们需要在本地启用一个服务器,用来返回mock数据。本篇将会介绍常用的几种mock服务开启办法,大家根据需要自行选择。

    首先,我们肯定要引入mock数据。在根目录下新建mock文件夹用来存放我们的mock数据,如下图:



    goods.json内容如下:

    {
      "status": "0",
      "msg": "",
      "result": [
        {
          "productId": "10001",
          "productName": "小米6",
          "salePrice": "2499",
          "productImage": "mi6.jpg"
        },
        {
          "productId": "10002",
          "productName": "小米笔记本",
          "salePrice": "3999",
          "productImage": "note.jpg"
        },
        {
          "productId": "10003",
          "productName": "小米6",
          "salePrice": "2499",
          "productImage": "mi6.jpg"
        },
        {
          "productId": "10004",
          "productName": "小米6",
          "salePrice": "2499",
          "productImage": "1.jpg"
        },
        {
          "productId": "10005",
          "productName": "小米6",
          "salePrice": "2499",
          "productImage": "2.jpg"
        },
        {
          "productId": "10006",
          "productName": "小米6",
          "salePrice": "2499",
          "productImage": "3.jpg"
        },
        {
          "productId": "10007",
          "productName": "小米6",
          "salePrice": "2499",
          "productImage": "4.jpg"
        },
        {
          "productId": "10008",
          "productName": "小米6",
          "salePrice": "2499",
          "productImage": "5.jpg"
        }
      ]
    }
    

    然后,我们开启服务器,允许我们访问该mock数据。

    方法1 MAC下可以直接使用apache

    apache相关命令如下:

    开启apache: sudo apachectl start
    
    重启apache: sudo apachectl restart
    
    关闭apache: sudo apachectl stop
    
    服务python -m SimpleHTTPServer [port]
    

    所以我们只需要开启apache,然后进入需要开启服务器的目录,运行如下命令:

    python -m SimpleHTTPServer 8888
    

    即可,端口号可根据你自己的需要来指定。假设我们现在在根目录开启服务,在浏览器输入

    http://localhost:8888/mock/goods.json
    

    会有:



    访问成功。

    方法2 使用http-server开启服务

    原理上,和apache相同,都是进入指定目录开启服务,所选工具不一样而已。我们可以全局或者在项目中使用npm安装http-server,然后进入指定目录开启服务。这里假设是在全局安装,步骤如下:

    npm install http-server -g
    

    进入项目根目录:

    http-server -p 8888
    

    方法3 使用express

    我们同样可以使用express自己新开一个服务器,但是这没有太大的必要,vue-cli构建的build文件夹下以前有一个dev-server.js,但是现在已经没有了,如果需要mock数据我们可以直接在webpack.dev.conf.js中进行修改。
    最简单的办法如下,添加如下代码:

    const express = require('express')
    const app = express()
    
    var goodsData = require('../mock/goods.json')
    var apiRoutes = express.Router()
    app.use('/mock', apiRoutes)
    

    然后在该文件的devServer对象中添加如下代码:

        before(app) {
          app.get('/mock/goods', (req, res) => {
            res.json(goodsData)
          })
        }
    

    如果你没看懂,不要紧,文末我会放出文件的整体代码。
    好的,现在试着重新run以下代码。访问http://localhost:8086/mock/goods


    成功。

    方法3的优化

    好的,目前来看,方法3是最不错的,因为你可以指定mock请求的路径,比如mock/goods或者api/goods,可以对返回做额外的处理,比如

    res.json({
      code: '000',
      data: goodsData
    })
    

    可是,还是有一点不方便。如果现在项目中有其他人也建立了自己的mock数据,难道每个人都需要在这个文件中新增一段代码吗?那么这个代码的体积和维护难度将大大增加。这里我有个思路,就是直接遍历mock文件夹,将所有的文件数据放进一个mock数组,根据需要返回。
    webpack.dev.conf.js需要进行如下修改:

    const fs = require('fs')
    
    var mockData = {}
    var mockFiles = fs.readdirSync(path.resolve(__dirname, '../mock'))
    mockFiles.forEach(function (val) {
      mockData[val.split('.')[0]] = require('../mock/' + val)
    })
    
    devServer{
        ...
        before(app) {
          app.get(/\/mock\/(\w+)/, (req, res) => {
            res.json(mockData[RegExp.$1])
          })
        }
    }
    

    这里我是用的正则,因为直接在before(app)里写函数方法没有运行,所以我猜想此处是根据正则进行匹配和回调,当然,我的正则水平很一般,有大神的话可以自己写一个。
    我们来验证一下,复制一份goods.json命名为goods2.json,然后重新run以下代码,分别访问这两个路径如下:


    成功访问到了mock下的隔文件。不过其实这样也并不是很好,因为有些mock数据没有使用的情况下也会构建,拖慢性能。这里有两个办法,一个是即使清理已经废弃的mock数据,第二就是新添一个mock数据的配置表,只有配置表指定的数据我们才去mock。这里我就不详述方法了。

    webpack.dev.conf.js代码如下:

    'use strict'
    const utils = require('./utils')
    const webpack = require('webpack')
    const config = require('../config')
    const merge = require('webpack-merge')
    const path = require('path')
    const baseWebpackConfig = require('./webpack.base.conf')
    const CopyWebpackPlugin = require('copy-webpack-plugin')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
    const portfinder = require('portfinder')
    
    const fs = require('fs')
    const express = require('express')
    const app = express()
    
    // var goodsData = require('../mock/goods.json')
    
    var mockData = {}
    var mockFiles = fs.readdirSync(path.resolve(__dirname, '../mock'))
    mockFiles.forEach(function (val) {
      mockData[val.split('.')[0]] = require('../mock/' + val)
    })
    
    var apiRoutes = express.Router()
    app.use('/mock', apiRoutes)
    
    const HOST = process.env.HOST
    const PORT = process.env.PORT && Number(process.env.PORT)
    
    const devWebpackConfig = merge(baseWebpackConfig, {
      module: {
        rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
      },
      // cheap-module-eval-source-map is faster for development
      devtool: config.dev.devtool,
    
      // these devServer options should be customized in /config/index.js
      devServer: {
        clientLogLevel: 'warning',
        historyApiFallback: {
          rewrites: [
            { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
          ],
        },
        hot: true,
        contentBase: false, // since we use CopyWebpackPlugin.
        compress: true,
        host: HOST || config.dev.host,
        port: PORT || config.dev.port,
        open: config.dev.autoOpenBrowser,
        overlay: config.dev.errorOverlay
          ? { warnings: false, errors: true }
          : false,
        publicPath: config.dev.assetsPublicPath,
        proxy: config.dev.proxyTable,
        quiet: true, // necessary for FriendlyErrorsPlugin
        watchOptions: {
          poll: config.dev.poll,
        },
        // before(app) {
        //   app.get('/mock/goods', (req, res) => {
        //     res.json(goodsData)
        //   })
        // }
        before(app) {
          app.get(/\/mock\/(\w+)/, (req, res) => {
            res.json(mockData[RegExp.$1])
          })
        }
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env': require('../config/dev.env')
        }),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
        new webpack.NoEmitOnErrorsPlugin(),
        // https://github.com/ampedandwired/html-webpack-plugin
        new HtmlWebpackPlugin({
          filename: 'index.html',
          template: 'index.html',
          inject: true
        }),
        // copy custom static assets
        new CopyWebpackPlugin([
          {
            from: path.resolve(__dirname, '../static'),
            to: config.dev.assetsSubDirectory,
            ignore: ['.*']
          }
        ])
      ]
    })
    
    module.exports = new Promise((resolve, reject) => {
      portfinder.basePort = process.env.PORT || config.dev.port
      portfinder.getPort((err, port) => {
        if (err) {
          reject(err)
        } else {
          // publish the new Port, necessary for e2e tests
          process.env.PORT = port
          // add port to devServer config
          devWebpackConfig.devServer.port = port
    
          // Add FriendlyErrorsPlugin
          devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
            compilationSuccessInfo: {
              messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
            },
            onErrors: config.dev.notifyOnErrors
            ? utils.createNotifierCallback()
            : undefined
          }))
    
          resolve(devWebpackConfig)
        }
      })
    })
    

    总结

    另外,大家还可以用json-server,或者自己编写一个服务器,其实目的不过是返回一个假数据,不管怎样实现都是可以的,看实际项目中怎么方便。你甚至还可以使用mock.js来模拟随机数据等。就不一一列举了。

    然后我们提交代码

    git status
    git diff
    git add .
    git commit -am 'add mock data and mock server'
    git push
    

    相关文章

      网友评论

        本文标题:在线商城项目03-启用mock服务

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