warehouse-mock 1.0.0 → 1.0.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
@@ -1,90 +1,39 @@
1
- # warehouse-mock
1
+ # warehouse-mock-plugin
2
2
 
3
- 一个专为 Vue 2 项目设计的 Webpack 插件,支持 RPC 风格接口 mock,零业务代码侵入,实时更新。
3
+ <div align="center">
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/warehouse-mock.svg)](https://www.npmjs.com/package/warehouse-mock)
6
- [![license](https://img.shields.io/npm/l/warehouse-mock.svg)](https://github.com/CodeMomentYY/warehouse-mock/blob/main/LICENSE)
5
+ 极简 Vue Mock 插件,零业务代码侵入,完美支持 RPC 风格接口
7
6
 
8
- ## ✨ 特性
7
+ [![npm version](https://img.shields.io/npm/v/warehouse-mock-plugin.svg)](https://www.npmjs.com/package/warehouse-mock-plugin)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
9
 
10
- - ✅ **RPC 风格接口支持**: 完美支持 `/api?user.account.getInfo` 格式
11
- - ✅ **零业务代码侵入**: 只需修改配置文件,无需改动业务逻辑
12
- - ✅ **实时更新**: 修改 Mock 数据后刷新页面即可,无需重启服务
13
- - ✅ **按需 Mock**: 只拦截配置了 Mock 数据的接口,其他接口不受影响
14
- - ✅ **TypeScript 编写**: 类型安全,易于维护
15
- - ✅ **兼容性强**: 支持 Webpack 4/5,Vue CLI 3/4/5
10
+ </div>
16
11
 
17
- ## 📦 安装
12
+ ## 安装
18
13
 
19
14
  ```bash
20
- npm install warehouse-mock --save-dev
15
+ npm install warehouse-mock-plugin --save-dev
21
16
  ```
22
17
 
23
- ## 🚀 快速开始
18
+ ## 快速开始
24
19
 
25
20
  ### 1. 配置 vue.config.js
26
21
 
27
22
  ```javascript
28
- const WarehouseMockPlugin = require('warehouse-mock');
29
- const webpack = require('webpack');
30
- const path = require('path');
23
+ const WarehouseMockPlugin = require('warehouse-mock-plugin');
31
24
 
32
25
  const isMock = process.env.MOCK === 'true';
33
- const mockPlugin = isMock ? new WarehouseMockPlugin({
34
- mockPath: path.resolve(__dirname, 'warehouseMock'),
35
- }) : null;
36
26
 
37
27
  module.exports = {
38
28
  configureWebpack: config => {
39
- if (isMock && mockPlugin) {
40
- config.plugins.push(
41
- new webpack.DefinePlugin({
42
- 'process.env.VUE_APP_MOCK': JSON.stringify('true'),
43
- })
44
- );
45
- config.plugins.push(mockPlugin);
29
+ if (isMock) {
30
+ config.plugins.push(new WarehouseMockPlugin());
46
31
  }
47
- },
48
-
49
- devServer: {
50
- // Vue CLI 5.x (Webpack 5)
51
- setupMiddlewares: (middlewares, devServer) => {
52
- if (isMock && mockPlugin) {
53
- return mockPlugin.setupMiddlewares(middlewares, devServer);
54
- }
55
- return middlewares;
56
- },
57
-
58
- // Vue CLI 3.x/4.x (Webpack 4) 使用这个:
59
- // before: isMock && mockPlugin ? (app) => mockPlugin.runBefore(app) : undefined,
60
32
  }
61
33
  };
62
34
  ```
63
35
 
64
- ### 2. 修改 API 配置
65
-
66
- 在 `src/const/config.js` 中添加 Mock 模式判断:
67
-
68
- ```javascript
69
- const config = { env: process.env.VUE_APP_ENV || 'dev' };
70
-
71
- // Mock 模式优先判断
72
- if (process.env.VUE_APP_MOCK === 'true') {
73
- Object.assign(config, {
74
- API: '/mock-api',
75
- });
76
- } else if (config.env === 'dev') {
77
- Object.assign(config, {
78
- API: 'https://fat-api.hellobike.com/api',
79
- });
80
- }
81
-
82
- export default config;
83
- ```
84
-
85
- ### 3. 添加 Mock 脚本
86
-
87
- 在 `package.json` 中:
36
+ ### 2. 添加 Mock 脚本
88
37
 
89
38
  ```json
90
39
  {
@@ -94,114 +43,133 @@ export default config;
94
43
  }
95
44
  ```
96
45
 
97
- ### 4. 创建 Mock 数据
46
+ ### 3. 配置 API 切换
98
47
 
99
- 创建 `warehouseMock` 目录并添加 Mock 数据文件:
48
+ `src/const/config.js` 中:
100
49
 
101
- **warehouseMock/user.account.getInfo.json**:
102
- ```json
103
- {
104
- "code": 0,
105
- "msg": "success",
106
- "data": {
107
- "userId": 12345,
108
- "userName": "Mock 测试用户"
109
- }
50
+ ```javascript
51
+ if (process.env.VUE_APP_MOCK === 'true') {
52
+ config.API = '/mock-api';
53
+ } else {
54
+ config.API = 'https://your-api.com';
110
55
  }
111
56
  ```
112
57
 
58
+ ### 4. 创建 Mock 数据
59
+
60
+ 在项目根目录创建 `warehouseMock/` 文件夹,添加 JSON 文件:
61
+
62
+ ```
63
+ warehouseMock/
64
+ ├── user.account.getInfo.json
65
+ └── user.taurus.pointInfo.json
66
+ ```
67
+
113
68
  ### 5. 启动
114
69
 
115
70
  ```bash
116
71
  npm run mock
117
72
  ```
118
73
 
119
- ## ⚙️ 配置选项
74
+ ## 配置选项
120
75
 
121
76
  ```typescript
122
- new WarehouseMockPlugin({
123
- // 必填:Mock 数据存放目录
124
- mockPath: string;
77
+ interface MockPluginOptions {
78
+ // Mock 数据目录,默认 'warehouseMock'
79
+ mockPath?: string;
125
80
 
126
- // 可选:需要拦截的 API 路径前缀,默认 ['/api', '/mock-api']
81
+ // 需要拦截的 API 路径前缀,默认 ['/api', '/mock-api']
127
82
  apiPrefixes?: string[];
128
83
 
129
- // 可选:本地 API 路径前缀,默认 '/mock-api'
84
+ // 本地代理路径前缀,默认 '/mock-api'
130
85
  localApiPrefix?: string;
131
- })
86
+
87
+ // 是否启用,默认 true
88
+ enabled?: boolean;
89
+
90
+ // 是否自动注入环境变量 VUE_APP_MOCK,默认 true
91
+ injectEnv?: boolean;
92
+
93
+ // 响应延迟(毫秒),模拟网络延迟,默认 0
94
+ delay?: number;
95
+
96
+ // 代理配置:未匹配的请求转发到真实 API
97
+ proxy?: {
98
+ target: string;
99
+ changeOrigin?: boolean;
100
+ };
101
+ }
132
102
  ```
133
103
 
134
- ## 📝 Mock 文件命名规则
135
-
136
- ### RPC 风格(推荐)
137
-
138
- | 请求 URL | Mock 文件名 |
139
- |---------|-----------|
140
- | `/api?user.account.getInfo` | `user.account.getInfo.json` |
141
- | `/api?user.taurus.pointInfo` | `user.taurus.pointInfo.json` |
142
- | `/api?common.welfare.banner.query` | `common.welfare.banner.query.json` |
143
-
144
- ### RESTful 风格
104
+ ## 使用示例
145
105
 
146
- | 请求 URL | Mock 文件名(二选一) |
147
- |---------|---------------------|
148
- | `/api/user/info` | `api_user_info.json` (扁平化) |
149
- | `/api/user/info` | `api/user/info.json` (嵌套) |
106
+ ### 基础配置
150
107
 
151
- ## 🔍 调试工具
152
-
153
- ### 查看可用 Mock 列表
154
-
155
- 访问: `http://localhost:8080/__mock_list__`
156
-
157
- ### 直接访问 Mock 数据
158
-
159
- 访问: `http://localhost:8080/mock-api?user.account.getInfo`
108
+ ```javascript
109
+ new WarehouseMockPlugin({
110
+ mockPath: 'warehouseMock',
111
+ apiPrefixes: ['/api', '/mock-api']
112
+ })
113
+ ```
160
114
 
161
- ## 💡 为什么选择 warehouse-mock?
115
+ ### 代理模式
162
116
 
163
- ### 适用场景
117
+ 未匹配的请求转发到真实 API:
164
118
 
165
- - ✅ 后端接口未就绪,需要前端先行开发
166
- - ✅ 后端接口不稳定,需要本地 Mock 数据测试
167
- - ✅ 需要模拟特殊场景(错误、超时、边界数据等)
168
- - ✅ 使用 RPC 风格接口的项目(如 hellobike
119
+ ```javascript
120
+ new WarehouseMockPlugin({
121
+ proxy: {
122
+ target: 'https://fat-api.hellobike.com',
123
+ changeOrigin: true
124
+ }
125
+ })
126
+ ```
169
127
 
170
- ### 对比其他方案
128
+ ### 模拟网络延迟
171
129
 
172
- | 方案 | warehouse-mock | Mock.js | json-server |
173
- |-----|---------------|---------|-------------|
174
- | 零代码侵入 | ✅ | ❌ 需修改业务代码 | ❌ 需单独启动服务 |
175
- | RPC 支持 | ✅ | ❌ | ❌ |
176
- | 实时更新 | ✅ | ❌ | ✅ |
177
- | TypeScript | ✅ | ❌ | ❌ |
178
- | Webpack 集成 | ✅ | ❌ | ❌ |
130
+ ```javascript
131
+ new WarehouseMockPlugin({
132
+ delay: 500 // 500ms 延迟
133
+ })
134
+ ```
179
135
 
180
- ## 📚 完整示例
136
+ ## Mock 文件命名规则
181
137
 
182
- 查看完整的示例项目:[example-vue2](https://github.com/CodeMomentYY/warehouse-mock/tree/main/packages/example-vue2)
138
+ ### RPC 风格 (推荐)
183
139
 
184
- ## 常见问题
140
+ | 请求 URL | Mock 文件名 |
141
+ |---------|-----------|
142
+ | `GET /api?user.account.getInfo` | `user.account.getInfo.json` |
143
+ | `POST /mock-api?user.taurus.pointInfo` | `user.taurus.pointInfo.json` |
185
144
 
186
- **Q: Mock 没有生效?**
145
+ ### RESTful 风格
187
146
 
188
- 确保在 `src/const/config.js` 中添加了 Mock 模式判断,将 API 地址改为 `/mock-api`。
147
+ | 请求 URL | Mock 文件名 |
148
+ |---------|-----------|
149
+ | `GET /api/user/info` | `api_user_info.json` (扁平化) |
150
+ | `GET /api/user/info` | `api/user/info.json` (嵌套) |
189
151
 
190
- **Q: 修改 Mock 数据后需要重启服务吗?**
152
+ ## 调试工具
191
153
 
192
- 不需要!直接刷新浏览器页面即可。
154
+ ### 查看可用 Mock 列表
193
155
 
194
- **Q: 可以只 Mock 部分接口吗?**
156
+ 访问: `http://localhost:8080/__mock_list__`
195
157
 
196
- 可以!只有存在对应 JSON 文件的接口才会使用 Mock 数据。
158
+ ### 直接访问 Mock 数据
197
159
 
198
- ## 📄 许可证
160
+ 访问: `http://localhost:8080/mock-api?user.account.getInfo`
199
161
 
200
- MIT © CodeMomentYY
162
+ ## 核心特性
201
163
 
202
- ## 🔗 相关链接
164
+ - **极简配置** - vue.config.js 只需 3 行代码
165
+ - ✅ **零业务侵入** - 无需修改接口调用代码
166
+ - ✅ **RPC 风格支持** - 原生支持 RPC 接口
167
+ - ✅ **实时热更新** - 修改 Mock 数据,刷新即可
168
+ - ✅ **按需拦截** - 只拦截配置了 Mock 文件的接口
169
+ - ✅ **代理模式** - 未匹配请求转发到真实 API
170
+ - ✅ **自动注入环境变量** - 无需手动配置 DefinePlugin
171
+ - ✅ **兼容性强** - 支持 Webpack 4/5,Vue CLI 3/4/5
203
172
 
204
- - [GitHub 仓库](https://github.com/CodeMomentYY/warehouse-mock)
205
- - [问题反馈](https://github.com/CodeMomentYY/warehouse-mock/issues)
206
- - [更新日志](https://github.com/CodeMomentYY/warehouse-mock/releases)
173
+ ## License
207
174
 
175
+ MIT
package/dist/index.d.ts CHANGED
@@ -1,13 +1,21 @@
1
1
  import { Compiler } from 'webpack';
2
2
  interface MockPluginOptions {
3
- mockPath: string;
3
+ mockPath?: string;
4
4
  apiPrefixes?: string[];
5
5
  localApiPrefix?: string;
6
+ enabled?: boolean;
7
+ proxy?: {
8
+ target: string;
9
+ changeOrigin?: boolean;
10
+ };
11
+ injectEnv?: boolean;
12
+ delay?: number;
6
13
  }
7
14
  declare class WarehouseMockPlugin {
8
15
  private options;
9
16
  private resolvedMockPath;
10
- constructor(options: MockPluginOptions);
17
+ private isEnabled;
18
+ constructor(options?: MockPluginOptions);
11
19
  /**
12
20
  * 实时扫描 mock 目录,获取所有 mock 文件名列表
13
21
  */
@@ -17,6 +25,10 @@ declare class WarehouseMockPlugin {
17
25
  */
18
26
  getLocalApiPrefix(): string;
19
27
  apply(compiler: Compiler): void;
28
+ /**
29
+ * 自动注入环境变量 VUE_APP_MOCK
30
+ */
31
+ private injectEnvironmentVariable;
20
32
  /**
21
33
  * 公共方法:设置中间件 (Webpack 5 / Vue CLI 5+)
22
34
  */
@@ -29,5 +41,9 @@ declare class WarehouseMockPlugin {
29
41
  private ensureMockDirectory;
30
42
  private createDemoFile;
31
43
  private handleRequest;
44
+ /**
45
+ * 代理请求到真实 API(改进版)
46
+ */
47
+ private proxyRequest;
32
48
  }
33
49
  export = WarehouseMockPlugin;
package/dist/index.js CHANGED
@@ -6,9 +6,26 @@ const fs_1 = __importDefault(require("fs"));
6
6
  const path_1 = __importDefault(require("path"));
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  class WarehouseMockPlugin {
9
- constructor(options) {
9
+ constructor(options = {}) {
10
10
  this.resolvedMockPath = '';
11
- this.options = Object.assign({ apiPrefixes: ['/api', '/mock-api'], localApiPrefix: '/mock-api' }, options);
11
+ this.isEnabled = true;
12
+ // 默认配置
13
+ this.options = {
14
+ mockPath: options.mockPath || 'warehouseMock',
15
+ apiPrefixes: options.apiPrefixes || ['/api', '/mock-api'],
16
+ localApiPrefix: options.localApiPrefix || '/mock-api',
17
+ enabled: options.enabled !== undefined ? options.enabled : true,
18
+ proxy: options.proxy || undefined,
19
+ injectEnv: options.injectEnv !== undefined ? options.injectEnv : true,
20
+ delay: options.delay || 0,
21
+ };
22
+ // 判断是否启用(支持环境变量控制)
23
+ if (process.env.MOCK === 'false' || process.env.VUE_APP_MOCK === 'false') {
24
+ this.isEnabled = false;
25
+ }
26
+ if (this.options.enabled === false) {
27
+ this.isEnabled = false;
28
+ }
12
29
  }
13
30
  /**
14
31
  * 实时扫描 mock 目录,获取所有 mock 文件名列表
@@ -33,7 +50,16 @@ class WarehouseMockPlugin {
33
50
  return this.options.localApiPrefix || '/mock-api';
34
51
  }
35
52
  apply(compiler) {
53
+ // 如果未启用,直接返回
54
+ if (!this.isEnabled) {
55
+ console.log(chalk_1.default.yellow('[WarehouseMock] Mock 模式未启用'));
56
+ return;
57
+ }
36
58
  this.resolvedMockPath = path_1.default.resolve(compiler.context, this.options.mockPath);
59
+ // 自动注入环境变量 VUE_APP_MOCK
60
+ if (this.options.injectEnv) {
61
+ this.injectEnvironmentVariable(compiler);
62
+ }
37
63
  // 确保 mock 目录存在
38
64
  if (!fs_1.default.existsSync(this.resolvedMockPath)) {
39
65
  try {
@@ -46,21 +72,51 @@ class WarehouseMockPlugin {
46
72
  }
47
73
  }
48
74
  const mockFileList = this.getMockFileList();
49
- console.log(chalk_1.default.cyan(`[WarehouseMock] 已加载 ${mockFileList.length} 个 mock 文件: ${mockFileList.join(', ')}`));
50
- const devServerOptions = compiler.options.devServer || {};
51
- const originalSetupMiddlewares = devServerOptions.setupMiddlewares;
52
- if (!compiler.options.devServer) {
53
- compiler.options.devServer = {};
54
- }
55
- // 适用于 Webpack 5 (setupMiddlewares)
56
- compiler.options.devServer.setupMiddlewares = (middlewares, devServer) => {
57
- return this.setupMiddlewares(middlewares, devServer, originalSetupMiddlewares);
58
- };
59
- // 适用于 Webpack 4 (before)
60
- const originalBefore = devServerOptions.before;
61
- compiler.options.devServer.before = (app, server, compilerArg) => {
62
- this.runBefore(app, server, compilerArg, originalBefore);
63
- };
75
+ console.log(chalk_1.default.cyan(`[WarehouseMock] 已加载 ${mockFileList.length} 个 mock 文件`));
76
+ if (mockFileList.length > 0) {
77
+ console.log(chalk_1.default.gray(` → ${mockFileList.join(', ')}`));
78
+ }
79
+ if (this.options.proxy) {
80
+ console.log(chalk_1.default.cyan(`[WarehouseMock] 代理模式: 未匹配请求 → ${this.options.proxy.target}`));
81
+ }
82
+ // 注意:devServer 的配置需要在 vue.config.js 中手动配置
83
+ // 对于 Webpack 5 使用 setupMiddlewares
84
+ // 对于 Webpack 4 使用 before
85
+ }
86
+ /**
87
+ * 自动注入环境变量 VUE_APP_MOCK
88
+ */
89
+ injectEnvironmentVariable(compiler) {
90
+ try {
91
+ // 使用 compiler 的 webpack 实例
92
+ const { webpack } = compiler;
93
+ if (webpack && webpack.DefinePlugin) {
94
+ const definePlugin = new webpack.DefinePlugin({
95
+ 'process.env.VUE_APP_MOCK': JSON.stringify('true'),
96
+ });
97
+ if (!compiler.options.plugins) {
98
+ compiler.options.plugins = [];
99
+ }
100
+ compiler.options.plugins.push(definePlugin);
101
+ console.log(chalk_1.default.gray('[WarehouseMock] 已注入环境变量: VUE_APP_MOCK=true'));
102
+ }
103
+ else {
104
+ // 备用方案:直接require webpack
105
+ const webpackModule = require('webpack');
106
+ const definePlugin = new webpackModule.DefinePlugin({
107
+ 'process.env.VUE_APP_MOCK': JSON.stringify('true'),
108
+ });
109
+ if (!compiler.options.plugins) {
110
+ compiler.options.plugins = [];
111
+ }
112
+ compiler.options.plugins.push(definePlugin);
113
+ console.log(chalk_1.default.gray('[WarehouseMock] 已注入环境变量: VUE_APP_MOCK=true'));
114
+ }
115
+ }
116
+ catch (err) {
117
+ console.error(chalk_1.default.red(`[WarehouseMock] 注入环境变量失败: ${err}`));
118
+ console.log(chalk_1.default.yellow('[WarehouseMock] 请在 vue.config.js 中手动配置 DefinePlugin'));
119
+ }
64
120
  }
65
121
  /**
66
122
  * 公共方法:设置中间件 (Webpack 5 / Vue CLI 5+)
@@ -131,7 +187,7 @@ class WarehouseMockPlugin {
131
187
  }
132
188
  }
133
189
  handleRequest(req, res, next, mockPath) {
134
- var _a, _b;
190
+ var _a, _b, _c;
135
191
  const url = req.path || ((_a = req.url) === null || _a === void 0 ? void 0 : _a.split('?')[0]);
136
192
  if (!url) {
137
193
  return next();
@@ -144,6 +200,8 @@ class WarehouseMockPlugin {
144
200
  res.end(JSON.stringify({
145
201
  mockList: fileList,
146
202
  localApiPrefix: this.getLocalApiPrefix(),
203
+ proxy: ((_b = this.options.proxy) === null || _b === void 0 ? void 0 : _b.target) || null,
204
+ enabled: this.isEnabled,
147
205
  }));
148
206
  return;
149
207
  }
@@ -153,7 +211,7 @@ class WarehouseMockPlugin {
153
211
  }
154
212
  // 检查是否在允许的 API 前缀范围内
155
213
  const { apiPrefixes } = this.options;
156
- const isApiRequest = (_b = apiPrefixes === null || apiPrefixes === void 0 ? void 0 : apiPrefixes.some((prefix) => url.startsWith(prefix))) !== null && _b !== void 0 ? _b : true;
214
+ const isApiRequest = (_c = apiPrefixes === null || apiPrefixes === void 0 ? void 0 : apiPrefixes.some((prefix) => url.startsWith(prefix))) !== null && _c !== void 0 ? _c : true;
157
215
  if (!isApiRequest) {
158
216
  return next();
159
217
  }
@@ -216,29 +274,142 @@ class WarehouseMockPlugin {
216
274
  }
217
275
  }
218
276
  if (matched) {
219
- console.log(chalk_1.default.green(`[WarehouseMock] 拦截: ${matchedName} -> ${path_1.default.basename(filePath)}`));
220
- try {
221
- const data = fs_1.default.readFileSync(filePath, 'utf-8');
277
+ console.log(chalk_1.default.green(`[WarehouseMock] 拦截: ${req.url || url}`));
278
+ console.log(chalk_1.default.gray(` → 返回: ${path_1.default.basename(filePath)}`));
279
+ // 模拟网络延迟
280
+ const respond = () => {
222
281
  try {
223
- const jsonData = JSON.parse(data);
282
+ const data = fs_1.default.readFileSync(filePath, 'utf-8');
283
+ try {
284
+ const jsonData = JSON.parse(data);
285
+ res.setHeader('Content-Type', 'application/json');
286
+ res.setHeader('X-Mock-By', 'WarehouseMock');
287
+ res.end(JSON.stringify(jsonData));
288
+ }
289
+ catch (jsonErr) {
290
+ console.warn(chalk_1.default.yellow(`[WarehouseMock] 无效的 JSON 文件: ${filePath}`));
291
+ res.setHeader('Content-Type', 'text/plain');
292
+ res.end(data);
293
+ }
294
+ }
295
+ catch (e) {
296
+ console.error(chalk_1.default.red(`[WarehouseMock] 读取 Mock 文件失败: ${e}`));
297
+ res.statusCode = 500;
298
+ res.end('Mock Read Error');
299
+ }
300
+ };
301
+ if (this.options.delay > 0) {
302
+ setTimeout(respond, this.options.delay);
303
+ }
304
+ else {
305
+ respond();
306
+ }
307
+ return;
308
+ }
309
+ // 未匹配到 Mock 文件
310
+ if (this.options.proxy) {
311
+ // 如果配置了代理,转发到真实 API
312
+ console.log(chalk_1.default.gray(`[WarehouseMock] ⊳ 代理: ${req.url || url} → ${this.options.proxy.target}`));
313
+ this.proxyRequest(req, res, next);
314
+ }
315
+ else {
316
+ // 未配置代理,直接放行
317
+ next();
318
+ }
319
+ }
320
+ /**
321
+ * 代理请求到真实 API(改进版)
322
+ */
323
+ proxyRequest(req, res, next) {
324
+ if (!this.options.proxy) {
325
+ return next();
326
+ }
327
+ try {
328
+ const http = require('http');
329
+ const https = require('https');
330
+ const url = require('url');
331
+ // 构建完整的目标 URL
332
+ // 将 /mock-api?xxx 转换为 真实API/api?xxx
333
+ const targetUrl = this.options.proxy.target + req.url.replace('/mock-api', '/api');
334
+ const parsedUrl = url.parse(targetUrl);
335
+ const isHttps = parsedUrl.protocol === 'https:';
336
+ const lib = isHttps ? https : http;
337
+ // 清理请求头
338
+ const headers = Object.assign({}, req.headers);
339
+ delete headers.host;
340
+ headers.host = parsedUrl.hostname;
341
+ // 创建代理请求
342
+ const proxyReq = lib.request({
343
+ hostname: parsedUrl.hostname,
344
+ port: parsedUrl.port || (isHttps ? 443 : 80),
345
+ path: parsedUrl.path,
346
+ method: req.method,
347
+ headers: headers,
348
+ timeout: 30000, // 30秒超时
349
+ }, (proxyRes) => {
350
+ // 转发响应头
351
+ res.writeHead(proxyRes.statusCode, proxyRes.headers);
352
+ // 转发响应体
353
+ proxyRes.pipe(res);
354
+ });
355
+ // 错误处理
356
+ proxyReq.on('error', (err) => {
357
+ console.error(chalk_1.default.red(`[WarehouseMock] 代理请求失败: ${err.message}`));
358
+ console.error(chalk_1.default.red(` 目标地址: ${targetUrl}`));
359
+ // 返回友好的错误信息
360
+ if (!res.headersSent) {
361
+ res.statusCode = 502;
224
362
  res.setHeader('Content-Type', 'application/json');
225
- res.end(JSON.stringify(jsonData));
363
+ res.end(JSON.stringify({
364
+ code: -1,
365
+ msg: `代理请求失败: ${err.message}`,
366
+ error: 'PROXY_ERROR'
367
+ }));
226
368
  }
227
- catch (jsonErr) {
228
- console.warn(chalk_1.default.yellow(`[WarehouseMock] 无效的 JSON 文件: ${filePath}`));
229
- res.setHeader('Content-Type', 'text/plain');
230
- res.end(data);
369
+ });
370
+ // 超时处理
371
+ proxyReq.on('timeout', () => {
372
+ proxyReq.destroy();
373
+ if (!res.headersSent) {
374
+ res.statusCode = 504;
375
+ res.setHeader('Content-Type', 'application/json');
376
+ res.end(JSON.stringify({
377
+ code: -1,
378
+ msg: '代理请求超时',
379
+ error: 'PROXY_TIMEOUT'
380
+ }));
231
381
  }
232
- return;
382
+ });
383
+ // 转发请求体
384
+ if (req.method === 'POST' || req.method === 'PUT') {
385
+ // 处理 POST/PUT 请求的 body
386
+ let body = '';
387
+ req.on('data', (chunk) => {
388
+ body += chunk.toString();
389
+ });
390
+ req.on('end', () => {
391
+ if (body) {
392
+ proxyReq.write(body);
393
+ }
394
+ proxyReq.end();
395
+ });
233
396
  }
234
- catch (e) {
235
- console.error(chalk_1.default.red(`[WarehouseMock] 读取 Mock 文件失败: ${e}`));
397
+ else {
398
+ proxyReq.end();
399
+ }
400
+ }
401
+ catch (err) {
402
+ console.error(chalk_1.default.red(`[WarehouseMock] 代理配置错误: ${err}`));
403
+ if (!res.headersSent) {
236
404
  res.statusCode = 500;
237
- res.end('Mock Read Error');
238
- return;
405
+ res.setHeader('Content-Type', 'application/json');
406
+ res.end(JSON.stringify({
407
+ code: -1,
408
+ msg: `代理配置错误: ${err}`,
409
+ error: 'PROXY_CONFIG_ERROR'
410
+ }));
239
411
  }
240
412
  }
241
- next();
242
413
  }
243
414
  }
244
415
  module.exports = WarehouseMockPlugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "warehouse-mock",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "一个专为 Vue 2 项目设计的 Webpack 插件,支持 RPC 风格接口 mock,零业务代码侵入,实时更新",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -39,18 +39,18 @@
39
39
  "chokidar": "^3.5.3"
40
40
  },
41
41
  "devDependencies": {
42
- "typescript": "^5.0.0",
43
- "webpack": "^5.0.0",
44
- "webpack-dev-server": "^4.0.0",
42
+ "@types/node": "^18.0.0",
45
43
  "@types/webpack": "^5.0.0",
46
44
  "@types/webpack-dev-server": "^4.0.0",
47
- "@types/node": "^18.0.0"
45
+ "typescript": "^5.0.0",
46
+ "webpack": "^5.0.0",
47
+ "webpack-dev-server": "^4.0.0"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "webpack": "^4.0.0 || ^5.0.0"
51
51
  },
52
52
  "engines": {
53
53
  "node": ">=12.0.0"
54
- }
54
+ },
55
+ "gitHead": "dd7a56f686885eebc054fa738235ddf882ca02fa"
55
56
  }
56
-