mock-service-cli 3.3.2 → 3.3.3

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 CHANGED
@@ -24,6 +24,8 @@
24
24
 
25
25
  #### Mock Server - 本地 Mock 服务器
26
26
 
27
+ **支持热更新,即 Mock 文件改动后自动重启服务**
28
+
27
29
  > Mock File 仅支持 commonjs 规范的 js、cjs 文件,不支持 ES Module
28
30
 
29
31
  支持以下常见业务场景:
@@ -9,6 +9,7 @@ const argv = require('minimist')(process.argv.slice(2));
9
9
  const { logger } = require('../lib/utils');
10
10
  const spawn = require('child_process').spawn;
11
11
  const node = process.execPath;
12
+
12
13
  process.title = 'mock-service-cli';
13
14
 
14
15
  if (argv.h || argv.help) {
@@ -113,6 +114,7 @@ if (proxyArg) {
113
114
  }
114
115
  process.env.PROXY_OPTIONS = JSON.stringify(proxyTable);
115
116
  }
117
+ // whether to start Web server or not
116
118
  if (argv.D || argv['web-dir']) {
117
119
  // 解析SPA应用参数:SPA Web目录
118
120
  process.env.WEB_ROOT = resolve(process.cwd(), argv.D || argv['web-dir']);
@@ -122,24 +124,38 @@ if (argv.D || argv['web-dir']) {
122
124
  }
123
125
  // Web Server port
124
126
  portfinder.basePort = argv.P || argv['web-port'] || 9090;
127
+ portfinder.getPort(function (err, webPort) {
128
+ if (err) {
129
+ throw err;
130
+ }
131
+ process.env.WEB_PORT = webPort;
132
+ // Mock Server port
133
+ portfinder.basePort = port || 8090;
134
+ portfinder.getPort(function (err, port) {
135
+ if (err) {
136
+ throw err;
137
+ }
138
+ process.env.PORT = port;
139
+ initServe();
140
+ });
141
+ });
142
+ } else {
143
+ // Mock Server port
144
+ portfinder.basePort = port || 8090;
125
145
  portfinder.getPort(function (err, port) {
126
146
  if (err) {
127
147
  throw err;
128
148
  }
129
- process.env.WEB_PORT = port;
149
+ process.env.PORT = port;
150
+ initServe();
130
151
  });
131
152
  }
132
153
 
133
- // Mock Server port
134
- portfinder.basePort = port || 8090;
135
- portfinder.getPort(function (err, port) {
136
- if (err) {
137
- throw err;
138
- }
139
- process.env.PORT = port;
140
- });
141
-
142
- const watchMockFiles = function (watchDir) {
154
+ /**
155
+ * Watch change of mock files, restart serve
156
+ * @param watchDir
157
+ */
158
+ function watchMockFiles(watchDir) {
143
159
  /**
144
160
  * script 重启的脚本
145
161
  * ext 检测的文件
@@ -164,50 +180,62 @@ const watchMockFiles = function (watchDir) {
164
180
  [colors.green('\nnodemon: mockServer restarted due to: '), files, colors.green(' have changed'), '\n'].join('')
165
181
  );
166
182
  });
167
- };
183
+ }
168
184
 
169
185
  // Node子进程启动MockServer
170
- const startMockServer = function () {
186
+ function startMockServer() {
171
187
  spawn(node, [resolve(__dirname, '../lib/mockServer.js')], {
172
188
  stdio: 'inherit'
173
189
  });
174
- };
190
+ }
175
191
 
176
192
  // Node子进程启动StaticServer
177
- const startStaticServer = function () {
193
+ function startStaticServer() {
178
194
  spawn(node, [resolve(__dirname, '../lib/staticServer.js')], {
179
195
  stdio: 'inherit'
180
196
  });
181
- };
182
-
183
- if (specifiedFile) {
184
- // Mock服务器:指定文件
185
- process.env.SPECIFIED_FILE = resolve(process.cwd(), specifiedFile);
186
- if (isStartSocketServer) {
187
- startMockServer();
188
- } else {
189
- watchMockFiles(process.env.SPECIFIED_FILE);
190
- }
191
- } else if (watchDir) {
192
- // Mock服务器:指定目录
193
- process.env.SPECIFIED_DIR = resolve(process.cwd(), watchDir);
194
- // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
195
- if (isStartSocketServer) {
196
- startMockServer();
197
- } else {
198
- watchMockFiles(process.env.SPECIFIED_DIR);
199
- }
200
- } else if (process.env.STATIC_DIRECTORY) {
201
- // 静态服务器
202
- process.env.STATIC_DIRECTORY = resolve(process.cwd(), process.env.STATIC_DIRECTORY);
203
- startStaticServer();
204
- } else {
205
- // Mock服务:使用默认目录
206
- watchDir = process.env.SPECIFIED_DIR = resolve(process.cwd(), './mock');
207
- // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
208
- if (isStartSocketServer) {
209
- startMockServer();
197
+ }
198
+ /**
199
+ * 初始化服务
200
+ */
201
+ function initServe() {
202
+ if (specifiedFile) {
203
+ // Mock服务器:指定文件
204
+ process.env.SPECIFIED_FILE = resolve(process.cwd(), specifiedFile);
205
+ if (isStartSocketServer) {
206
+ startMockServer();
207
+ } else {
208
+ watchMockFiles(process.env.SPECIFIED_FILE);
209
+ }
210
+ } else if (watchDir) {
211
+ // Mock服务器:指定目录
212
+ process.env.SPECIFIED_DIR = resolve(process.cwd(), watchDir);
213
+ // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
214
+ if (isStartSocketServer) {
215
+ startMockServer();
216
+ } else {
217
+ watchMockFiles(process.env.SPECIFIED_DIR);
218
+ }
219
+ } else if (process.env.STATIC_DIRECTORY) {
220
+ // 静态服务器
221
+ process.env.STATIC_DIRECTORY = resolve(process.cwd(), process.env.STATIC_DIRECTORY);
222
+ startStaticServer();
210
223
  } else {
211
- watchMockFiles(watchDir);
224
+ // Mock服务:使用默认目录
225
+ watchDir = process.env.SPECIFIED_DIR = resolve(process.cwd(), './mock');
226
+ // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
227
+ if (isStartSocketServer) {
228
+ startMockServer();
229
+ } else {
230
+ // whether include web serve or not
231
+ const includesWebServe = process.env.STATIC_DIRECTORY || process.env.WEB_ROOT;
232
+
233
+ if (includesWebServe && !existsSync(resolve(process.cwd(), watchDir))) {
234
+ // 若包含web服务,则允许不启动mock服务
235
+ startMockServer();
236
+ } else {
237
+ watchMockFiles(watchDir);
238
+ }
239
+ }
212
240
  }
213
241
  }
package/lib/mockServer.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const express = require('express'), // 引入express
2
2
  bodyParser = require('body-parser'),
3
- fs = require('fs'),
3
+ { readdirSync, existsSync } = require('fs'),
4
4
  os = require('os'),
5
5
  path = require('path'),
6
6
  colors = require('colors/safe'),
@@ -25,8 +25,6 @@ const app = express();
25
25
  const log = logger(process.env.SILENT);
26
26
  const argv = JSON.parse(process.env.ARGV);
27
27
  let socketServer = null; // Socket server instance
28
- const AsyncTaskQueue = require('./asyncTaskQueue');
29
- const saveDataAsyncTask = new AsyncTaskQueue();
30
28
  let corsOrigin = [],
31
29
  corsHeaders = '';
32
30
 
@@ -35,6 +33,12 @@ let count = 0,
35
33
  fileCount = 0, // 记录mock api个数,mock file个数
36
34
  mockDirStat = {}, // 缓存mock目录的统计信息
37
35
  mockFileStat = {}; // 缓存mock文件的统计信息
36
+
37
+ // whether include web serve or not
38
+ const includesWebServe = process.env.STATIC_DIRECTORY || process.env.WEB_ROOT;
39
+
40
+ const mockFileOrDir = process.env.SPECIFIED_FILE || process.env.SPECIFIED_DIR;
41
+
38
42
  if (!process.env.PORT) {
39
43
  portfinder.basePort = 8090;
40
44
  portfinder.getPort(function (err, port) {
@@ -68,12 +72,16 @@ function init() {
68
72
  app.use(crossDomain()); // 允许跨域
69
73
  app.use(bodyParser.json()); // 解析body
70
74
 
75
+ let requireMockServe = true;
71
76
  if (process.env.SPECIFIED_FILE) {
72
77
  composeRouteFromJsFile(process.env.SPECIFIED_FILE);
78
+ } else if (includesWebServe && !existsSync(path.resolve(process.cwd(), process.env.SPECIFIED_DIR))) {
79
+ // 若包含web服务,则允许不启动mock服务
80
+ requireMockServe = false;
73
81
  } else {
74
82
  parseMockFiles(process.env.SPECIFIED_DIR);
75
83
  }
76
- argv.a && log.info(colors.yellow(`${fileCount} mock file are parsed in total.`));
84
+ requireMockServe && argv.a && log.info(colors.yellow(`${fileCount} mock file are parsed in total.`));
77
85
 
78
86
  startServer();
79
87
  }
@@ -144,7 +152,7 @@ function composeRouteFromJsFile(file) {
144
152
  * @return {void}
145
153
  */
146
154
  function parseMockFiles(specialDir = '../mock') {
147
- const files = fs.readdirSync(path.resolve(process.cwd(), specialDir), { withFileTypes: true });
155
+ const files = readdirSync(path.resolve(process.cwd(), specialDir), { withFileTypes: true });
148
156
  const curFilesSize = files.length;
149
157
  for (let index = 0; index < curFilesSize; index++) {
150
158
  const el = files[index];
@@ -231,7 +239,7 @@ function startServer() {
231
239
  }
232
240
  webApp.use(webPublicPath, express.static(process.env.WEB_ROOT)); // 将dist目录下所有文件作为静态文件来管理
233
241
  const defaultStaticEntry = `${process.env.WEB_ROOT}/index.html`;
234
- if (fs.existsSync(defaultStaticEntry)) {
242
+ if (existsSync(defaultStaticEntry)) {
235
243
  // Used as static HTTP server for SPA
236
244
  webApp.get('*', (req, res) => {
237
245
  res.sendFile(defaultStaticEntry);
@@ -255,6 +263,9 @@ function startServer() {
255
263
  }
256
264
  const http = require('http').createServer(app);
257
265
  if (process.env.SOCKET_SERVER) {
266
+ const AsyncTaskQueue = require('./asyncTaskQueue');
267
+ const saveDataAsyncTask = new AsyncTaskQueue();
268
+
258
269
  socketServer = new Server(http, { path: '/ws/mock-service' });
259
270
  log.info(colors.bgBlue(`Socket server has started. path: /ws/mock-service, `));
260
271
  socketServer.of('/mock-data').on('connection', function (socket) {
@@ -302,34 +313,35 @@ function startServer() {
302
313
  });
303
314
  }
304
315
 
305
- http.listen(Number.parseInt(process.env.PORT, 10), () => {
306
- console.info(colors.red('\n Mock File仅支持commonjs规范的js、cjs文件,不支持ES Module'));
316
+ if (existsSync(mockFileOrDir)) {
317
+ http.listen(Number.parseInt(process.env.PORT, 10), () => {
318
+ console.info(colors.red('\n Mock File仅支持commonjs规范的js、cjs文件,不支持ES Module'));
307
319
 
308
- console.info(
309
- [
310
- colors.yellow(`\n${process.env.RESTARTED ? 'Restarting' : 'Starting'} up mock-server, serving `),
311
- colors.cyan(process.env.SPECIFIED_FILE || process.env.SPECIFIED_DIR),
312
- colors.yellow(` ${dateFormat('YYYY-mm-dd HH:MM:SS', new Date())}`)
313
- ].join('')
314
- );
315
- if (!process.env.RESTARTED) {
316
320
  console.info(
317
- [colors.yellow('\n🌍 mock-server version: '), colors.cyan(require('../package.json').version), '\n'].join('')
321
+ [
322
+ colors.yellow(`\n${process.env.RESTARTED ? 'Restarting' : 'Starting'} up mock-server, serving `),
323
+ colors.cyan(process.env.SPECIFIED_FILE || process.env.SPECIFIED_DIR),
324
+ colors.yellow(` ${dateFormat('YYYY-mm-dd HH:MM:SS', new Date())}`)
325
+ ].join('')
318
326
  );
319
- console.info(colors.yellow(`\n Mock server available on:\n`));
320
- console.info(' http://localhost:' + colors.green(process.env.PORT));
321
- Object.keys(ifaces).forEach(function (dev) {
322
- ifaces[dev].forEach(function (details) {
323
- if (details.family === 'IPv4') {
324
- console.info(' http://' + details.address + ':' + colors.green(process.env.PORT));
325
- }
327
+ if (!process.env.RESTARTED) {
328
+ console.info(
329
+ [colors.yellow('\n🌍 mock-server version: '), colors.cyan(require('../package.json').version), '\n'].join('')
330
+ );
331
+ console.info(colors.yellow(`\n Mock server available on:\n`));
332
+ console.info(' http://localhost:' + colors.green(process.env.PORT));
333
+ Object.keys(ifaces).forEach(function (dev) {
334
+ ifaces[dev].forEach(function (details) {
335
+ if (details.family === 'IPv4') {
336
+ console.info(' http://' + details.address + ':' + colors.green(process.env.PORT));
337
+ }
338
+ });
326
339
  });
327
- });
328
- }
329
- });
340
+ }
341
+ });
342
+ }
330
343
 
331
344
  if (webApp && !process.env.RESTARTED) {
332
- console.info(colors.red('\n Mock File仅支持commonjs规范的js、cjs文件,不支持ES Module'));
333
345
  webApp.listen(Number.parseInt(process.env.WEB_PORT, 10), () => {
334
346
  console.info(colors.yellow(`\n Web server available on:\n`));
335
347
  console.info(' http://localhost:' + colors.green(process.env.WEB_PORT) + webPublicPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mock-service-cli",
3
- "version": "3.3.2",
3
+ "version": "3.3.3",
4
4
  "description": "🦅 Local mock server, Static server, SPA server, Http?s request proxy",
5
5
  "main": "./lib/mockServer.js",
6
6
  "bin": {
@@ -28,7 +28,6 @@
28
28
  "node": ">=12"
29
29
  },
30
30
  "author": "chendq <deqiaochen@gmail.com>",
31
- "packageManager": "yarn@1.22.19",
32
31
  "keywords": [
33
32
  "Static Server",
34
33
  "Web Server",