npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lzwme/simple-mock

v1.5.1

Published

Simple mock used in node server

Downloads

32

Readme

SIMPLE-MOCK

NPM version npm download

以注入到 node server 的 API 代理方式,实现简洁而功能强大的 API MOCK 功能。附带自动保存真实 API 接口返回数据功能。

SIMPLE-MOCK 简介

特色

  • 不侵入浏览器端代码:node server 注入模式实现 MOCK,不影响浏览器端编码
  • MOCK 实现简单:可自动保存后端 API 返回内容,mock 数据编写无需繁琐流程
  • 自定义 MCOK 方式简单强大:commonjs 方式自定义 MOCK 数据文件编写,无学习门槛,能实现各种自定义逻辑
  • 自定义 MOCK 文件修改实时生效:高效复现不同数据场景
  • 配置文件实时生效:自由切换生产与 MOCK 数据,排查比对问题方便高效
  • 支持接口过滤规则:只针对部分接口进行 MOCK 或 不 MOCK,只需修改一下配置文件
  • 支持 TypeScript:配置文件、自定义 mock 规则文件均支持以 TypeScript 方式编写(文件需以 .ts 结尾)
  • 支持 websocket 服务 MOCK
  • more...

何时使用

  • 与后端同步开发时:根据约定自定义接口规则,MOCK 数据进行功能开发
  • 需重现不同数据场景时:根据需求描述、测试反馈等,MOCK 相关数据不同的取值实现不同场景重现。重现测试反馈问题 so easy
  • 后端服务响应慢、不可用时:默认开启的自动保存功能,已经将平时请求的接口数据进行了基本的保存。只需要修改配置文件开启 Mock 即立即生效,避免阻塞前端研发
  • more...

安装与使用

安装

yarn add -d @lzwme/simple-mock

使用

在 nodejs 服务中的 API 代理部分,加入 simpleMock.rendersimpleMock.saveApi 相关 API 接入逻辑。 针对 websocket 的 MOCK 方案可参考 ws-proxy-server 目录下的示例。

这里以 http-proxy 作为代理示例,具体参见 server/app.js 中的源码。示例参考:

const app = require('express')();
const bodyParser = require('body-parser');
const httpProxy = require('http-proxy');
const apiProxy = httpProxy.createProxyServer();
const queryString = require('querystring');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

/**
 * 接口代理配置与mock
 */
const simpleMock = require('@lzwme/simple-mock');

app.all('/{api,rest}/**', async function(req, res) {
  // 开发模式下且可 mock 的情况
  if (appConfig.media === 'dev' && await simpleMock.render(req, res)) {
    return;
  }

  console.log('[apiProxy]', req._parsedUrl.pathname);
  apiProxy.web(req, res, {target: config[proxyTarget]});
});

// 在代理返回时,注入 saveApi 方法
apiProxy.on('proxyRes', function (proxyRes, req, res) {
  apiMock.saveApi(req, res, encoding);
});

// 以下为针对 post 请求,代理消费了 stream 的情况
// 针对 post 请求,将 (express.js)bodyParser 消费过的 stream 重新写回到 req
apiProxy.on('proxyReq', function(proxyReq, req, res, options) {
  if (!req.body || !Object.keys(req.body).length) {
    return;
  }

  const contentType = proxyReq.getHeader('Content-Type');
  let bodyData;

  if (contentType === 'application/json') {
    bodyData = JSON.stringify(req.body);
  }

  if (contentType === 'application/x-www-form-urlencoded') {
    bodyData = queryString.stringify(req.body);
  }

  if (bodyData) {
    proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
    proxyReq.write(bodyData);
  }
});

另外,这里还有两篇相关文章可参考:

MOCK 规则

基本的 MOCK 的规则为:

  • config.customSaveFileName 参数定义 MOCK 文件查找/保存后端返回数据的命名规则。对于 http 服务,默认为将请求 URL.pathname 路径。最后的文件名会将 / 替换为 _ 并以 js 结尾。例如,请求 URL 为 /a/b/c?t=123,则对应的默认文件名为 a_b_c.js
  • 关于 MOCK 文件规则:
    • 导出内容可为普通对象或数组、字符等,将直接作为 API 返回内容
    • 导出内容可为函数,函数传入参数 req 和 req 对象。此时:
      • 可根据 req.query 处理不同的返回内容;
      • 可直接处理返回信息。如: res.status(200).send(content)res.status(403).send('禁止访问')(模拟出错)
  • Mock 文件可存在于三个目录中,其优先级为:customdata > mockdata > customdata/autosave
    • mockdata 目录用于存放常用的公共 API 规则,会提交至 GIT 仓库
    • customdata 目录用于自定义 API 规则,不会提交至 GIT 仓库。该目录优先级最高
    • customdata/autosave 目录用于自动保存后端返回数据,也是保底的 mock 规则
  • 不 MOCK 的情况(代理至后端 API):
    • 符合规则的文件不存在
    • 文件导出内容为 undefinednull 或者 __ignore_mock__

mock 文件查找规则:

  • 先查找 ${config.mockFileDir}/customdata 目录
  • 再查找 ${config.mockFileDir}/mockdata 目录
  • 最后查找 ${config.mockFileDir}/customdata/autosave 目录
  • 都没有,则走转发到真实 API 代理。如果开启了自动保存,则会将返回结果保存到 autosave 目录中

自定义 mock 文件内容示例

当开启自动保存 API 内容时,autosave 目录内容下会生成 API 请求返回的结果。当需要对这些 API 进行自定义的规则时,可直接编辑它,不过更推荐将其复制到 mockdata 目录中,然后重新编辑器内容规则。下面为一个以函数方式定义的规则参考示例(可参考 mock/mockdata/rest_user_666.ts 文件内容):

module.exports = (req, res) => {
  console.log(req.body, req.query);
  // console.log(req.ip, req.ips, req.originalUrl);
  // 你甚至可以直接发送各种状态来返回结果(这里 server 以 express 为例)
  // res.status(500).send({ error: 'something blew up' });

  const result = {
    "code": 200,
    "url": req.url,
    "data": {
      "name": "lzw",
      "webSite": "https://lzw.me"
    },
    "date": new Date().toLocaleString(),
    "query": req.query,
    "body": req.body,
  };

  return result;
};

配置与 API

开启/关闭 mock 的配置方法

  • 配置文件方式

项目根目录 simple-mock-config.js 为配置文件,应自行创建,并配置 .gitignore 中忽略它,以便于随时修改 mock 行为而不影响其他开发者。配置内容示例可参考 simple-mock-config-sample.js 文件。

  • 环境变量方式

环境变量主要用于开启或关闭相关功能。其功能开启的优先级高于 simple-mock-config.js 中的配置。

  • 开启MOCK功能 process.env.MOCKAPI_ENABLE=mock
  • 开启自动保存API返回内容 process.env.MOCKAPI_AUTOSAVE=save
  • 强制每次请求都保存API返回内容(未开启MOCK功能时有效,一般不推荐开启) process.env.MOCKAPI_AUTOSAVE_FORCE=force
# 开启MOCK功能
set MOCKAPI_ENABLE=mock # process.env.MOCKAPI_ENABLE=mock
# 开启自动保存API返回内容
set MOCKAPI_AUTOSAVE=save # process.env.MOCKAPI_AUTOSAVE=save
# 强制每次请求都保存API返回内容(未开启MOCK功能时有效,一般不推荐开启)
set MOCKAPI_AUTOSAVE_FORCE=force # process.env.MOCKAPI_AUTOSAVE_FORCE=force

API

  • render(req, res, apiPath?): Promise<boolean>

判断一个请求是否可 mock,如果满足条件则执行 mock 逻辑。 应在 nodejs 服务中代理转发前执行。返回一个 Promise,结果为 true 则表示可 mock,停止继续执行代理转发;否则为不 mock,应继续走代理转发逻辑。 reqres 会传递到 mocK 规则文件中的自定义规则函数参数中,可通过 reqres 参数自行处理 mock 数据逻辑。

  • saveApi(req, res, contentEncoding)

在代理请求返回时执行,以判定是否需要保存后端返回的 API 数据。

注意: contentEncoding 取值为 encoded 时, res 应为需要直接保存的 JSON 格式的内容。如:

simpleMock.saveApi(req, {user: 'zhansan'}, 'encoded');
  • renderWs(reqData, client, filename = '')

针对 websocket 类型的 mock。client 参数可自行实现一些方法,其将在 mock 文件规则为函数时传入为第二个参数。

  • saveData: (data, filename = '')

主要是用于 websocket 服务端返回消息的保存。若 filename 为空,则具体的文件规需根据 config.customSaveFileName 确定。

FAQ / MOCK规则编写示例与技巧

  • 如何保存通过代理返回的信息?

关闭 mock 功能,开启自动保存API功能:

process.env.MOCKAPI_ENABLE=N
process.env.MOCKAPI_AUTOSAVE=save
  • 在开启 mock 模式下,如何忽略某个 API 请求的 mock,从真实后端 API 去请求?

mock/customdata目录中,编辑该 API 对应的 mock 文件,将返回值改为 __ignore_mock__。如果需要根据参数来处理,也是可以实现的,示例:

// 忽略mock
module.exports = '__ignore_mock__';
// or
module.exports = req => {
  const query = Object.assign({}, req.query, req.body);
  // id 为 1 则不 mock
  if (+query.id === 1) {
    return '__ignore_mock__';
  }

  return {...};
}
  • 小技巧:对于同一 API,如何快速保存不同参数返回的不同的值?

简单的数据返回,在 customdata 目录下自行写 Javascript 逻辑即可。但对于不同参数返回结果复杂、差异巨大这种情况,自行写逻辑就变得繁琐。

一种方式是通过定义 config.customSaveFileName 参数,根据不同的参数将他们落地为不同的文件。

另一种方式是可以关闭 MOCK,开启自动保存和强制保存:

module.exports = {
  mockFileDir: 'mock',
  isEnableMock: false,
  isAutoSaveApi: true,
  isForceSaveApi: true,
}

然后每触发一次请求成功后,到 customdata/autosave 中找到返回内容并复制出来,如此即可快速得到不同的返回值,再到customdata 中编写自定义函数处理规则,根据不同参数定义不同的返回逻辑。如果是比较公共性的逻辑,也可以编写到 mockdata 目录中。

  • mock 模式下,API 对应 mock 文件不存在时,会转发至后端。但此时会报错?

登陆信息为 mock 返回,session 为无效信息,转发至后端登陆认证失败,API 请求自然也不会成功。 此时可关闭 mock 功能,正常登陆一次,再开启mock;也可临时关闭登陆相关 API 的 mock。

  • 忽略自定义目录 customdata 的内容,使用公共目录下的 mockdata?

当 customdata 目录下有符合的规则时,会优先使用,否则则使用 mockdata 下的规则定义。因此,删除 customdata 目录下的定义即可。 但是因为开启 saveApi 会自动保存到 customdata,所以还有一种办法,就是在该目录下的文件中导出值为 undefined

module.exports = void(0);
  • saveApi 保存的某 API 的内容陈旧过时?

手动修改对应 mock 数据文件内容,或者删除该文件,以重新自动保存远端请求的结果。也可开启 config.isForceSaveApi 参数自动更新

  • more...

开发与测试

git clone https://github.com/lzwme/simple-mock.git
cd simple-mock

yarn run dev
yarn run serve:ws
yarn run serve

其他相关