mock-service-plugin
Version:
487 lines (403 loc) • 8.68 kB
Markdown
# mock-service-plugin
[English](README.md) | [中文](README-zh.md)
A powerful Mock service plugin that supports multiple frameworks and build tools, providing flexible interface simulation capabilities.
## Features
- 🚀 Support for multiple build tools
- Webpack 4/5
- Vite
- Vue CLI
- Create React App (CRA)
- 🎯 Support for multiple frameworks
- Vue
- React
- 🔥 Powerful feature support
- RESTful API support
- Streaming responses (SSE/EventStream)
- Multiple response formats (JSON/XML/CSV/Text etc.)
- Dynamic route parameters
- Request method matching (GET/POST/PUT/DELETE etc.)
- 💡 Easy to use
- Zero configuration startup
- Hot reload support
- Friendly debugging interface
## Quick Start
### Installation
```bash
npm install mock-service-plugin --save-dev
yarn add mock-service-plugin --dev
```
### Basic Configuration
```javascript
const MockServicePlugin = require("mock-service-plugin");
module.exports = {
plugins: [
new MockServicePlugin({
path: path.join(__dirname, "./mocks"), // mock data directory
port: 3000, // mock service port
}),
],
};
```
## Mock Data Specification
### Basic Format
```javascript
/**
* @url /api/users
* @method GET
*/
{
"code": 200,
"data|5-10": [{
"id": "@id",
"name": "@cname",
"email": "@email"
}],
"message": "success"
}
```
### Header Annotation Description
```javascript
/**
* @url /api/users
* @method GET
*/
```
- `@url`: Interface path (required)
- `@method`: Request method (optional, supports GET/POST/PUT/DELETE etc., case-insensitive)
### Request Method Matching
1. Specify request method:
```javascript
/**
* @url /api/users
* @method POST
*/
{
"code": 200,
"message": "Created successfully"
}
```
2. Support all request methods (without @method):
```javascript
/**
* @url /api/users
*/
{
"code": 200,
"data": {
"id": "@id",
"name": "@cname"
}
}
```
3. RESTful API example:
```javascript
// POST request
/**
* @url /api/users
* @method POST
*/
{
"code": 200,
"message": "Created successfully"
}
// GET request
/**
* @url /api/users/:id
* @method GET
*/
{
"id": "@id",
"name": "@cname"
}
// PUT request
/**
* @url /api/users/:id
* @method PUT
*/
{
"code": 200,
"message": "Updated successfully"
}
// DELETE request
/**
* @url /api/users/:id
* @method DELETE
*/
{
"code": 200,
"message": "Deleted successfully"
}
```
### Supported Response Types
| Mock file extension | Content-Type | Description |
| ------------------- | ---------------------- | ----------------- |
| .json | application/json | JSON data format |
| .txt | text/plain | Plain text format |
| .html | text/html | HTML document |
| .xml | application/xml | XML data format |
| .csv | text/csv | CSV table data |
| .md | text/markdown | Markdown document |
| .pdf | application/pdf | PDF document |
| .png | image/png | PNG image |
| .jpg/.jpeg | image/jpeg | JPEG image |
| .gif | image/gif | GIF image |
| .svg | image/svg+xml | SVG vector image |
| .css | text/css | CSS stylesheet |
| .js | application/javascript | JavaScript code |
| .yaml/.yml | application/x-yaml | YAML config file |
| .sse | text/event-stream | SSE event stream |
### Mock File Examples
#### JSON Format (mock.json)
```javascript
/**
* @url /api/users
* @method GET
*/
{
"code": 200,
"data": {
"name": "@cname",
"age": "@integer(18, 60)"
}
}
```
#### Text Format (mock.txt)
```javascript
/**
* @url /api/text
* @method GET
*/
This is a mock text content, supporting multiple lines.
Second line content.
Third line content.
```
#### CSS Format (mock.css)
```javascript
/**
* @url /api/styles
* @method GET
*/
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
```
#### Markdown Format (mock.md)
```javascript
/**
* @url /api/markdown
* @method GET
*/
# Heading 1
## Heading 2
- List item 1
- List item 2
```
#### YAML Format (mock.yaml)
```javascript
/**
* @url /api/config
* @method GET
*/
version: 1.0;
settings: debug: true;
timeout: 30;
```
#### CSV Format (mock.csv)
```javascript
/**
* @url /api/data
* @method GET
*/
id, name, age;
1, John, 25;
2, Jane, 30;
3, Bob, 28;
```
#### XML Format (mock.xml)
```javascript
/**
* @url /api/xml
* @method GET
*/
<?xml version="1.0" encoding="UTF-8"?>
<root>
<user>
<name>John</name>
<age>25</age>
</user>
</root>
```
#### JavaScript Format (mock.js)
```javascript
/**
* @url /api/script
* @method GET
*/
function greeting(name) {
return `Hello, ${name}!`;
}
```
For image type responses, you can directly return the image file path:
```javascript
/**
* @url /api/avatar
* @content-type image/png
*/
"/path/to/avatar.png";
```
## Advanced Features
### RESTful API Support
```javascript
/**
* @url /api/users/:id
* @method GET
*/
{
"id": "@id",
"name": "@cname",
"email": "@email"
}
```
### Streaming Response
File extension: mock.sse
```javascript
/**
* @url /api/stream
*/
{
"interval": "@integer(100,500)",
"items|10": [{
"id": "@increment(1)",
"data": {
"content": "@csentence(3,10)"
}
}]
}
```
## Framework Integration
### Vue Project
```javascript
// vue.config.js
const MockServicePlugin = require("mock-service-plugin");
module.exports = {
configureWebpack: {
plugins: [
new MockServicePlugin({
path: path.join(__dirname, "./mocks"),
port: 9090,
}),
],
},
devServer: {
proxy: {
"/api": {
target: "http://localhost:9090",
pathRewrite: { "^/api": "" },
},
},
},
};
```
### React Project (CRA)
#### Using craco
```javascript
// craco.config.js
const MockServicePlugin = require("mock-service-plugin");
module.exports = {
webpack: {
plugins: {
add: [
new MockServicePlugin({
path: path.join(__dirname, "./mocks"),
port: 9090,
}),
],
},
},
};
```
#### Using customize-cra
```javascript
// config-overrides.js
const { override, addWebpackPlugin } = require("customize-cra");
const MockServicePlugin = require("mock-service-plugin");
module.exports = override(
addWebpackPlugin(
new MockServicePlugin({
path: path.join(__dirname, "./mocks"),
port: 9090,
})
)
);
```
### Vite Project
```ts
// vite-mock-plugin.ts file
import MockServicePlugin from "mock-service-plugin";
import { createServer } from "net";
import { join } from "path";
function isPortTaken(port: number) {
return new Promise((resolve) => {
const server = createServer();
server.once("error", (err: { code: string }) => {
if (err.code === "EADDRINUSE") {
resolve(true);
} else {
resolve(false);
}
});
server.once("listening", () => {
server.close();
resolve(false);
});
server.listen(port);
});
}
export default function ViteMockServicePlugin(e: string) {
return {
name: "ViteMockServicePlugin",
buildStart() {
(async () => {
const port = 3008;
const portTaken = await isPortTaken(port);
if (portTaken) {
console.log(`Port ${port} is already in use`);
} else {
if (e === "mock") {
const ints = new MockServicePlugin({
// Path for mock data
path: join(__dirname, "./mocks"),
// Configure mock service port to avoid conflicts with application port
port: 3008,
});
ints.apply();
}
}
})();
},
};
}
```
```typescript
// vite.config.ts
import { defineConfig } from "vite";
// The vite-mock-plugin imported here is the code snippet above
import ViteMockServicePlugin from "./vite-mock-plugin";
export default defineConfig({
plugins: [ViteMockServicePlugin("development")],
});
```
## Example Projects
- [Vue Example](https://github.com/bianliuzhu/vite-vue-ts)
- [React Example](https://github.com/bianliuzhu/react-app-ts)
## Notes
1. Page refresh required after modifying mock data
2. Ensure mock service port doesn't conflict with application port
3. Recommended to use relative paths for mock data directory configuration
## Contributing
Issues and Pull Requests are welcome
## License
MIT