When developing web applications based on API interaction and separation of front and back ends, we often encounter several problems:
- The front end page is choreographed, but the back end interface is not ready, or suddenly buggy, so there is no way to do docking testing.
- We want the server to return certain types of data to test if a page has a problem under certain conditions, but as a front end we generally don’t have access to back-end code and databases, and it’s a hassle to have to go to the back end to add simulated data every time.
The simplest solution to both of these problems is to build a mock Server that returns only the mock data you need.
Webpack-dev-server is an essential tool for vue and React development. The before hook of webpack-dev-server can be used to add mock Server functions to webpack-dev-server. There is no need to build a separate server.
After a bit of searching, I found this article and the webpack middleware Webpack-api-Mocker. With a few modifications webpack-dev-server can be used as a mock server. In addition, different HTTP methods such as GET, POST and PATCH under the same URL are processed separately, and hot swap is supported.
To use it, add a new hook before in the devServer of webpack.dev.conf.js to hand over all requests to apiMocker, and then change the request URL to the WebPack server when you need to use mock data.
npm install webpack-api-mocker --save-dev
Copy the code
const apiMocker = require('webpack-api-mocker')
config = {
...
devServer: {
before(app) {
apiMocker(app, path.resolve('mock/api.js'))}}... }Copy the code
api.js
const fs = require('fs');
function fromJSONFile(filename) {
return (req, res) => {
const data = fs.readFileSync(`mock/data/${filename}.json`).toString();
const json = JSON.parse(data);
return res.json(json);
};
}
const proxy = {
'GET /app/user/profile': fromJSONFile('profile'),}; module.exports = proxy;Copy the code
Modify the URL
axios.get('user/info').then(...)
// Modify the URL with a prefix
axios.get('http://127.0.0.1:8080/' + 'user/info').then(...)
Copy the code
further
After the above steps, the Mock Server is almost ready to run, but still a little unfriendly. Each time you need to use mock data, you have to modify the project source code, rewrite the URL of the request, and then change it back after testing. If the request is used in multiple places within the source code, there are many changes, which can be troublesome. We can make some improvements.
The idea is to start the Mock Server and send all requests to the API server to the WebPack Server, which intercepts and processes all interface requests that have mock data defined, and forward undefined interface requests to the API server.
The author of the project mentioned above has merged my PR, the following paragraph can be ignored, continue to use the above onewebpack-api-mocker
First of all, we need to improve the middleware webpack-apI-Mocker used before. The modified code is on my Github, and the plug-in is mainly a file index.js, which can be copied and used directly. You can look at the commit log
Then add a new NPM command dev-mock to define an environment variable mock to control whether or not mock Server is enabled:
"script": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
+ "dev-mock": "MOCK=true webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
}
Copy the code
In WebPack Config MOCK Server is enabled only when the MOCK variable exists
config = {
...
devServer: {
if (process.env.MOCK) {
before(app) {
apiMocker(app, path.resolve('mock/api.js'), {
proxy: {
'/app//*': 'http://api.leaderlegend.com',}}); }}}... }Copy the code
To MOCK the environment variable in our code, we pass that value in WebPack Config. Passing Environment-dependent variables in webpack
config = {
...
devServer: ...
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: process.env.NODE_ENV,
MOCK: process.env.MOCK, } }), ... ] . }Copy the code
MOCK the environment variable to determine the API server address, and it’s best to keep the first path the same for easier forwarding
const BASE_URL = process.env.MOCK ? 'http://127.0.0.1:8080/app/' : 'http://api.harlanluo.com/app/';
Copy the code
This is all done. Use the NPM run dev-mock command when you need to use mock data, or NPM run dev when you don’t, without making any changes to the project’s source code pairs.