Mock data is a very meaningful thing, and the front and back end can be developed in parallel because of the fake data generated by mock. In the spare time, easy-config-mock is a wheel. The following is a record of the implementation idea and all the code technical details of the final implementation
concerns
Document your concerns during development:
How to implement mock data functionality (Technology selection)
Use MockJS to generate fake data (mock rules)
Build service with Express (attached: Express official website)
How does it integrate into scaffolding, or workflows
Designed to be as simple as possible so that it is easy to integrate into existing scaffolding or workflows, easy-config-Mock does just that:
const easyConfigMock = require('easy-config-mock')
new easyConfigMock({
// If you pass in the configuration file path, the service will automatically listen for file changes and restart the service
path: path.resolve(__dirname, 'mock.config.js')})Copy the code
How does it work with the project
It is recommended to place mock data configuration files in the root directory of the project because mock data is closely related to the business and is easy to view and maintain when thrown together, as follows:
+ vue-preject-node_modules-src mock.config.js // Mock data configuration file. The name is only used as an exampleCopy the code
How can more complex scenarios be supported
Mockjs is powerful enough to generate random fake data, but this is not enough in very complex business scenarios, where the expectation is that you can customize the return of the mock interface to validate the display logic
This can be done thanks to express middleware. Take a look at the configuration file in easy-config-mock
// mock.config.js
module.exports = {
// The common option is not required, you can do without it, the built-in configuration is as follows, of course you can change it
common: {
// The mock service's default port is automatically replaced if the port is occupied
port: 8018.// If you want to see the loading effect of Ajax, this configuration item can set the return delay of the interface
timeout: 500.// If you want to see the effect of interface request failure, set the rate to 0. The rate ranges from 0 to 1, representing the probability of success
rate: 1.// The default is true to enable mock services automatically, but you can also disable mock services by setting it to false
mock: true
},
// Common API...
'/pkApi/getList': {
code: 0.'data|5': [{
'uid|1000-99999': 999.'name': '@cname'}].result: true
},
// Middleware API (standard Express middleware), where you can write interface return logic
['/pkApi/getOther'] (req, res, next) {
const id = req.query.id
req.myData = { / / important! Mount the returned data on req.myData
0: {
code: 0.'test|1-100': 100
},
1: {
code: 1.'number|+1': 202
},
2: {code: 2.'name': '@cname'
}
}[id]
next() // Finally, don't forget to call next manually, otherwise the interface will pause processing!}}Copy the code
The advantages of easy – config – the mock
- It is easy to integrate into scaffolding or workflows and automatically restart services
- Support for custom middleware for more complex business scenarios
- Basically no intrusion into the business code, just change the interface request prefix to
http://127.0.0.1:mock port
- Configuration files are left in projects for development and maintenance
The technical details of the implementation
The following are all the technical details needed to implement the wheel. The code only briefly presents the basic idea. For details, see the source code
How to listenmock.config.js
File changes
Use the Chokidar module
const chokidar = require('chokidar')
chokidar.watch(somepath, {
persistent: true
}).on('change', _ = > {// file change...
// do some logic...
})
Copy the code
How to enable automatic service restart
Fork the child process to start the Express service. If the configuration file changes, the child process is killed and the service restarts
const childProcess = require('child_process')
let child
// Start the Express service with a child process
child = childProcess.fork('./server.js', [] and {encoding: 'utf8'.execArgv: process.execArgv
})
chokidar.watch(somepath, {
persistent: true
}).on('change', _ = > {// Kill the child process and restart the service after the file changes
child.kill('SIGKILL')
child = childProcess.fork('./server.js', [] and {encoding: 'utf8'.execArgv: process.execArgv
})
})
Copy the code
How does a child process read configuration file data
The program passes data to the parent process that the child process does not know, and can take advantage of the communication between the parent and child processes. See child_process for communication and disconnection between the child process and the parent process
// Pass data to the child process
child.send({
path: path
...
})
// The child process receives data
process.on('message', ({ path, ... = > {})delete require.cache[path]
// Here we get the mock data configuration item
const options = require(path)
})
Copy the code
Require has a cache. You need to delete the cache of require before retrieving data from the configuration file
How to simulate a JSONP request
First, you need to know if the request is JSONP and check if the request link has a callback parameter
let dataType
app.use((req, res, next) = > {
dataType = req.query.callback ? 'jsonp' : 'json'
next()
})
Copy the code
How do I delay the return of an interface
Sometimes we write loading and want to verify it
const delayRes = (time) = > (req, res, next) => {
setTimeout(function() { next() }, time)
}
// Add 1 second delay to the interface
app.use(delayRes(1000))
Copy the code
How do I make an interface return failure
Sometimes, we want to see what happens when the Internet goes down or the server goes wrong
const successRate = (rate) = > (req, res, next) => {
if (rate > Math.random()) return next()
return next(500)}// 100% returns 500 errors
app.use(successRate(0))
app.use((err, req, res, next) = > {
res.status(500).json({ status: 0.code: 500.msg: 'Server Error'})})Copy the code
How are cross-domains allowed
Mock interfaces that are not JSONP accessed are cross-domain requests (co-domain only if the protocol, domain name, and port are the same). Cross-domain requests are prohibited and will generate errors. You need to enable cross-domain requests
const crossDomain = (a)= > (req, res, next) => {
res.header("Access-Control-Allow-Origin"."*");
res.header("Access-Control-Allow-Methods"."GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers"."Origin, X-Requested-With, Content-Type, Accept, Authorization");
if (req.method === 'OPTIONS') res.status(200) // Let OPTIONS return quickly
next();
}
app.use(crossDomain())
Copy the code
Final: Route creation
const { mock } = require('mockjs')
// Options is the API information in the configuration file
Object.keys(options).forEach(path= > {
const data = options[path]
// If it is a custom middle
if (typeof data === 'function') app.use(data)
app.use(path, (req, res, next) => {
// Req with myData indicates custom middleware, otherwise it is plain mock API
const rsp = req.myData ? mock(req.myData) : mock(data)
res.status(200)[dataType](rsp)
})
})
Copy the code
Added: The Webpack version of Easy-config-Mock plug-in
easy-mock-webpack-plugin
Just use easy-config-mock
Refer to the link
- vipm-cli
- MockWebpackPlugin
👍 ~🙂😃😃 college 👍 source address
In this paper, to the end.