mock-service-cli 3.2.2 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -11
- package/bin/mock-service-cli +21 -1
- package/lib/mockServer.js +8 -5
- package/lib/staticServer.js +76 -0
- package/lib/utils.js +6 -2
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
[](https://github.com/chandq/mock-service-cli/actions/workflows/node.js.yml)
|
|
2
2
|
[](https://coveralls.io/github/chandq/mock-service-cli?branch=master)
|
|
3
3
|
[](https://github.com/chandq/mock-service-cli)
|
|
4
|
-
[](https://nodejs.org/download/release/v14.0.0/)
|
|
5
4
|
[](https://nodejs.org/download/release/v12.0.0/)
|
|
6
5
|
[](https://github.com/chandq/mock-service-cli/blob/master/LICENSE.md)
|
|
7
6
|
[](https://npmcharts.com/compare/mock-service-cli?minimal=true)
|
|
@@ -10,7 +9,7 @@
|
|
|
10
9
|
|
|
11
10
|
### 简介
|
|
12
11
|
|
|
13
|
-
内置 Mock Server
|
|
12
|
+
内置 **Static Server**、**Mock Server**、**SPA Web Server**、Http?s request proxy 等功能集。
|
|
14
13
|
|
|
15
14
|
**简易轻量**、**B/S 架构**、**0 秒启动**的本地命令行 Mock 服务套件, 支持热更新,对于开发调试 mock 数据很实用,能提高前端开发者的开发效率。支持 `GET`,`POST`,`PUT`,`DELETE`,`PATCH`,`OPTIONS`,`COPY`,`LINK`,`UNLINK`,`PURGE` 等常用请求类型,无需布署后端,可能是本地最好用的 Mock 工具之一。
|
|
16
15
|
|
|
@@ -19,8 +18,14 @@
|
|
|
19
18
|
- 支持统计 mock 的文件数量和 mock 请求数量
|
|
20
19
|
- 支持终端打开 mock 文件的所在位置
|
|
21
20
|
|
|
21
|
+
#### Static Server (和 Mock Server 互斥使用)
|
|
22
|
+
|
|
23
|
+
简易的静态资源服务器,可用于开发调试,如需更多使用场景,请选择 [http-server](https://www.npmjs.com/package/http-server)
|
|
24
|
+
|
|
22
25
|
#### Mock Server - 本地 Mock 服务器
|
|
23
26
|
|
|
27
|
+
> Mock File 仅支持 commonjs 规范的 js、cjs 文件,不支持 ES Module
|
|
28
|
+
|
|
24
29
|
支持以下常见业务场景:
|
|
25
30
|
|
|
26
31
|
- [x] 无服务端演示项目的数据 Mock
|
|
@@ -83,40 +88,45 @@ This will install `mock-service-cli` globally so that it may be run from the com
|
|
|
83
88
|
| `-o` or `--cors-origin` | Allow origin by cors, list separated by commas, must not be \* when withCredential is true .If specified, cors-headers will be `Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token,Token` | \* |
|
|
84
89
|
| `-O` or `--proxy-options` | Optionally provide http request proxy options list, support accept js file、json file、cli arguments string. Examples: `-O '/api/apaas\|http://192.168.0.105:60700,/api/permission\| http://192.168.0.105:60700'`. Must start web server to use proxy for http request test under browser console or api test tools. | - |
|
|
85
90
|
| `-P` or `--web-port` | Web server port to use. Use `-P 9090` to look for an open port, starting at 9090 | 9090 |
|
|
86
|
-
| `-b` or `--web-baseurl` | Specify public path of the
|
|
91
|
+
| `-b` or `--web-baseurl` | Specify public path of the SPA web server, can be base address of SPA route. | - |
|
|
92
|
+
| `-R` or `--static-server` | Specify directory of the Static Web Server. | - |
|
|
87
93
|
|
|
88
94
|
## Example
|
|
89
95
|
|
|
90
|
-
1. Specify
|
|
96
|
+
1. Specify static resource file directory to startup Static Server.
|
|
97
|
+
|
|
98
|
+
`mock-service-cli -R ./test`
|
|
99
|
+
|
|
100
|
+
2. Specify mock server port.
|
|
91
101
|
|
|
92
102
|
`mock-service-cli -p 8085`
|
|
93
103
|
|
|
94
|
-
|
|
104
|
+
3. Enable cors of mock server, specify the origin and headers of http request.
|
|
95
105
|
|
|
96
106
|
`mock-service-cli -o "http://192.168.0.8:38200,http://10.30.30.3" -H "custom-header"`
|
|
97
107
|
|
|
98
|
-
|
|
108
|
+
4. Specify mock directory to startup Mock Server.
|
|
99
109
|
|
|
100
110
|
`mock-service-cli -d ./mock`
|
|
101
111
|
|
|
102
|
-
|
|
112
|
+
5. Specify mock file to startup Mock Server.
|
|
103
113
|
|
|
104
114
|
`mock-service-cli -f ./mock/test.js`
|
|
105
115
|
|
|
106
|
-
|
|
116
|
+
6. Start socket server for used to save api response data.
|
|
107
117
|
|
|
108
118
|
`mock-service-cli -S`
|
|
109
119
|
|
|
110
|
-
|
|
120
|
+
7. Only Used as api server for test on browser console or api request tools.
|
|
111
121
|
> must specified server directory which can be empty but not includes index.html file, and also need config API proxy.
|
|
112
122
|
|
|
113
123
|
`mock-service-cli -D server -O '/api/apaas|http://192.168.0.105:60700'`
|
|
114
124
|
|
|
115
|
-
|
|
125
|
+
8. Start static web server for SPA, and optionally specify public path and port.
|
|
116
126
|
|
|
117
127
|
`mock-service-cli -D ../react-best-practice/dist [-b '/redbridge/'] [-P 9090]`
|
|
118
128
|
|
|
119
|
-
|
|
129
|
+
9. Enable Proxy base on above item 7. support accept js file、json file、cli arguments string
|
|
120
130
|
|
|
121
131
|
- cli arguments string
|
|
122
132
|
|
package/bin/mock-service-cli
CHANGED
|
@@ -16,6 +16,7 @@ if (argv.h || argv.help) {
|
|
|
16
16
|
[
|
|
17
17
|
'usage: mock-service-cli [options]',
|
|
18
18
|
'',
|
|
19
|
+
'PS: Mock File仅支持commonjs规范的js、cjs文件,不支持ES Module',
|
|
19
20
|
'options:',
|
|
20
21
|
' -p --port Mock server port to use. If 0, look for open port. [8090]',
|
|
21
22
|
' -d Specify mock directory, default [./mock] directory,',
|
|
@@ -37,6 +38,8 @@ if (argv.h || argv.help) {
|
|
|
37
38
|
' -D --web-dir Enable web server, specify web directory, default [./dist] directory',
|
|
38
39
|
' -b --web-baseurl Specify website public path when enabled web server.',
|
|
39
40
|
'',
|
|
41
|
+
' -R --static-server Specify static resource file directory when enabled static server.',
|
|
42
|
+
'',
|
|
40
43
|
' -h --help Print this list and exit.',
|
|
41
44
|
' -v --version Print the version and exit.'
|
|
42
45
|
].join('\n')
|
|
@@ -81,6 +84,7 @@ injectEnvVariable('CORS_ORIGIN', argv.o || argv['cors-origin']);
|
|
|
81
84
|
injectEnvVariable('CORS_HEADERS', argv.H || argv['cors-headers']);
|
|
82
85
|
|
|
83
86
|
injectEnvVariable('WEB_PUBLIC_PATH', argv.b || argv['web-baseurl']);
|
|
87
|
+
injectEnvVariable('STATIC_DIRECTORY', argv.R || argv['static-server']);
|
|
84
88
|
// injectEnvVariable('PROXY_OPTIONS', argv.O || argv['proxy-options']);
|
|
85
89
|
// 解析Web代理配置项(来源js|config文件或命令行参数字符串)
|
|
86
90
|
const proxyArg = argv.O || argv['proxy-options'];
|
|
@@ -110,6 +114,7 @@ if (proxyArg) {
|
|
|
110
114
|
process.env.PROXY_OPTIONS = JSON.stringify(proxyTable);
|
|
111
115
|
}
|
|
112
116
|
if (argv.D || argv['web-dir']) {
|
|
117
|
+
// 解析SPA应用参数:SPA Web目录
|
|
113
118
|
process.env.WEB_ROOT = resolve(process.cwd(), argv.D || argv['web-dir']);
|
|
114
119
|
if (!existsSync(process.env.WEB_ROOT)) {
|
|
115
120
|
console.error(`web-dir: 目录 ${process.env.WEB_ROOT} 不存在`);
|
|
@@ -142,7 +147,7 @@ const watchMockFiles = function (watchDir) {
|
|
|
142
147
|
nodemon({
|
|
143
148
|
script: resolve(__dirname, '../lib/mockServer.js'),
|
|
144
149
|
watch: [watchDir],
|
|
145
|
-
ext: 'js,json'
|
|
150
|
+
ext: 'cjs,js,json'
|
|
146
151
|
});
|
|
147
152
|
|
|
148
153
|
nodemon
|
|
@@ -160,6 +165,7 @@ const watchMockFiles = function (watchDir) {
|
|
|
160
165
|
);
|
|
161
166
|
});
|
|
162
167
|
};
|
|
168
|
+
|
|
163
169
|
// Node子进程启动MockServer
|
|
164
170
|
const startMockServer = function () {
|
|
165
171
|
spawn(node, [resolve(__dirname, '../lib/mockServer.js')], {
|
|
@@ -167,7 +173,15 @@ const startMockServer = function () {
|
|
|
167
173
|
});
|
|
168
174
|
};
|
|
169
175
|
|
|
176
|
+
// Node子进程启动StaticServer
|
|
177
|
+
const startStaticServer = function () {
|
|
178
|
+
spawn(node, [resolve(__dirname, '../lib/staticServer.js')], {
|
|
179
|
+
stdio: 'inherit'
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
|
|
170
183
|
if (specifiedFile) {
|
|
184
|
+
// Mock服务器:指定文件
|
|
171
185
|
process.env.SPECIFIED_FILE = resolve(process.cwd(), specifiedFile);
|
|
172
186
|
if (isStartSocketServer) {
|
|
173
187
|
startMockServer();
|
|
@@ -175,6 +189,7 @@ if (specifiedFile) {
|
|
|
175
189
|
watchMockFiles(process.env.SPECIFIED_FILE);
|
|
176
190
|
}
|
|
177
191
|
} else if (watchDir) {
|
|
192
|
+
// Mock服务器:指定目录
|
|
178
193
|
process.env.SPECIFIED_DIR = resolve(process.cwd(), watchDir);
|
|
179
194
|
// log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
|
|
180
195
|
if (isStartSocketServer) {
|
|
@@ -182,7 +197,12 @@ if (specifiedFile) {
|
|
|
182
197
|
} else {
|
|
183
198
|
watchMockFiles(process.env.SPECIFIED_DIR);
|
|
184
199
|
}
|
|
200
|
+
} else if (process.env.STATIC_DIRECTORY) {
|
|
201
|
+
// 静态服务器
|
|
202
|
+
process.env.STATIC_DIRECTORY = resolve(process.cwd(), process.env.STATIC_DIRECTORY);
|
|
203
|
+
startStaticServer();
|
|
185
204
|
} else {
|
|
205
|
+
// Mock服务:使用默认目录
|
|
186
206
|
watchDir = process.env.SPECIFIED_DIR = resolve(process.cwd(), './mock');
|
|
187
207
|
// log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
|
|
188
208
|
if (isStartSocketServer) {
|
package/lib/mockServer.js
CHANGED
|
@@ -92,8 +92,8 @@ const composeRouteFromJsFile = function (file) {
|
|
|
92
92
|
const fileObject = getFileLatestContent(file);
|
|
93
93
|
|
|
94
94
|
argv.a && log.info(colors.green(`Mockfile ${++fileCount}: `), file, colors.yellow('all API URL is follows: '));
|
|
95
|
-
if (
|
|
96
|
-
console.error(colors.red(`[warning] "${file}" 文件解析失败,请检查并确保文件中的js语法正确`));
|
|
95
|
+
if (fileObject === 'getFileLatestContent_ERROR') {
|
|
96
|
+
// console.error(colors.red(`[warning] "${file}" 文件解析失败,请检查并确保文件中的js语法正确`));
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
99
|
Object.keys(fileObject).forEach(item => {
|
|
@@ -143,8 +143,8 @@ const parseMockFiles = function (specialDir = '../mock') {
|
|
|
143
143
|
argv.a &&
|
|
144
144
|
log.info(colors.green(`Mockfile ${++fileCount}: `), filePath, colors.yellow('all API URL is follows: '));
|
|
145
145
|
const fileObject = getFileLatestContent(filePath);
|
|
146
|
-
if (
|
|
147
|
-
console.error(colors.red(`[warning] "${filePath}" 文件解析失败,请检查并确保文件中的js语法正确`));
|
|
146
|
+
if (fileObject === 'getFileLatestContent_ERROR') {
|
|
147
|
+
// console.error(colors.red(`[warning] "${filePath}" 文件解析失败,请检查并确保文件中的js语法正确`));
|
|
148
148
|
continue;
|
|
149
149
|
}
|
|
150
150
|
// eslint-disable-next-line no-loop-func
|
|
@@ -166,7 +166,7 @@ const parseMockFiles = function (specialDir = '../mock') {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
// 非js文件跳过
|
|
169
|
-
if (!el.name.endsWith('.js')) {
|
|
169
|
+
if (!el.name.endsWith('.js') && !el.name.endsWith('.cjs')) {
|
|
170
170
|
continue;
|
|
171
171
|
}
|
|
172
172
|
composeRouteFromJsFile(filePath);
|
|
@@ -291,6 +291,8 @@ if (process.env.SOCKET_SERVER) {
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
http.listen(Number.parseInt(process.env.PORT, 10), () => {
|
|
294
|
+
console.info(colors.red('\n Mock File仅支持commonjs规范的js、cjs文件,不支持ES Module'));
|
|
295
|
+
|
|
294
296
|
console.info(
|
|
295
297
|
[
|
|
296
298
|
colors.yellow(`\n${process.env.RESTARTED ? 'Restarting' : 'Starting'} up mock-server, serving `),
|
|
@@ -315,6 +317,7 @@ http.listen(Number.parseInt(process.env.PORT, 10), () => {
|
|
|
315
317
|
});
|
|
316
318
|
|
|
317
319
|
if (webApp && !process.env.RESTARTED) {
|
|
320
|
+
console.info(colors.red('\n Mock File仅支持commonjs规范的js、cjs文件,不支持ES Module'));
|
|
318
321
|
webApp.listen(Number.parseInt(process.env.WEB_PORT, 10), () => {
|
|
319
322
|
console.info(colors.yellow(`\n Web server available on:\n`));
|
|
320
323
|
console.info(' http://localhost:' + colors.green(process.env.WEB_PORT) + webPublicPath);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Static Server
|
|
3
|
+
* @Date: 2023-12-03 18:02:24
|
|
4
|
+
* @LastEditors: chendq
|
|
5
|
+
* @LastEditTime: 2023-12-03 18:44:33
|
|
6
|
+
* @Author : chendq
|
|
7
|
+
*/
|
|
8
|
+
const express = require('express'), // 引入express
|
|
9
|
+
os = require('os'),
|
|
10
|
+
colors = require('colors/safe'),
|
|
11
|
+
portfinder = require('portfinder');
|
|
12
|
+
const { dateFormat, logger } = require('./utils');
|
|
13
|
+
const ifaces = os.networkInterfaces();
|
|
14
|
+
const log = logger(process.env.SILENT);
|
|
15
|
+
|
|
16
|
+
let done = false;
|
|
17
|
+
if (!process.env.PORT) {
|
|
18
|
+
portfinder.basePort = 8090;
|
|
19
|
+
portfinder.getPort(function (err, port) {
|
|
20
|
+
if (err) {
|
|
21
|
+
throw err;
|
|
22
|
+
}
|
|
23
|
+
process.env.PORT = port;
|
|
24
|
+
done = true;
|
|
25
|
+
});
|
|
26
|
+
} else {
|
|
27
|
+
done = true;
|
|
28
|
+
}
|
|
29
|
+
// 将异步函数转换为同步代码代码执行
|
|
30
|
+
require('deasync').loopWhile(function () {
|
|
31
|
+
return !done;
|
|
32
|
+
});
|
|
33
|
+
const app = express();
|
|
34
|
+
|
|
35
|
+
app.use(express.static(process.env.STATIC_DIRECTORY)); // 将dist目录下所有文件作为静态文件来管理
|
|
36
|
+
|
|
37
|
+
app.listen(Number.parseInt(process.env.PORT, 10), () => {
|
|
38
|
+
console.info(
|
|
39
|
+
[
|
|
40
|
+
colors.yellow(`\nStarting up Static Server, serving `),
|
|
41
|
+
colors.cyan(process.env.STATIC_DIRECTORY),
|
|
42
|
+
colors.yellow(` ${dateFormat('YYYY-mm-dd HH:MM:SS', new Date())}`)
|
|
43
|
+
].join('')
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
console.info(colors.yellow(`\n Static Server available on:\n`));
|
|
47
|
+
console.info(' http://localhost:' + colors.green(process.env.PORT));
|
|
48
|
+
Object.keys(ifaces).forEach(function (dev) {
|
|
49
|
+
ifaces[dev].forEach(function (details) {
|
|
50
|
+
if (details.family === 'IPv4') {
|
|
51
|
+
console.info(' http://' + details.address + ':' + colors.green(process.env.PORT));
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (process.platform === 'win32') {
|
|
58
|
+
require('readline')
|
|
59
|
+
.createInterface({
|
|
60
|
+
input: process.stdin,
|
|
61
|
+
output: process.stdout
|
|
62
|
+
})
|
|
63
|
+
.on('SIGINT', function () {
|
|
64
|
+
process.emit('SIGINT');
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
process.on('SIGINT', function () {
|
|
69
|
+
log.info(colors.red('mock-server process stopped.'));
|
|
70
|
+
process.exit();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
process.on('SIGTERM', function () {
|
|
74
|
+
log.info(colors.red('mock-server process stopped.'));
|
|
75
|
+
process.exit();
|
|
76
|
+
});
|
package/lib/utils.js
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* @description: 工具函数库
|
|
3
3
|
* @Date: 2021-12-25 17:52:48
|
|
4
4
|
* @LastEditors: chendq
|
|
5
|
-
* @LastEditTime:
|
|
5
|
+
* @LastEditTime: 2024-01-16 22:28:37
|
|
6
6
|
* @Author: chendq
|
|
7
7
|
*/
|
|
8
8
|
const fs = require('fs');
|
|
9
|
+
const colors = require('colors/safe');
|
|
9
10
|
const path = require('path');
|
|
10
11
|
// const JSONStream = require('JSONStream');
|
|
11
12
|
/**
|
|
@@ -102,9 +103,12 @@ const getFileLatestContent = function (filePath) {
|
|
|
102
103
|
delete require.cache[require.resolve(filePath)];
|
|
103
104
|
return require(path.resolve(process.cwd(), filePath));
|
|
104
105
|
} catch (error) {
|
|
105
|
-
getLogger(path.resolve(process.cwd())).error(filePath, require.cache[require.resolve(filePath)], error);
|
|
106
|
+
// getLogger(path.resolve(process.cwd())).error(filePath, require.cache[require.resolve(filePath)], error);
|
|
107
|
+
console.error(colors.red('[error]:'), error);
|
|
108
|
+
return 'getFileLatestContent_ERROR';
|
|
106
109
|
}
|
|
107
110
|
};
|
|
111
|
+
|
|
108
112
|
/**
|
|
109
113
|
* @description: 文件路径转成API的url
|
|
110
114
|
* @param {string} filePath
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mock-service-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "🦅 Local mock server",
|
|
5
5
|
"main": "./lib/mockServer.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"prettier": "prettier -c --write \"**/*.{ts,js,jsx,css,less,scss,json}\"",
|
|
17
17
|
"release:prerelease": "standard-version --prerelease",
|
|
18
18
|
"release:prefix": "standard-version --prerelease alpha",
|
|
19
|
-
"release:patch": "standard-version --release-as patch && git push origin master
|
|
19
|
+
"release:patch": "standard-version --release-as patch && git push --follow-tags origin master",
|
|
20
20
|
"release:minor": "standard-version --release-as minor && git push --follow-tags origin master",
|
|
21
21
|
"release:major": "standard-version --release-as major && git push --follow-tags origin master"
|
|
22
22
|
},
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"packageManager": "yarn@1.22.19",
|
|
33
33
|
"keywords": [
|
|
34
34
|
"MIT-licensed",
|
|
35
|
+
"Static Server",
|
|
35
36
|
"Mock",
|
|
36
37
|
"MockServer",
|
|
37
38
|
"mock-service-cli",
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
"eslint-plugin-mocha": "^9.0.0",
|
|
68
69
|
"husky": "^4.3.8",
|
|
69
70
|
"lint-staged": "^10.2.2",
|
|
70
|
-
"mockjs": "^
|
|
71
|
+
"mockjs": "^0.1.10",
|
|
71
72
|
"standard-version": "^8.0.0",
|
|
72
73
|
"tap": "^15.0.10"
|
|
73
74
|
},
|