vite-plugin-mock-dev-server 1.6.1 → 1.7.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 CHANGED
@@ -1,12 +1,6 @@
1
1
  # vite-plugin-mock-dev-server
2
2
 
3
- <br>
4
- <br>
5
- <p align="center">
6
- <b>Vite Plugin for API mock dev server.</b>
7
- </p>
8
-
9
- <br>
3
+ Vite Plugin for API mock dev server.
10
4
 
11
5
  <p align="center">
12
6
  <a href="https://www.npmjs.com/package/vite-plugin-mock-dev-server"><img alt="npm" src="https://img.shields.io/npm/v/vite-plugin-mock-dev-server?style=flat-square"></a>
@@ -17,21 +11,15 @@
17
11
  <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/pengzhanbo/vite-plugin-mock-dev-server/lint.yml?style=flat-square">
18
12
  <a href="https://app.fossa.com/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server?ref=badge_shield"><img alt="fossa status" src="https://app.fossa.com/api/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server.svg?type=shield"></a>
19
13
  </p>
20
- <br>
21
- <p align="center">
22
- <span>English</span> | <a href="/README.zh-CN.md">简体中文</a>
23
- </p>
24
- <br>
25
- <br>
26
14
 
27
- ## Feature
15
+ ## Features
28
16
 
29
17
  - ⚡️ Lightweight, Flexible, Fast.
30
18
  - 🧲 Not injection-based, non-intrusive to client code.
31
19
  - 💡 ESModule/commonjs.
32
20
  - 🦾 Typescript.
33
21
  - 🔥 HMR
34
- - 🏷 Support `json` / `json5`.
22
+ - 🏷 Support `.[cm]?js` / `.ts` / `.json` / `.json5`.
35
23
  - 📦 Auto import mock file.
36
24
  - 🎨 Support any lib, like `mockjs`, or do not use it.
37
25
  - 📥 Path rule matching, request parameter matching.
@@ -48,13 +36,11 @@
48
36
 
49
37
  ## Documentation
50
38
 
51
- See the [documentation](https://vite-plugin-mock-dev-server.netlify.app/en/) to learn more.
39
+ See the [documentation](https://vite-plugin-mock-dev-server.netlify.app/en/) for more details.
52
40
 
53
41
  [![Netlify Status](https://api.netlify.com/api/v1/badges/9ccda610-2c6a-4cd0-aeaa-a8932f2b477c/deploy-status)](https://app.netlify.com/sites/vite-plugin-mock-dev-server/deploys)
54
42
 
55
- ## Usage
56
-
57
- ### Install
43
+ ## Install
58
44
 
59
45
  ``` sh
60
46
  # npm
@@ -65,7 +51,7 @@ yarn add vite-plugin-mock-dev-server
65
51
  pnpm add -D vite-plugin-mock-dev-server
66
52
  ```
67
53
 
68
- ### Configuration
54
+ ## Usage
69
55
 
70
56
  `vite.config.ts`
71
57
 
@@ -75,11 +61,12 @@ import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
75
61
 
76
62
  export default defineConfig({
77
63
  plugins: [
78
- mockDevServerPlugin(),
64
+ mockDevServerPlugin(/* plugin options */),
79
65
  ],
80
66
  // The fields defined here can also be used in mock.
81
67
  define: {},
82
68
  server: {
69
+ // plugin will read `server.proxy`
83
70
  proxy: {
84
71
  '^/api': { target: 'http://example.com' }
85
72
  }
@@ -91,11 +78,7 @@ The plugin will read the configuration of `server.proxy` or `options.prefix`, an
91
78
 
92
79
  The plugin will also read the `define` configuration, which supports direct use in mock files.
93
80
 
94
- > Because in general scenarios, we only need to mock URLs with proxies so that we can use the proxy and mock services provided by Vite's HTTP service.
95
- >
96
- > However, you can also configure mocks using `options.prefix`.
97
-
98
- ### Edit Mock File
81
+ ## Edit Mock File
99
82
 
100
83
  By default, write mock data in the `mock` directory of your project's root directory:
101
84
 
@@ -110,875 +93,14 @@ export default defineMock({
110
93
  })
111
94
  ```
112
95
 
113
- ## Methods
114
-
115
- ### mockDevServerPlugin(options)
116
-
117
- Vite plugin
118
-
119
- `vite.config.ts`
120
-
121
- ``` ts
122
- import { defineConfig } from 'vite'
123
- import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
124
-
125
- export default defineConfig({
126
- plugins: [
127
- mockDevServerPlugin(),
128
- ]
129
- })
130
- ```
131
-
132
- #### options
133
-
134
- - `options.prefix`
135
-
136
- **Type:** `string | string[]`
137
-
138
- Configure custom matching rules for the mock server. Any request path starting with the value of `prefix` will be proxied to the corresponding target. If the `prefix` value starts with ^, it will be recognized as a RegExp.
139
-
140
- > In general, `server.proxy` is sufficient to meet the needs. Adding this item is for compatibility with certain scenarios.
141
-
142
- **Default:** `[]`
143
-
144
- - `options.wsPrefix`
145
-
146
- **Type:** `string | string[]`
147
-
148
- Configure the matching rules for the WebSocket service. Any request path starting with the value of `wsPrefix` and using the `ws/wss` protocol will be proxied to the corresponding target.
149
-
150
- If the value of `wsPrefix` starts with `^`, it will be recognized as a RegExp.
151
-
152
- > Different from using `viteConfig.server.proxy` by default for http mock, `websocket mock` does not use the ws-related configuration in `viteConfig.server.proxy`. Also, rules configured in `wsPrefix` cannot be configured simultaneously in `viteConfig.server.proxy`, as it will cause conflicts when starting the vite server because multiple instances of WebSocketServer cannot be implemented for the same request.
153
- > This conflict is neither a problem with Vite nor with the plugin; it belongs to a reasonable error type. When switching between WebSocket Mock and WebSocket Proxy, please pay attention to avoid duplicate configurations that may cause conflicts.
154
-
155
- - `option.cwd`
156
-
157
- **Type:** `string`
158
-
159
- Configure the matching context for `include` and `exclude`.
160
-
161
- **Default:** `process.cwd()`
162
-
163
- - `option.include`
164
-
165
- **Type:** `string | string[]`
166
-
167
- Configure to read mock files, which can be a directory, glob, or an array.
168
-
169
- **Default:** `['mock/**/*.mock.{js,ts,cjs,mjs,json,json5}']` (Relative to the root directory.)
170
-
171
- - `options.exclude`
172
-
173
- **Type:** `string | string[]`
174
-
175
- When reading mock files for configuration, the files that need to be excluded can be a directory, glob, or array.
176
-
177
- **Default:** `['**/node_modules/**','**/.vscode/**','**/.git/**']`
178
-
179
- - `options.reload`
180
-
181
- **Type:** `boolean`
182
-
183
- When the mock resource is hot updated, only the data content is updated, but the page is not refreshed by default. If you want to refresh the page every time you modify the mock file, you can open this option.
184
-
185
- - `options.cors`
186
-
187
- **Type:** `boolean | CorsOptions`
188
-
189
- Enable by default.
190
-
191
- Configure to `cors`, see [cors](https://github.com/expressjs/cors#configuration-options)
192
-
193
- **Default:** `true`
194
-
195
- - `options.log`
196
-
197
- **Type:** `boolean | 'info' | 'warn' | 'error' | 'silent'`
198
-
199
- Enable log and configure log level.
200
-
201
- - `options.formidableOptions`
202
-
203
- Configure to `formidable`, see [formidable options](https://github.com/node-formidable/formidable#options)
204
-
205
- **Default:** `{}`
206
-
207
- example: Configure to file upload dir
208
-
209
- ``` ts
210
- MockDevServerPlugin({
211
- formidableOptions: {
212
- uploadDir: path.join(process.cwd(), 'uploads'),
213
- }
214
- })
215
- ```
216
-
217
- - `options.cookiesOptions`
218
-
219
- Configure to `cookies`, see [cookies](https://github.com/pillarjs/cookies#new-cookiesrequest-response--options)
220
-
221
- **Default:** `{}`
222
-
223
- - `options.bodyParserOptions`
224
-
225
- Configure to `co-body`, see [co-body](https://github.com/cojs/co-body#options)
226
-
227
- **Default:** `{}`
228
-
229
- - `options.build`
230
-
231
- The configuration needed to build a small, independently deployable mock service.
232
-
233
- **Type:** `boolean | ServerBuildOptions`
234
-
235
- **Default:** `false`
236
-
237
- ``` ts
238
- interface ServerBuildOptions {
239
- /**
240
- * server port
241
- * @default 8080
242
- */
243
- serverPort?: number
244
- /**
245
- * build output dir
246
- * @default 'mockServer'
247
- */
248
- dist?: string
249
- /**
250
- * log level
251
- * @default 'error'
252
- */
253
- log?: LogLevel
254
- }
255
- ```
256
-
257
- - `options.priority`
258
-
259
- Custom path matching rule priority。[read more](#custom-path-matching-priority)
260
-
261
- **Default:** `undefined`
262
-
263
- ### defineMock(config)
264
-
265
- Mock Type Helper
266
-
267
- ``` ts
268
- import { defineMock } from 'vite-plugin-mock-dev-server'
269
-
270
- export default defineMock({
271
- url: '/api/test',
272
- body: {}
273
- })
274
- ```
275
-
276
- ### createDefineMock(transformer)
277
-
278
- Return a custom defineMock function to support preprocessing of mock config.
279
-
280
- ``` ts
281
- import path from 'node:path'
282
- import { createDefineMock } from 'vite-plugin-mock-dev-server'
283
-
284
- // Preprocessed mock url
285
- const defineAPIMock = createDefineMock((mock) => {
286
- mock.url = path.join('/api', mock.url)
287
- })
288
-
289
- export default defineApiMock({
290
- url: '/test' // Complete as '/api/test'
291
- })
292
- ```
293
-
294
- ## Mock Configuration
295
-
296
- ``` ts
297
- // Configure the http mock
298
- export default defineMock({
299
- /**
300
- * Request address, supports the `/api/user/:id` format.
301
- * The plugin matches the path through `path-to-regexp`.
302
- * @see https://github.com/pillarjs/path-to-regexp
303
- */
304
- url: '/api/test',
305
- /**
306
- * Supported request methods of the interface.
307
- * @type string | string[]
308
- * @default ['POST','GET']
309
- *
310
- */
311
- method: ['GET', 'POST'],
312
- /**
313
- * In practical scenarios,
314
- * we usually only need certain mock interfaces to take effect,
315
- * rather than enabling all mock interfaces.
316
- * For interfaces that do not currently require mocking,
317
- * they can be set to false.
318
- *
319
- * @default true
320
- */
321
- enabled: true,
322
- /**
323
- * Set interface response delay, if an array is passed in,
324
- * it represents the range of delay time.
325
- * unit: ms.
326
- * @default 0
327
- */
328
- delay: 1000,
329
- /**
330
- * response status
331
- * @default 200
332
- */
333
- status: 200,
334
- /**
335
- * response status text
336
- */
337
- statusText: 'OK',
338
- /**
339
- * response headers
340
- * @type Record<string, any>
341
- * @type (({ query, body, params, headers }) => Record<string, any>)
342
- */
343
- headers: {
344
- 'Content-Type': 'application/json'
345
- },
346
-
347
- /**
348
- * response cookies
349
- * @type Record<string, string | [value: string, option: CookieOption]>
350
- * @see https://github.com/pillarjs/cookies#cookiessetname--values--options
351
- */
352
- cookies: {
353
- 'your-cookie': 'your cookie value',
354
- 'cookie&option': ['cookie value', { path: '/', httpOnly: true }]
355
- },
356
- /**
357
- * Response body data type, optional values include `text, json, buffer`.
358
- * And also support types included in `mime-db`.
359
- * When the response body returns a file and you are not sure which type to use,
360
- * you can pass the file name as the value. The plugin will internally search for matching
361
- * `content-type` based on the file name suffix.
362
- * However, if it is a TypeScript file such as `a.ts`, it may not be correctly matched
363
- * as a JavaScript script. You need to modify `a.ts` to `a.js` as the value passed
364
- * in order to recognize it correctly.
365
- * @see https://github.com/jshttp/mime-db
366
- * @default 'json'
367
- */
368
- type: 'json',
369
-
370
- /**
371
- * Response Body
372
- * Support `string/number/array/object/buffer/ReadableStream`
373
- * You can also use libraries such as' mockjs' to generate data content
374
- * @type string | number | array | object | ReadableStream | buffer
375
- * @type (request: { headers, query, body, params, refererQuery, getCookie }) => any | Promise<any>
376
- */
377
- body: '',
378
-
379
- /**
380
- * If the mock requirement cannot be solved through `body` configuration,
381
- * then it can be achieved by configuring response and exposing the interface of http server
382
- * to realize fully controllable custom configuration in req parameters.
383
- * The parsing of query, body and params has been built-in, so you can use them directly.
384
- * Don't forget to return response data through `res.end()` or skip mock by calling `next()`.
385
- */
386
- response(req, res, next) {
387
- res.end()
388
- },
389
- /**
390
- * Request validator, return mock data if validated, otherwise do not use current mock.
391
- * This is useful in scenarios where an interface needs to return different data based
392
- * on different input parameters.
393
- * Validators can solve this type of problem well by dividing the same URL into multiple
394
- * mock configurations and determining which one is effective based on the validator.
395
- *
396
- * @type { headers, body, query, params, refererQuery }
397
- * If the validator passed in is an object,
398
- * then the validation method is to deeply compare whether
399
- * `headers/body/query/params/refererQuery` of the requested interface contain
400
- * the `key-value` of the validator.
401
- *
402
- * @type (request) => boolean
403
- * If the validator passed in is a function,
404
- * then the data related to the requested interface will be provided as input parameters
405
- * for users to perform custom validation and return a boolean.
406
- *
407
- */
408
- validator: {
409
- headers: {},
410
- body: {},
411
- query: {},
412
- params: {},
413
- /**
414
- * refererQuery validates the query parameters in the URL of the request source page,
415
- * which allows for direct modification of parameters in the browser address bar
416
- * to obtain different simulated data.
417
- */
418
- refererQuery: {}
419
- },
420
- })
421
- ```
422
-
423
- ``` ts
424
- // Configure the WebSocket mock
425
- export default defineMock({
426
- /**
427
- * Request address, supports the `/api/user/:id` format.
428
- * The plugin matches the path through `path-to-regexp`.
429
- * @see https://github.com/pillarjs/path-to-regexp
430
- */
431
- url: '/api/test',
432
- /**
433
- * Value must be explicitly specified as `true`.
434
- * The plugin needs to make a judgment based on this field.
435
- */
436
- ws: true,
437
- /**
438
- * Configure the WebSocketServer
439
- * @see https://github.com/websockets/ws/blob/master/doc/ws.md#class-websocketserver
440
- * If there are some additional automatically executed tasks or loop
441
- * tasks in the setup function,a callback needs to be passed in
442
- * `onCleanup()` to clear these tasks.
443
- * This is because when the plugin is hot updated,
444
- * it needs to re-execute setup and clear previous tasks; otherwise,
445
- * duplicate tasks may cause conflicts.
446
- * `onCleanup()` can be called multiple times within setup.
447
- * @type `(wss: WebSocketServer, context: SetupContext) => void`
448
- */
449
- setup(wss, { onCleanup }) {
450
- wss.on('connection', (ws, request) => {
451
- ws.on('message', (rawData) => {})
452
- const timer = setInterval(() => ws.send('data'), 1000)
453
- onCleanup(() => clearInterval(timer))
454
- })
455
- }
456
- })
457
- ```
458
-
459
- ### Request/Response Enhance
460
-
461
- When defining methods using `headers`, `body`, and `response`, the plugin adds new content to the `request` and `response` parameters.
462
-
463
- **In Request:**
464
-
465
- The original type of `request` is [`Connect.IncomingMessage`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/connect/index.d.ts). The plugin adds data such as `query`, `params`, `body`, `refererQuery`, and the `getCookie(name)` method for obtaining cookie information on this basis.
466
-
467
- ```ts
468
- type Request = Connect.IncomingMessage & {
469
- query: object
470
- params: object
471
- body: any
472
- refererQuery: object
473
- getCookie: (name: string, option?: Cookies.GetOption) => string | undefined
474
- }
475
- ```
476
-
477
- **In Response:**
478
-
479
- The original type of `response` is `http.ServerResponse<http.IncomingMessage>`. The plugin adds `setCookie(name, value)` method for configuration cookies on this basis.
480
-
481
- ``` ts
482
- type Response = http.ServerResponse<http.IncomingMessage> & {
483
- setCookie: (
484
- name: string,
485
- value?: string | null,
486
- option?: Cookies.SetOption,
487
- ) => void
488
- }
489
- ```
490
-
491
- > **Tips:**
492
- >
493
- > If you write mock files using json/json5,
494
- > the 'response' method is not supported,
495
- > as is the function form that uses other fields.
496
-
497
- ## Share Mock Data
498
-
499
- Due to each `mock` file being compiled as a separate entry point, the local files they depend on are also compiled within. Additionally, each mock file has an independent scope. This means that even if multiple mock files collectively depend on a `data.ts` file, they cannot share data. If one mock file modifies the data in `data.ts`, other mock files will not receive the updated data.
500
-
501
- To address this, the plugin offers a `defineMockData` function, which allows using `data.ts` as a shared data source within mock files.
502
-
503
- ```ts
504
- type defineMockData<T> = (
505
- key: string, // key
506
- initialData: T, // initial data
507
- ) => [getter, setter] & { value: T }
508
- ```
509
-
510
- ### Exp
511
-
512
- `data.ts`
513
-
514
- ```ts
515
- import { defineMockData } from 'vite-plugin-mock-dev-server'
516
-
517
- export default defineMockData('posts', [
518
- { id: '1', title: 'title1', content: 'content1' },
519
- { id: '2', title: 'title2', content: 'content2' },
520
- ])
521
- ```
522
-
523
- `*.mock.ts`
524
-
525
- ```ts
526
- import { defineMock } from 'vite-plugin-mock-dev-server'
527
- import posts from './data'
528
-
529
- export default defineMock([
530
- {
531
- url: '/api/posts',
532
- body: () => posts.value
533
- },
534
- {
535
- url: '/api/posts/delete/:id',
536
- body: (params) => {
537
- const id = params.id
538
- posts.value = posts.value.filter(post => post.id !== id)
539
- return { success: true }
540
- }
541
- }
542
- ])
543
- ```
544
-
545
- > **Tips:**
546
- >
547
- > The `defineMockData` function relies solely on the shared data support provided by `memory`.
548
- > If persistent mock data is required, it is recommended to use a `nosql` database like `lowdb` or `level`.
549
-
550
- ## Custom-Path-Matching-Priority
551
-
552
- > Custom rules only affect links with dynamic parameters, such as: `/api/user/:id`
553
-
554
- The priority of the path matching rules built into the plugin can already meet most needs, but if you need more flexible customization of the matching rule priority, you can use the `priority` parameter.
555
-
556
- Exp:
557
-
558
- ```ts
559
- import { defineConfig } from 'vite'
560
- import mockPlugin from 'vite-plugin-mock-dev-server'
561
-
562
- export default defineConfig({
563
- plugins: [
564
- mockPlugin({
565
- priority: {
566
- // The priority of matching rules is global.
567
- // The rules declared in this option will take priority over the default rules.
568
- // The higher the position of the rule in the array, the higher the priority.
569
- global: ['/api/:a/b/c', '/api/a/:b/c', '/api/a/b/:c'],
570
- // For some special cases where the priority of certain rules needs to be adjusted,
571
- // this option can be used. For example, when a request matches both Rule A and Rule B,
572
- // and Rule A has a higher priority than Rule B, but it is desired for Rule B to take effect.
573
- special: {
574
- // When both A and B or C match, and B or C is at the top of the sort order,
575
- // insert A into the top position.
576
- // The `when` option is used to further constrain the priority adjustment to
577
- // be effective only for certain requests.
578
- '/api/:a/:b/c': {
579
- rules: ['/api/a/:b/:c', '/api/a/b/:c'],
580
- when: ['/api/a/b/c']
581
- },
582
- // If no `when` is specified, it means that all requests matching the rules need to have their priorities adjusted. It can be abbreviated as `[key]: [...rules]`
583
- '/api/:a/b': ['/api/a/:b'],
584
- }
585
- }
586
- })
587
- ]
588
- })
589
- ```
590
-
591
- > **Tip:**
592
- >
593
- > `priority` although it can adjust the priority,
594
- > most of the time you do not need to do so. For some special requests,
595
- > you can use static rules instead of `priority`,
596
- > as static rules always have the highest priority.
597
-
598
- ## Example
599
-
600
- `mock/**/*.mock.{ts,js,mjs,cjs,json,json5}`
601
-
602
- See more examples: [example](/example/)
603
-
604
- **exp:** Match `/api/test`, And returns a response body content with empty data
605
-
606
- ``` ts
607
- export default defineMock({
608
- url: '/api/test',
609
- })
610
- ```
611
-
612
- **exp:** Match `/api/test` , And returns a static content data
613
-
614
- ``` ts
615
- export default defineMock({
616
- url: '/api/test',
617
- body: { a: 1 },
618
- })
619
- ```
620
-
621
- **exp:** Only Support `GET` Method
622
-
623
- ``` ts
624
- export default defineMock({
625
- url: '/api/test',
626
- method: 'GET'
627
- })
628
- ```
629
-
630
- **exp:** In the response header, add a custom header and cookie
631
-
632
- ``` ts
633
- export default defineMock({
634
- url: '/api/test',
635
- headers: { 'X-Custom': '12345678' },
636
- cookies: { 'my-cookie': '123456789' },
637
- })
638
- ```
639
-
640
- ``` ts
641
- export default defineMock({
642
- url: '/api/test',
643
- headers({ query, body, params, headers }) {
644
- return { 'X-Custom': query.custom }
645
- },
646
- cookies() {
647
- return { 'my-cookie': '123456789' }
648
- }
649
- })
650
- ```
651
-
652
- **exp:** Define multiple mock requests for the same URL and match valid rules with validators
653
-
654
- ``` ts
655
- export default defineMock([
656
- // Match /api/test?a=1
657
- {
658
- url: '/api/test',
659
- validator: {
660
- query: { a: 1 },
661
- },
662
- body: { message: 'query.a == 1' },
663
- },
664
- // Match /api/test?a=2
665
- {
666
- url: '/api/test',
667
- validator: {
668
- query: { a: 2 },
669
- },
670
- body: { message: 'query.a == 2' },
671
- },
672
- {
673
- // `?a=3` will resolve to `validator.query`
674
- url: '/api/test?a=3',
675
- body: { message: 'query.a == 3' }
676
- },
677
- // Hitting the POST /api/test request, and in the request body,
678
- // field a is an array that contains items with values of 1 and 2.
679
- {
680
- url: '/api/test',
681
- method: ['POST'],
682
- validator: { body: { a: [1, 2] } }
683
- }
684
- ])
685
- ```
686
-
687
- **exp:** Response Delay
688
-
689
- ``` ts
690
- export default defineMock({
691
- url: '/api/test',
692
- delay: 6000, // delay 6 seconds
693
- })
694
- ```
695
-
696
- **exp:** The interface request failed
697
-
698
- ``` ts
699
- export default defineMock({
700
- url: '/api/test',
701
- status: 502,
702
- statusText: 'Bad Gateway'
703
- })
704
- ```
705
-
706
- **exp:** Dynamic route matching
707
-
708
- ``` ts
709
- export default defineMock({
710
- url: '/api/user/:userId',
711
- body({ params }) {
712
- return { userId: params.userId }
713
- }
714
- })
715
- ```
716
-
717
- The `userId` in the route will be resolved into the `request.params` object.
718
-
719
- **exp**:** Use the buffer to respond data
720
-
721
- ```ts
722
- import { Buffer } from 'node:buffer'
723
-
724
- // Since the default value of type is json,
725
- // although buffer is used for body during transmission,
726
- // the content-type is still json.
727
- export default defineMock({
728
- url: 'api/buffer',
729
- body: Buffer.from(JSON.stringify({ a: 1 }))
730
- })
731
- ```
732
-
733
- ``` ts
734
- // When the type is buffer, the content-type is application/octet-stream.
735
- // The data passed in through body will be converted to a buffer.
736
- export default defineMock({
737
- url: 'api/buffer',
738
- type: 'buffer',
739
- // Convert using Buffer.from(body) for internal use
740
- body: { a: 1 }
741
- })
742
- ```
743
-
744
- **exp:** Response file type
745
-
746
- Simulate file download, and pass in the file reading stream.
747
-
748
- ``` ts
749
- import { createReadStream } from 'node:fs'
750
-
751
- export default defineMock({
752
- url: '/api/download',
753
- // When you are unsure of the type, you can pass in the file name for internal parsing by the plugin.
754
- type: 'my-app.dmg',
755
- body: () => createReadStream('./my-app.dmg')
756
- })
757
- ```
758
-
759
- ```html
760
- <a href="/api/download" download="my-app.dmg">Download File</a>
761
- ```
762
-
763
- **exp:** Use `mockjs`:
764
-
765
- ``` ts
766
- import Mock from 'mockjs'
767
-
768
- export default defineMock({
769
- url: '/api/test',
770
- body: Mock.mock({
771
- 'list|1-10': [{
772
- 'id|+1': 1
773
- }]
774
- })
775
- })
776
- ```
777
-
778
- You need install `mockjs`
779
-
780
- **exp:** Use `response` to customize the response
781
-
782
- ``` ts
783
- export default defineMock({
784
- url: '/api/test',
785
- response(req, res, next) {
786
- const { query, body, params, headers } = req
787
- console.log(query, body, params, headers)
788
-
789
- res.status = 200
790
- res.setHeader('Content-Type', 'application/json')
791
- res.end(JSON.stringify({
792
- query,
793
- body,
794
- params,
795
- }))
796
- }
797
- })
798
- ```
799
-
800
- **exp:** Use json / json5
801
-
802
- ``` json
803
- {
804
- "url": "/api/test",
805
- "body": {
806
- "a": 1
807
- }
808
- }
809
- ```
810
-
811
- **exp:** multipart, upload files.
812
-
813
- use [`formidable`](https://www.npmjs.com/package/formidable#readme) to support.
814
-
815
- ``` html
816
- <form action="/api/upload" method="post" enctype="multipart/form-data">
817
- <p>
818
- <span>file: </span>
819
- <input type="file" name="files" multiple="multiple">
820
- </p>
821
- <p>
822
- <span>name:</span>
823
- <input type="text" name="name" value="mark">
824
- </p>
825
- <p>
826
- <input type="submit" value="submit">
827
- </p>
828
- </form>
829
- ```
830
-
831
- fields `files` mapping to `formidable.File`
832
-
833
- ``` ts
834
- export default defineMock({
835
- url: '/api/upload',
836
- method: 'POST',
837
- body(req) {
838
- const body = req.body
839
- return {
840
- name: body.name,
841
- files: body.files.map((file: any) => file.originalFilename),
842
- }
843
- },
844
- })
845
- ```
846
-
847
- **exp:** Graphql
848
-
849
- ``` ts
850
- import { buildSchema, graphql } from 'graphql'
851
-
852
- const schema = buildSchema(`
853
- type Query {
854
- hello: String
855
- }
856
- `)
857
- const rootValue = { hello: () => 'Hello world!' }
858
-
859
- export default defineMock({
860
- url: '/api/graphql',
861
- method: 'POST',
862
- body: async (request) => {
863
- const source = request.body.source
864
- const { data } = await graphql({ schema, rootValue, source })
865
- return data
866
- },
867
- })
868
- ```
869
-
870
- ``` ts
871
- fetch('/api/graphql', {
872
- method: 'POST',
873
- body: JSON.stringify({ source: '{ hello }' })
874
- })
875
- ```
876
-
877
- **exp:** WebSocket Mock
878
-
879
- ``` ts
880
- // ws.mock.ts
881
- export default defineMock({
882
- url: '/socket.io',
883
- ws: true,
884
- setup(wss, { onCleanup }) {
885
- const wsMap = new Map()
886
- wss.on('connection', (ws, req) => {
887
- const token = req.getCookie('token')
888
- wsMap.set(token, ws)
889
- ws.on('message', (raw) => {
890
- const data = JSON.parse(String(raw))
891
- if (data.type === 'ping')
892
- return
893
- // Broadcast
894
- for (const [_token, _ws] of wsMap.entires()) {
895
- if (_token !== token)
896
- _ws.send(raw)
897
- }
898
- })
899
- })
900
- wss.on('error', (err) => {
901
- console.error(err)
902
- })
903
- onCleanup(() => wsMap.clear())
904
- }
905
- })
906
- ```
907
-
908
- ``` ts
909
- // app.ts
910
- const ws = new WebSocket('ws://localhost:5173/socket.io')
911
- ws.addEventListener('open', () => {
912
- setInterval(() => {
913
- // heartbeat
914
- ws.send(JSON.stringify({ type: 'ping' }))
915
- }, 1000)
916
- }, { once: true })
917
- ws.addEventListener('message', (raw) => {
918
- console.log(raw)
919
- })
920
- ```
921
-
922
- ## Mock Services
923
-
924
- In some scenarios, it may be necessary to use the data provided by mock services for display purposes, but the project may have already been packaged, built and deployed without support from `Vite` and this plugin's mock service. Since this plugin supports importing various `node` modules in mock files at the design stage, the mock file cannot be inline into client build code.
925
-
926
- To meet such scenarios, on one hand, the plugin provides support under `vite preview`, and on the other hand, it also builds a small independent mock service application that can be deployed to relevant environments during `vite build`. This can then be forwarded through other HTTP servers like Nginx to actual ports for mock support.
927
-
928
- The default output is built into the directory `dist/mockServer`, generating files as follows:
929
-
930
- ``` sh
931
- ./mockServer
932
- ├── index.js
933
- ├── mock-data.js
934
- └── package.json
935
- ```
936
-
937
- In this directory, execute `npm install` to install dependencies, and then execute `npm start` to start the mock server.
938
-
939
- The default port is `8080`.
940
-
941
- You can access related `mock` interfaces through `localhost:8080/`.
942
-
943
- ## Archives
944
-
945
- [awesome-vite](https://github.com/vitejs/awesome-vite#helpers)
946
-
947
- ## Contributors
948
-
949
- <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
950
- [![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors)
951
- <!-- ALL-CONTRIBUTORS-BADGE:END -->
952
-
953
- <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
954
- <!-- prettier-ignore-start -->
955
- <!-- markdownlint-disable -->
956
- <table>
957
- <tbody>
958
- <tr>
959
- <td align="center" valign="top" width="14.28%"><a href="https://pengzhanbo.cn"><img src="https://avatars.githubusercontent.com/u/16745751?v=4?s=100" width="100px;" alt="pengzhanbo"/><br /><sub><b>pengzhanbo</b></sub></a><br /><a href="https://github.com/pengzhanbo/vite-plugin-mock-dev-server/commits?author=pengzhanbo" title="Documentation">📖</a> <a href="#ideas-pengzhanbo" title="Ideas, Planning, & Feedback">🤔</a> <a href="#example-pengzhanbo" title="Examples">💡</a> <a href="https://github.com/pengzhanbo/vite-plugin-mock-dev-server/commits?author=pengzhanbo" title="Code">💻</a></td>
960
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/jiadesen"><img src="https://avatars.githubusercontent.com/u/22772994?v=4?s=100" width="100px;" alt="jiadesen"/><br /><sub><b>jiadesen</b></sub></a><br /><a href="#ideas-jiadesen" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/pengzhanbo/vite-plugin-mock-dev-server/issues?q=author%3Ajiadesen" title="Bug reports">🐛</a></td>
961
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/yogibaba"><img src="https://avatars.githubusercontent.com/u/152670?v=4?s=100" width="100px;" alt="yogibaba"/><br /><sub><b>yogibaba</b></sub></a><br /><a href="https://github.com/pengzhanbo/vite-plugin-mock-dev-server/commits?author=yogibaba" title="Code">💻</a></td>
962
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/pfdgithub"><img src="https://avatars.githubusercontent.com/u/3262762?v=4?s=100" width="100px;" alt="pfdgithub"/><br /><sub><b>pfdgithub</b></sub></a><br /><a href="https://github.com/pengzhanbo/vite-plugin-mock-dev-server/commits?author=pfdgithub" title="Code">💻</a> <a href="https://github.com/pengzhanbo/vite-plugin-mock-dev-server/issues?q=author%3Apfdgithub" title="Bug reports">🐛</a></td>
963
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/chuyuandu"><img src="https://avatars.githubusercontent.com/u/6959138?v=4?s=100" width="100px;" alt="chuyuan du"/><br /><sub><b>chuyuan du</b></sub></a><br /><a href="https://github.com/pengzhanbo/vite-plugin-mock-dev-server/commits?author=chuyuandu" title="Code">💻</a></td>
964
- </tr>
965
- </tbody>
966
- </table>
967
-
968
- <!-- markdownlint-restore -->
969
- <!-- prettier-ignore-end -->
970
-
971
- <!-- ALL-CONTRIBUTORS-LIST:END -->
972
- <!-- prettier-ignore-start -->
973
- <!-- markdownlint-disable -->
974
-
975
- <!-- markdownlint-restore -->
976
- <!-- prettier-ignore-end -->
96
+ ## Links
977
97
 
978
- <!-- ALL-CONTRIBUTORS-LIST:END -->
98
+ - [vite](https://vitejs.dev/)
99
+ - [awesome-vite](https://github.com/vitejs/awesome-vite#helpers)
100
+ - [rspack-plugin-mock](https://github.com/pengzhanbo/rspack-plugin-mock) - **Rspack** and **Rsbuild** plugin for API mock server
979
101
 
980
102
  ## LICENSE
981
103
 
982
- [MIT](/LICENSE)
104
+ The plugin is licensed under the [MIT License](./LICENSE)
983
105
 
984
106
  [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fpengzhanbo%2Fvite-plugin-mock-dev-server?ref=badge_large)