• 作者:老汪软件技巧
  • 发表时间:2024-10-13 17:02
  • 浏览量:

一、前言

开发了个Mock CLI工具,助力开发速度提升一倍,欢迎使用和点赞:

支持能力

在开发过程中,也遇到了一些难点,做一下复盘

二、实现原理图1、原理图

2、原理描述三、项目实战1、配置命令行参数

首先我们配置mock命令,设定参数

type: 分别代表API类型,这里写一下Restful风格的实现思路

port: 服务启动的端口

配置package.json

{
  "main": "index.js",
  "files": [
    "bin",
    "command",
    "public",
    "utils",
    "index.js",
    "package.json",
    "server.js",
    "README.md"
  ],
  "type": "module",
  "bin": {
    "dev-mock-cli": "./bin/index.js"
  }
}

入口文件index.js

必须添加 #!/usr/bin/env node,否则无法执行

#!/usr/bin/env node
class MockServer {
  constructor(config) {
    this.config = config;
    // 初始化配置
  }
  // 启动服务器
  async start() {
    // 判断当前要使用的端口是否被占用
    const newPort = await getIdlePort(this.port);
    
    // 启动服务器
    const app = express();
    app.use(express.urlencoded({ extended: true }));
    app.use(express.json({ limit: '50mb' }));
    // 通用中间件
    app.all('*', cors);
    app.all('*', timeoutSetting);
    
    // 根据类型加载模块
    const loadModule = this.type === 'action' ? action : restful;
    loadModule({ app, filePath: this.filePath, config: this.config });
    this.startServer(app);
  }
  // 启动Express服务器并打印启动日志
  startServer(app) {
    app.listen(this.port, () => logServerStart(this.port, this.type));
  }
}
export default MockServer;

上面的做了三件事:

有了这个mock工具,开发速度提升一倍:原理篇__有了这个mock工具,开发速度提升一倍:原理篇

2、加载restful风格API逻辑

const restful = async ({ app, filePath, config }) => {
  const { proxyApiUrl, swaggerApi=[] } = config;
  // 如果没有文件,新建example
  checkFileExist(filePath, true)
  const apiList = getAllAPIPath(filePath);
  // 获取本地所有的path,生成本地代理
  app.all(apiList, async (req, res) => {
    const url = req.path;
    checkFileExistsAndRespond(url, filePath, req, res);
  });
  await fetchAndCreateRoutes({app, swaggerApi});
  
  // 没有本地mock,则读取远程接口
  if (proxyApiUrl) {
    const proxyMiddleware = createProxyMiddleware({
      target: proxyApiUrl,
      changeOrigin: true,
    })
    app.use('*', proxyMiddleware);
  }
};
export default restful;

上面实现了几个方法

3、检查、生成Mock数据

原理:我们以目录为api请求路径,以文件名为请求方法。

不存在路由参数的请求:

存在路由参数的请求:

4、根据swagger json数据生成API返回数据

// 生成 Mock 值的示例函数
const generateMockValue = (schema, openAPIDoc) => {
    if (schema.$ref) {
        // 解析 $ref 并递归处理
        const resolvedSchema = resolveRef(schema.$ref, openAPIDoc);
        return generateMockValue(resolvedSchema, openAPIDoc);
    }
    switch (schema.type) {
      case 'string':
        return Mock.mock('@string(5, 10)');
      case 'number':
        return  Mock.mock('@integer(0, 1)');
      case 'integer':
        return  Mock.mock('@integer(0, 1)');
      case 'boolean':
        return true;
      case 'array':
        return [generateMockValue(schema.items, openAPIDoc)];
      case 'object':
        const mockObject = {};
        for (const [key, value] of Object.entries(schema.properties)) {
          mockObject[key] = generateMockValue(value, openAPIDoc);
        }
        return mockObject;
      default:
        return null;
    }
};

这里我们可以根据谁类型生成对应的mock数据,也可以通过配置文件来自定义生成规则。要注意的是swagger2.x和3.x的字段有些不同,需要做好不同情况的适配。

5、自动构建Docker镜像

通过Github构建不同的Docker镜像,发送Docker hub。

完成后发现启动这个API服务后,可以通过docker处理,这样也方便随时使用,镜像适配的平台不同,我们通过docker/build-push-action@v5,来配置platforms实现多个平台镜像的构建,然后通过Action推送到Docker hub

# 构建多平台镜像
- name: Build and push Docker image
  uses: docker/build-push-action@v5
  with:
      context: .
      platforms: linux/amd64,linux/arm64
      push: true
      tags: |
        ${{ secrets.DOCKER_USERNAME }}/dev-mock-cli:latest

四、总结

对于大部分mock来说,复杂的配置是不需要的,一个简单的服务,然后根据文档返回模拟数据,方便前端调试即可。