webpack 5 mock 10分鐘快速配置

Webpack Mock Configuration

不說廢話,直接開始。我使用 webpack 5.90.3,以下是我的配置。

  1. 文件結構

    1project_root/
    2  |-- webpack.config.js
    3  |-- mockserver.js
    4  |-- mock/
    5    |-- user.js
    
  2. webpack.config.js

    因爲 express 現在不再附帶 body-parser,現在需要執行 npm i -D body-parser。如果你希望讀取 request 裏面的內容,你會需要這個插件。

     1const webpack = require("webpack");
     2var bodyParser = require('body-parser')
     3const mockServer = require("./mockserver.js")
     4
     5module.exports = (env, argv) => {
     6    // ... some code
     7    return {
     8        devServer: {
     9            setupMiddlewares: (middlewares, devServer) => {
    10                if (!devServer) {
    11                    throw new Error('webpack-dev-server is not defined');
    12                }
    13
    14                devServer.app.use(bodyParser.json())
    15                devServer.app.use(mockServer());
    16                // don't forget this line
    17                return middlewares;
    18            }
    19        },
    20        //... and so on
    
  3. mockserver.js

    mockserver.js 返回給 express dev server 需要的一箇中間件(其實在java開發看來,這個東西習慣稱爲切面或過濾器)。

     1const fs = require("fs");
     2const path = require("path");
     3
     4module.exports = function () {
     5  let mockDataPath = path.resolve(__dirname, "./mock/");
     6  let existsMockDir = fs.existsSync(mockDataPath);
     7  let getMockData = () => {
     8    if (existsMockDir) {
     9      let modules = fs.readdirSync(mockDataPath);
    10      return modules.reduce((pre, module) => {
    11        return {
    12          ...pre,
    13          ...require(path.join(mockDataPath, "./" + module)),
    14        };
    15      }, {});
    16    } else {
    17      console.log("please create a mock directory under your project root!");
    18      return {};
    19    }
    20  };
    21
    22  let splitApiPath = (mockData) => {
    23    let data = {};
    24    for (let path in mockData) {
    25      let [method, apiPath, sleep] = path.split(" ");
    26      let newApiPath = method.toLocaleUpperCase() + apiPath;
    27      data[newApiPath] = {
    28        path: newApiPath,
    29        method,
    30        sleep,
    31        callback: mockData[path],
    32      };
    33    }
    34    return data;
    35  };
    36
    37  let delayFn = (sleep) => {
    38    return new Promise((resolve) => {
    39      setTimeout(() => {
    40        resolve();
    41      }, sleep);
    42    });
    43  };
    44
    45  async function ret(req, res, next) {
    46    let { path, method } = req;
    47    console.log("mock server received request: %s %s", method, path);
    48
    49    if (path.indexOf("api") === -1 || !existsMockDir) {
    50      return next();
    51    }
    52    let mockData = splitApiPath(getMockData());
    53    let pathKey = method.toLocaleUpperCase() + path;
    54    let { sleep, callback } = mockData[pathKey];
    55    let isFuntion = callback.__proto__ === Function.prototype;
    56    if (sleep && sleep > 0) {
    57      await delayFn(sleep);
    58    }
    59    if (isFuntion) {
    60      callback(req, res);
    61    } else {
    62      res.json({
    63        ...callback,
    64      });
    65    }
    66    next();
    67  }
    68
    69  return async (req, res, next) => {
    70    // next();
    71    return ret(req, res, next);
    72  };
    73};
    
  4. mock/user.js

    user.js 裏面定義 mock 的數據以及如何返回。 可以按模塊多寫幾個js, 都會自動加載。

     1module.exports = {
     2  "GET /api/v0/user/list": {
     3    success: true,
     4    code: 200,
     5    data: {
     6      list: [
     7        {
     8          name: "anyone",
     9          age: 18,
    10        },
    11      ],
    12    },
    13  },
    14  // method path delay(ms)
    15  "POST /api/v0/reset 1000": (req, res) => {
    16    res.json({
    17      success: true,
    18      code: 200,
    19      data: { username: req.body.username },
    20    });
    21  },
    22};
    

本文參考了掘金文章,我做了些改動以便讓它能夠在 webpack5 上運行。