不說廢話,直接開始。我使用 webpack 5.90.3,以下是我的配置。
文件結構
1project_root/ 2 |-- webpack.config.js 3 |-- mockserver.js 4 |-- mock/ 5 |-- user.js
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
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};
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 上運行。