Webpack Mock Server
ExpressJs Middleware for webpack-dev-server with built-in hot-replacement (HMR) and typescript compiler.
Uses for mocking api responses
Features
- Typescript support (>=v2.7): supports .js, .ts, .json files
- ES6 export/import support
- Hot replacement support
- Does not require proxy-path-pattern (because this is middleware that pipes routes to splitted server without proxy-path-pattern)
- Can be used without webpack (because this is expressjs middleware)
- Shows every configured response in user-friendly index.html (just click on mock-server-url in console after as mockServer is started)
Installing
Using npm (installing Typescript is required even if you don't use ts files):
npm i --save-dev webpack-mock-server typescript @types/express
Examples
Usage with defaults
const webpackMockServer = require("webpack-mock-server");
module.exports = {
devServer: {
setupMiddlewares: (middlewares, devServer) => {
webpackMockServer.use(devServer.app);
return middlewares;
},
},
};
import webpackMockServer from "webpack-mock-server";
import nodePath from "path";
export default webpackMockServer.add((app, helper) => {
app.get("/testGet", (_req, res) => {
res.json("JS get-object can be here. Random int:" + helper.getRandomInt());
});
app.post("/testPost", (_req, res) => {
res.json("JS post-object can be here");
});
app.get("/testResponseFromJsonFile", (_req, res) => {
res.sendFile(nodePath.join(__dirname, "./response.json"));
});
});
export const result = webpackMockServer.add((app, helper) => {
app.delete("/testDelete", (_req, res) => {
res.json(
"JS delete-object can be here. Random int:" + helper.getRandomInt()
);
});
app.put("/testPut", (_req, res) => {
res.json("JS put-object can be here");
});
});
Usage with multiple/custom entries (instead of default webpack.mock.ts)
const webpackMockServer = require("webpack-mock-server");
module.exports = {
devServer: {
setupMiddlewares: (middlewares, devServer) => {
webpackMockServer.use(devServer.app, {
entry: [
"api/users.mock.ts",
"api/goods.mock.js"
],
before: (req, res, next) => {
console.log(`Got request: ${req.method} ${req.url}`);
res.once("finish", () => {
console.log(`Sent response: ${req.method} ${req.url}`);
})
next();
}
});
return middlewares;
}
}
}
...
export default webpackMockServer.add((app, helper) => {
app.get("/testGetGoods", (_req, res) => {
res.json([{
id: helper.getRandomInt(1, 999),
name: "pen"
}]);
});
})
Usage with multiple entries by pattern (wildcard)
const webpackMockServer = require("webpack-mock-server");
module.exports = {
devServer: {
before: app =>
webpackMockServer.use(app, {
entry: [],
tsConfigFileName: "mock/tsconfig.json"
})
}
}
module.exports = {
devServer: {
setupMiddlewares: (middlewares, devServer) => {
webpackMockServer.use(devServer.app, {
entry: [],
tsConfigFileName: "mock/tsconfig.json"
});
return middlewares;
}
}
}
{
"extends": "../tsconfig.json",
"include": [
"../mock/*",
"*.mock.ts",
"**/global.d.ts",
],
"files": [],
"exclude": ["*test.mock.ts"]
}
Usage without webpack
As Express middleware: http://expressjs.com/en/guide/using-middleware.html
const webpackMockServer = require("webpack-mock-server");
const express = require('express');
const app = express();
webpackMockServer.use(app, {})
...
app.listen(1782);
...
Usage with the whole default config
for webpack v5+
...
const webpackMockServer = require("webpack-mock-server");
module.exports = {
devServer: {
setupMiddlewares: (middlewares, devServer) => {
webpackMockServer.use(devServer.app, {
port: 8079,
verbose: false,
logRequests: false,
logResponses: false,
before: undefined,
entry: ["webpack.mock.ts"],
tsConfigFileName: "tsconfig.json",
compilerOptions: {
strictNullChecks: false,
noImplicitAny: false,
noUnusedLocals: false,
noUnusedParameters: false,
skipLibCheck: true,
resolveJsonModule: true
},
strictCompilerOptions: {
outDir: ""
rootDir: process.cwd(),
noEmit: false,
noEmitHelpers: false,
esModuleInterop: true,
module: ts.ModuleKind.CommonJS,
declaration: false,
moduleResolution: ModuleResolutionKind.Node10,
target: defineTarget()
}
});
return middlewares;
}
}
}
...
for webpack v4
...
const webpackMockServer = require("webpack-mock-server");
module.exports = {
devServer: {
before: app =>
webpackMockServer.use(app, {
port: 8079,
verbose: false,
logRequests: false,
logResponses: false,
before: undefined,
entry: ["webpack.mock.ts"],
tsConfigFileName: "tsconfig.json",
compilerOptions: {
strictNullChecks: false,
noImplicitAny: false,
noUnusedLocals: false,
noUnusedParameters: false,
skipLibCheck: true,
resolveJsonModule: true
},
strictCompilerOptions: {
outDir: ""
rootDir: process.cwd(),
noEmit: false,
noEmitHelpers: false,
esModuleInterop: true,
module: ts.ModuleKind.CommonJS,
declaration: false,
moduleResolution: ModuleResolutionKind.Node10,
target: defineTarget()
}
})
}
}
...
Options
Note: Every path-file-name in options has to be pointed relative to the currentWorkingDirectory (process.cwd() in NodeJs) or point an absolute path
Param | Type | Default | Description |
---|
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! |
port | Number | 8079 | App searches for free port (starts searching from pointed) |
verbose | Boolean | false | Show debug info in NodeJs via console.log |
logResponses | Boolean | false | Show responses-info in NodeJs via console.log |
logRequests | Boolean | false | Show request-info in NodeJs via console.log |
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 |
compilerOptions | typescript.CompilerOptions | ... | See the latest example above |
strictCompilerOptions | typescript.CompilerOptions | ... | readOnly. See the latest example above. These options impossible to override |
tsConfigFileName | String | "tsconfig.json" | Pointer to typescript config file. Example here: |
MockServerHelper. Methods
Troubleshooting
- It's important to install Typescript even if use only JS-files (webpack-mock-server uses ts-compiler for gathering ts,js,json files)
- 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)
- NodeJs caches every required module (file), so you maybe interested in clearing cache for require(.json)*.
Use
delete require.cache[require.resolve({yourPathName})]
before you call require({yourPathName})
; - Mockserver can't compile the TS-code.
Possible reason: you have some extra import OR missed some global files (like
global.d.ts
).
Solution: all mock-files must be without dependencies (imports) of components defined in the main-project files
- If you have custom
tsconfig.mock.json
file check if all required \*d.ts
files are included .. include: ["**/global.d.ts", ..] ..
- To check what's wrong check compilation trace
npx tsc --project tsconfig.mock.json --generateTrace traceDir
OR enable logging via option verbose:true
app.get("/testResponseFromJsonFile", (_req, res) => {
res.sendFile(require.resolve("./response.json"));
});
app.get("/testResponseFromJsonFile2", (_req, res) => {
res.json(require("./response.json"));
});
import nodePath from "path";
app.get("/testResponseFromJsonFile", (_req, res) => {
res.sendFile(nodePath.join(__dirname, "./response.json"));
});
app.get("/testResponseFromJsonFile2", (_req, res) => {
const resolvedPath = require.resolve(
nodePath.join(__dirname, "./response.json")
);
delete require.cache[resolvedPath];
res.json(require(resolvedPath));
});