1 | # Webpack Mock Server
|
2 |
|
3 | ExpressJs Middleware for webpack-dev-server with built-in hot-replacement (HMR) and typescript compiler.
|
4 | Uses for mocking api responses
|
5 |
|
6 | [![npm version](https://img.shields.io/npm/v/webpack-mock-server.svg?style=flat-square)](https://www.npmjs.com/package/webpack-mock-server)
|
7 | [![install size](https://packagephobia.now.sh/badge?p=webpack-mock-server)](https://packagephobia.now.sh/result?p=webpack-mock-server)
|
8 | [![npm downloads](https://img.shields.io/npm/dm/webpack-mock-server.svg?style=flat-square)](http://npm-stat.com/charts.html?package=webpack-mock-server)
|
9 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
|
10 |
|
11 | ## Features
|
12 |
|
13 | - Typescript support (>=v2.7): supports **.js**, **.ts**, **.json** files
|
14 | - ES6 export/import support
|
15 | - Hot replacement support
|
16 | - Does not require proxy-path-pattern (because this is middleware that pipes routes to splitted server without proxy-path-pattern)
|
17 | - Can be used without webpack (because this is expressjs [middleware](http://expressjs.com/en/guide/using-middleware.html))
|
18 | - Shows every configured response in user-friendly _index.html_ (just click on mock-server-url in console after as mockServer is started)
|
19 |
|
20 | ## Installing
|
21 |
|
22 | Using npm (installing Typescript is required even if you don't use ts files):
|
23 |
|
24 | ```npm
|
25 | npm install --save-dev webpack-mock-server typescript
|
26 | ```
|
27 |
|
28 | ## Examples
|
29 |
|
30 | ### Usage with defaults
|
31 |
|
32 | ```js
|
33 | // webpack.config.js
|
34 | const webpackMockServer = require("webpack-mock-server");
|
35 |
|
36 | module.exports = {
|
37 | devServer: {
|
38 | before: webpackMockServer.use
|
39 | }
|
40 | };
|
41 |
|
42 | // webpack.mock.ts - feel free to mock responses yourself
|
43 | import webpackMockServer from "webpack-mock-server";
|
44 | import nodePath from "path";
|
45 |
|
46 | // app is expressjs application
|
47 | export default webpackMockServer.add((app, helper) => {
|
48 | // you can find more about expressjs here: https://expressjs.com/
|
49 | app.get("/testGet", (_req, res) => {
|
50 | res.json("JS get-object can be here. Random int:" + helper.getRandomInt());
|
51 | });
|
52 | app.post("/testPost", (_req, res) => {
|
53 | res.json("JS post-object can be here");
|
54 | });
|
55 |
|
56 | // you can return any file easy. Example for json response from file:
|
57 | app.get("/testResponseFromJsonFile", (_req, res) => {
|
58 | res.sendFile(nodePath.join(__dirname, "./response.json"));
|
59 | });
|
60 | });
|
61 |
|
62 | // multiple exports are supported
|
63 | export const result = webpackMockServer.add((app, helper) => {
|
64 | app.delete("/testDelete", (_req, res) => {
|
65 | res.json(
|
66 | "JS delete-object can be here. Random int:" + helper.getRandomInt()
|
67 | );
|
68 | });
|
69 | app.pust("/testPut", (_req, res) => {
|
70 | res.json("JS put-object can be here");
|
71 | });
|
72 | });
|
73 | ```
|
74 |
|
75 | ### Usage with multiple/custom entries (instead of default **webpack.mock.ts**)
|
76 |
|
77 | ```js
|
78 | // webpack.config.js
|
79 | const webpackMockServer = require("webpack-mock-server");
|
80 |
|
81 | module.exports = {
|
82 | devServer: {
|
83 | before: app =>
|
84 | webpackMockServer.use(app, { // MockServerOptions here
|
85 | entry: [ // exact fileNames are expected (no wildcard or folder - use custom tsConfig instead)
|
86 | "api/users.mock.ts",
|
87 | "api/goods.mock.js"
|
88 | ],
|
89 | before: (req, res, next) => { // you can use this for custom-logging instead of logResponses: true, logRequests: true
|
90 | console.log(`Got request: ${req.method} ${req.url}`);
|
91 | res.once("finish", () => {
|
92 | console.log(`Sent response: ${req.method} ${req.url}`);
|
93 | })
|
94 | next();
|
95 | }
|
96 | })
|
97 | }
|
98 | }
|
99 |
|
100 | // api/users.mock.ts
|
101 | ... // take the example for ts-file above
|
102 |
|
103 | // api/goods.mock.js
|
104 | export default webpackMockServer.add((app, helper) => {
|
105 | app.get("/testGetGoods", (_req, res) => {
|
106 | res.json([{
|
107 | id: helper.getRandomInt(1, 999),
|
108 | name: "pen"
|
109 | }]);
|
110 | });
|
111 | })
|
112 | ```
|
113 |
|
114 | ### Usage with multiple entries by pattern (wildcard)
|
115 |
|
116 | ```js
|
117 | // webpack.config.js
|
118 | const webpackMockServer = require("webpack-mock-server");
|
119 |
|
120 | // for webpack v4
|
121 | module.exports = {
|
122 | devServer: {
|
123 | before: app =>
|
124 | webpackMockServer.use(app, {
|
125 | /* set an empty-array or null to [entry], so entry will be defined
|
126 | from 'files' and 'includes' sections in [tsConfigFileName]
|
127 | */
|
128 | entry: [],
|
129 | tsConfigFileName: "mock/tsconfig.json" // use a different tsconfig-file that is contained entries
|
130 | })
|
131 | }
|
132 | }
|
133 |
|
134 | // for webpack v5
|
135 | module.exports = {
|
136 | devServer: {
|
137 | onBeforeSetupMiddleware: devServer => // it's different for wepback v4
|
138 | webpackMockServer.use(devServer.app, {
|
139 | /* set an empty-array or null to [entry], so entry will be defined
|
140 | from 'files' and 'includes' sections in [tsConfigFileName]
|
141 | */
|
142 | entry: [],
|
143 | tsConfigFileName: "mock/tsconfig.json" // use a different tsconfig-file that is contained entries
|
144 | })
|
145 | }
|
146 | }
|
147 |
|
148 | // ./mock/tsconfig.json
|
149 | {
|
150 | /*
|
151 | this is ordinary tsconfig file that overrides every option from [extends] - main tsconfig-file
|
152 | */
|
153 | "extends": "../tsconfig.json", // you can point the main tsconfig file or remove that property if it's not required
|
154 | "include": [ // wildcard-pattern is supported
|
155 | "../mock/*",
|
156 | "*.mock.ts"
|
157 | ],
|
158 | "files": [], // beside 'include' option you can point exact files here
|
159 | "exclude": ["*test.mock.ts"] // note: exclude option can override 'include' and 'files' options
|
160 | }
|
161 |
|
162 | ```
|
163 |
|
164 | ### Usage without webpack
|
165 |
|
166 | As expressjs middleware: <http://expressjs.com/en/guide/using-middleware.html>
|
167 |
|
168 | ```js
|
169 | // webpack.config.js
|
170 | const webpackMockServer = require("webpack-mock-server");
|
171 |
|
172 | const express = require('express');
|
173 | const app = express();
|
174 |
|
175 | webpackMockServer.use(app, {/*mockServerOptions*/})
|
176 | ...
|
177 | app.listen(1782);
|
178 |
|
179 | // webpack.mock.ts - example you can find above
|
180 | ...
|
181 | ```
|
182 |
|
183 | ### Usage with the whole default config
|
184 |
|
185 | #### for webpack [v5+](https://webpack.js.org/configuration/dev-server/#devserveronbeforesetupmiddleware)
|
186 |
|
187 | ```js
|
188 | // webpack.config.js
|
189 | ...
|
190 | const webpackMockServer = require("webpack-mock-server");
|
191 |
|
192 | module.exports = {
|
193 | devServer: {
|
194 | onBeforeSetupMiddleware: devServer => // it's different for wepback v4
|
195 | webpackMockServer.use(devServer.app, {
|
196 | port: 8079, // app searches for free port (starts searching from pointed)
|
197 | verbose: false, // send info via console.log
|
198 | logRequests: false,
|
199 | logResponses: false,
|
200 | before: undefined, //can be used for logging
|
201 | entry: ["webpack.mock.ts"],
|
202 | tsConfigFileName: "tsconfig.json",
|
203 | compilerOptions: { // typescript.CompilerOptions that override tsconfig.json:[compilerOptions]
|
204 | strictNullChecks: false,
|
205 | noImplicitAny: false,
|
206 | noUnusedLocals: false,
|
207 | noUnusedParameters: false,
|
208 | skipLibCheck: true,
|
209 | resolveJsonModule: true
|
210 | },
|
211 | strictCompilerOptions: { // these options impossible to override
|
212 | outDir: "" // used the following: {os.tmpdir()}/webpack-mock-server/{new Date().getTime()}
|
213 | rootDir: process.cwd(),
|
214 | noEmit: false,
|
215 | noEmitHelpers: false,
|
216 | esModuleInterop: true,
|
217 | module: ts.ModuleKind.CommonJS,
|
218 | declaration: false,
|
219 | moduelResolution: ModuleResolutionKind.NodeJs,
|
220 | target: defineTarget() // it defines target-ES based on NODE version
|
221 | }
|
222 | })
|
223 | }
|
224 | }
|
225 |
|
226 | // webpack.mock.ts - example you can find above
|
227 | ...
|
228 | ```
|
229 |
|
230 | #### for webpack v4
|
231 |
|
232 | ```js
|
233 | // webpack.config.js
|
234 | ...
|
235 | const webpackMockServer = require("webpack-mock-server");
|
236 |
|
237 | module.exports = {
|
238 | devServer: {
|
239 | before: app => // it's different for wepback v5
|
240 | webpackMockServer.use(app, {
|
241 | port: 8079, // app searches for free port (starts searching from pointed)
|
242 | verbose: false, // send info via console.log
|
243 | logRequests: false,
|
244 | logResponses: false,
|
245 | before: undefined, //can be used for logging
|
246 | entry: ["webpack.mock.ts"],
|
247 | tsConfigFileName: "tsconfig.json",
|
248 | compilerOptions: { // typescript.CompilerOptions that override tsconfig.json:[compilerOptions]
|
249 | strictNullChecks: false,
|
250 | noImplicitAny: false,
|
251 | noUnusedLocals: false,
|
252 | noUnusedParameters: false,
|
253 | skipLibCheck: true,
|
254 | resolveJsonModule: true
|
255 | },
|
256 | strictCompilerOptions: { // these options impossible to override
|
257 | outDir: "" // used the following: {os.tmpdir()}/webpack-mock-server/{new Date().getTime()}
|
258 | rootDir: process.cwd(),
|
259 | noEmit: false,
|
260 | noEmitHelpers: false,
|
261 | esModuleInterop: true,
|
262 | module: ts.ModuleKind.CommonJS,
|
263 | declaration: false,
|
264 | moduelResolution: ModuleResolutionKind.NodeJs,
|
265 | target: defineTarget() // it defines target-ES based on NODE version
|
266 | }
|
267 | })
|
268 | }
|
269 | }
|
270 |
|
271 | // webpack.mock.ts - example you can find above
|
272 | ...
|
273 | ```
|
274 |
|
275 | ## Options
|
276 |
|
277 | **Note:** Every path-file-name in options has to be pointed relative to the _currentWorkingDirectory_ (_process.cwd()_ in NodeJs) **or** point an absolute path
|
278 |
|
279 | | Param | Type | Default | Description |
|
280 | | --------------------- | -------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
281 | | entry | String, String[], null | ["webpack.mock.ts"] | Entry points for typescript-compiler (exact fileNames are expected). Set an **empty array** or **null** for using **files**, **include** and **exlcude** sections from _tsConfigFileName_. Otherwise these sections are ignored! |
|
282 | | port | Number | 8079 | App searches for free port (starts searching from pointed) |
|
283 | | verbose | Boolean | false | Show debug info in NodeJs via console.log |
|
284 | | logResponses | Boolean | false | Show responses-info in NodeJs via console.log |
|
285 | | logRequests | Boolean | false | Show request-info in NodeJs via console.log |
|
286 | | before | (req, res, next) => void | undefined | Execute custom middleware prior to all other middleware internally within the server Can be used for custom-logging. Example [here](#usage-with-multiplecustom-entries-instead-of-default-webpackmockts) |
|
287 | | compilerOptions | typescript.CompilerOptions | ... | See the latest example above |
|
288 | | strictCompilerOptions | typescript.CompilerOptions | ... | **readOnly**. See the latest example above. These options impossible to override |
|
289 | | tsConfigFileName | String | "tsconfig.json" | Pointer to typescript config file. Example [here](#usage-with-multiple-entries-by-pattern-wildcard): |
|
290 |
|
291 | ## MockServerHelper. Methods
|
292 |
|
293 | - [**.getRandomInt**(min = 0, max = 2147483648)](#MockServerHelper._Methods) ⇒ `Number - returns random integer between min and max`
|
294 | - [**.getUniqueIdInt**()](#MockServerHelper._Methods) ⇒ `Number - returns unique integer`
|
295 |
|
296 | ## Troubleshooting
|
297 |
|
298 | - It's important to install Typescript even if use only JS-files (webpack-mock-server uses ts-compiler for gathering ts,js,json files)
|
299 | - Don't use NodeJs **require** operator **as dynamic** to relative path. Use **dirname in this case or absolute path (**dirname is changed during the compilation)
|
300 | - NodeJs caches every **require**d module (file), so you maybe interested in clearing cache for _require(_.json)\*.
|
301 | Use `delete require.cache[require.resolve({yourPathName})]` before you call `require({yourPathName})`;
|
302 |
|
303 | ```js
|
304 | // Wrong
|
305 | app.get("/testResponseFromJsonFile", (_req, res) => {
|
306 | res.sendFile(require.resolve("./response.json"));
|
307 | });
|
308 |
|
309 | app.get("/testResponseFromJsonFile2", (_req, res) => {
|
310 | res.json(require("./response.json"));
|
311 | });
|
312 |
|
313 | // Good
|
314 | import nodePath from "path";
|
315 |
|
316 | app.get("/testResponseFromJsonFile", (_req, res) => {
|
317 | res.sendFile(nodePath.join(__dirname, "./response.json"));
|
318 | });
|
319 |
|
320 | app.get("/testResponseFromJsonFile2", (_req, res) => {
|
321 | /* From NodeJs v8.9.0 you can use options: path
|
322 | * const resolvedPath = require.resolve("./response.json", { paths: [__dirname] });
|
323 | */
|
324 | const resolvedPath = require.resolve(
|
325 | nodePath.join(__dirname, "./response.json")
|
326 | );
|
327 | // removing NodeJS cache for getting the latest file
|
328 | delete require.cache[resolvedPath];
|
329 | res.json(require(resolvedPath));
|
330 | });
|
331 | ```
|