No nonsense, let’s get straight to the point. I’m using webpack 5.90.3 and here is my configuration for mocking.
- File structure
text
project_root/
|-- webpack.config.js
|-- mockserver.js
|-- mock/
|-- user.js - webpack.config.js
{{< admonition tip >}}
express.js doesn’t bundle with some plugins anymore so you need to run npm i -D body-parser. You will need body-parser to read params from request.
{{< /admonition >}}
“`javascript
const webpack = require(“webpack”);
var bodyParser = require(‘body-parser’)
const mockServer = require(“./mockserver.js”)
module.exports = (env, argv) => {
// … some code
return {
devServer: {
setupMiddlewares: (middlewares, devServer) => {
if (!devServer) {
throw new Error(‘webpack-dev-server is not defined’);
}
devServer.app.use(bodyParser.json())
devServer.app.use(mockServer());
// don't forget this line
return middlewares;
}
},
//... and so on
“`
- mockserver.js
mockserver.js returns an middleware(Java developers might rather call it aspect or filter) to express dev server.
“`javascript
const fs = require(“fs”);
const path = require(“path”);
module.exports = function () {
let mockDataPath = path.resolve(__dirname, “./mock/”);
let existsMockDir = fs.existsSync(mockDataPath);
let getMockData = () => {
if (existsMockDir) {
let modules = fs.readdirSync(mockDataPath);
return modules.reduce((pre, module) => {
return {
…pre,
…require(path.join(mockDataPath, “./” + module)),
};
}, {});
} else {
console.log(“please create a mock directory under your project root!”);
return {};
}
};
let splitApiPath = (mockData) => {
let data = {};
for (let path in mockData) {
let [method, apiPath, sleep] = path.split(" ");
let newApiPath = method.toLocaleUpperCase() + apiPath;
data[newApiPath] = {
path: newApiPath,
method,
sleep,
callback: mockData[path],
};
}
return data;
};
let delayFn = (sleep) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, sleep);
});
};
async function ret(req, res, next) {
let { path, method } = req;
console.log("mock server received request: %s %s", method, path);
if (path.indexOf("api") === -1 || !existsMockDir) {
return next();
}
let mockData = splitApiPath(getMockData());
let pathKey = method.toLocaleUpperCase() + path;
let { sleep, callback } = mockData[pathKey];
let isFuntion = callback.__proto__ === Function.prototype;
if (sleep && sleep > 0) {
await delayFn(sleep);
}
if (isFuntion) {
callback(req, res);
} else {
res.json({
...callback,
});
}
next();
}
return async (req, res, next) => {
// next();
return ret(req, res, next);
};
};
“`
- mock/user.js
user.js defines what and how you want to give to the client.
Feel free to add more, like data.js, product.js. mockserver.js will load them for you.
javascript
module.exports = {
"GET /api/v0/user/list": {
success: true,
code: 200,
data: {
list: [
{
name: "anyone",
age: 18,
},
],
},
},
// method path delay(ms)
"POST /api/v0/reset 1000": (req, res) => {
res.json({
success: true,
code: 200,
data: { username: req.body.username },
});
},
};
This article referenced juejin.cn, and I did some necessary changes to make it work with current webpack version.