Создание фиктивного сервиса с нуля

Node.js внешний интерфейс Express Webpack

Мок-данные — очень значимая вещь: интерфейс и бэк-энд можно разрабатывать параллельно благодаря фейковым данным, генерируемым моком.easy-config-mock, далее записываются идеи реализации и все технические детали окончательной реализации кода


точка фокусировки

Документируйте проблемы во время разработки:

Как реализовать функцию mock data (технический отбор)

использоватьmockjsдля генерации поддельных данных (прилагается:ложные правила)

использоватьexpressСтроительные услуги (прилагается:официальный сайт экспресс)

Как интегрироваться в строительные леса или рабочий процесс

Разработан, чтобы быть как можно более простым, что позволяет легко интегрировать его в существующие леса или рабочие процессы.easy-config-mockЕго также легко интегрировать, просто:

const easyConfigMock = require('easy-config-mock')

new easyConfigMock({
  // 将配置文件路径传递进去,服务会自动监听文件变化并重启服务
  path: path.resolve(__dirname, 'mock.config.js')
})
Как использовать его с проектами

Рекомендуется поместить файл конфигурации фиктивных данных в корневой каталог проекта, потому что фиктивные данные тесно связаны с бизнесом, и их легко проверить и поддерживать, когда они собраны вместе, как показано ниже:

+ vue-preject
-   node_modules
-   src
    mock.config.js   // mock数据的配置文件,名字仅做示例用
Как поддерживать более сложные сценарии

mockjsФункция очень мощная и может генерировать случайные поддельные данные, но этого недостаточно в случае очень сложных бизнес-сценариев.Иногда для проверки логики отображения ожидание состоит в том, что отдачу макета интерфейса можно настроить

Это можно сделать, благодаря промежуточному программному обеспечению Express, взглянитеeasy-config-mockКак написать файл конфигурации вбольше инструкций

// mock.config.js
module.exports = {
  // common选项不是必须的,可以不用有该选项,内置的配置如下,当然你也可以更改
  common: {
    // mock服务的默认端口,如果端口被占用,会自动换一个
    port: 8018,
    // 如果你想看一下ajax的loading效果,该配置项可以设置接口的返回延迟
    timeout: 500,
    // 如果你想看一下接口请求失败的效果,将rate设置成0就可以了,rate取值范围0~1,代表成功的概率
    rate: 1,
    // 默认是true,自动开启mock服务,当然你也可以通过将其设置为false,关闭掉mock服务
    mock: true
  },
  // 普通的api...
  '/pkApi/getList': {
    code: 0,
    'data|5': [{
      'uid|1000-99999': 999,
      'name': '@cname'
    }],
    result: true
  },
  // 中间件api(标准的express中间件),这里你可以书写接口返回逻辑
  ['/pkApi/getOther'] (req, res, next) {
    const id = req.query.id
    req.myData = {   // 重要! 将返回数据挂载在req.myData
      0: {
        code: 0,
        'test|1-100': 100
      },
      1: {
        code: 1,
        'number|+1': 202
      },
      2:{
        code: 2,
        'name': '@cname'
      }
    }[id]
    next()  // 最后不要忘记手动调用一下next,不然接口就暂停处理了!
  }
}

Преимущества easy-config-mock

  • Легко интегрируется в строительные леса или рабочие процессы и может автоматически перезапускать службы.
  • Поддержка пользовательского промежуточного программного обеспечения для удовлетворения более сложных бизнес-сценариев
  • По сути, он не будет вторгаться в бизнес-код, просто измените префикс запроса интерфейса наhttp://127.0.0.1:mock端口
  • Файл конфигурации остается в проекте для облегчения разработки и обслуживания.

Конкретные технические детали реализации

Ниже приведены все технические детали, необходимые для реализации колеса. Код лишь кратко выражает основную идею. Подробности см.исходный код

Как слушатьmock.config.jsизменения файла

использоватьchokidarмодуль

const chokidar = require('chokidar')

chokidar.watch(somepath, {
  persistent: true
}).on('change', _ => {
  // file change...
  // do some logic...
})
Как добиться автоматического перезапуска служб

forkдочерний процесс для запускаexpressСлужба, при изменении файла конфигурации убить дочерний процесс и перезапустить службу

const childProcess = require('child_process')

let child
// 使用子进程启动express服务
child = childProcess.fork('./server.js', [], {
  encoding: 'utf8',
  execArgv: process.execArgv
})

chokidar.watch(somepath, {
  persistent: true
}).on('change', _ => {
  // 文件发生变化后杀死子进程并重启服务
  child.kill('SIGKILL')
  child = childProcess.fork('./server.js', [], {
    encoding: 'utf8',
    execArgv: process.execArgv
  })
})
Как дочерний процесс читает данные файла конфигурации

Данные, передаваемые программой родительскому процессу, неизвестны дочернему процессу, и можно использовать связь между родительским и дочерним процессами.Связь и отключение между дочерним процессом и родительским процессом в child_process

// 给子进程传递数据
child.send({
  path: path
  ...
})
// 子进程接收到数据
process.on('message', ({ path, ... }) => {
  delete require.cache[path]
  // 这里,拿到了mock数据的配置项
  const options = require(path)
})

require кэшируется, вам нужно сначала удалить кеш require, а затем повторно получить данные файла конфигурации

Как имитировать запрос jsonp

Прежде всего, вы должны знать, является ли запрос jsonp, и проверить, имеет ли ссылка запроса параметр обратного вызова.

let dataType
app.use((req, res, next) => {
  dataType = req.query.callback ? 'jsonp' : 'json'
  next()
})
Как отсрочить возврат интерфейса

Иногда мы пишем эффект загрузки и хотим его проверить

const delayRes = (time) => (req, res, next) => {
  setTimeout(function() { next() }, time)
}
// 给接口增加1秒延迟
app.use(delayRes(1000))
Как сделать так, чтобы интерфейс возвращал ошибку

Иногда мы хотим увидеть эффект отключения или ошибки сервера.

const successRate = (rate) => (req, res, next) => {
  if (rate > Math.random()) return next()
  return next(500)
}
// 100%返回500错误
app.use(successRate(0))
app.use((err, req, res, next) => {
  res.status(500).json({ status: 0, code: 500, msg: 'Server Error' })
})
Как разрешить междоменный доступ

Доступ к фиктивному интерфейсу, отличному от jsonp, является междоменным запросом.(协议,域名,端口三者相同才为同域), междоменные запросы запрещены, и будет выдано сообщение об ошибке.Здесь нужно установить разрешить междоменные

const crossDomain = () => (req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
  if (req.method === 'OPTIONS') res.status(200) // 让OPTIONS快速返回
  next();
}
app.use(crossDomain())
финал: создание маршрута
const { mock } = require('mockjs')

// options是配置文件里面的api信息
Object.keys(options).forEach(path => {
  const data = options[path]

  // 如果是自定义中间
  if (typeof data === 'function') app.use(data)

  app.use(path, (req, res, next) => {
    // req中带有myData的话说明是自定义中间件,否则是普通的mock api
    const rsp = req.myData ? mock(req.myData) : mock(data)
    res.status(200)[dataType](rsp)
  })
})
Добавлено: плагин webpack для easy-config-mock.

easy-mock-webpack-plugin

На самом деле использовать напрямуюeasy-config-mockпросто хорошо


Ссылка на ссылку


Я видел это, пожалуйста, поставьте лайк 👍~ 🙂😃😃😂😂😂Адрес источника

Эта статья закончилась.