|
| 1 | +# Mat 项目技术规格说明 |
| 2 | + |
| 3 | +## 🎯 项目概述 |
| 4 | + |
| 5 | +**Mat** 是一个基于 Node.js 的命令行工具,主要用于前端开发中的本地服务器搭建、代理转发和资源管理。它是一个轻量级的开发服务器,特别适合前端开发过程中的调试和测试需求。 |
| 6 | + |
| 7 | +## 📋 核心特性 |
| 8 | + |
| 9 | +### 1. **HTTP/HTTPS 服务器** |
| 10 | +- 支持 HTTP 和 HTTPS 协议 |
| 11 | +- 可配置端口、根目录等基本参数 |
| 12 | +- 内置静态文件服务 |
| 13 | + |
| 14 | +### 2. **反向代理功能** |
| 15 | +- 支持将本地请求代理到远程服务器 |
| 16 | +- 支持 HTTPS 代理 |
| 17 | +- 具备 RAP 平台集成支持 |
| 18 | +- 支持请求头修改和来源变更 |
| 19 | +- **NEW: SSE (Server-Sent Events) 支持**: 新增专用流式代理处理器,支持实时数据推送和长连接 |
| 20 | + |
| 21 | +### 3. **Combo URL 处理** |
| 22 | +- 支持类似阿里 CDN 的 combo URL 功能 |
| 23 | +- 可以将多个资源合并为一个请求 (如:`/path/??file1.js,file2.js`) |
| 24 | +- 自动处理资源拆分和合并 |
| 25 | + |
| 26 | +### 4. **URL 重写** |
| 27 | +- 支持通过正则表达式重写 URL |
| 28 | +- 支持函数式 URL 转换 |
| 29 | +- 适用于开发环境到生产环境的路径映射 |
| 30 | + |
| 31 | +### 5. **中间件架构** |
| 32 | +- 基于 Koa.js 框架构建 |
| 33 | +- 模块化的中间件设计 |
| 34 | +- 支持自定义中间件扩展 |
| 35 | + |
| 36 | +## 🏗️ 技术架构 |
| 37 | + |
| 38 | +### 核心依赖 |
| 39 | +- **Koa.js**: Web 框架基础 |
| 40 | +- **Orchestrator**: 任务管理器 (类似 Gulp) |
| 41 | +- **Liftoff**: CLI 工具启动器 |
| 42 | +- **co-request**: 异步 HTTP 请求 |
| 43 | + |
| 44 | +### 中间件系统 |
| 45 | +1. **Error 中间件**: 错误处理 |
| 46 | +2. **Logger 中间件**: 请求日志记录 |
| 47 | +3. **Combo 中间件**: Combo URL 处理 |
| 48 | +4. **Static 中间件**: 静态文件服务 |
| 49 | +5. **Proxy 中间件**: 反向代理 |
| 50 | +6. **URL 中间件**: URL 规则匹配和重写 |
| 51 | + |
| 52 | +### 项目结构 |
| 53 | +``` |
| 54 | +mat/ |
| 55 | +├── bin/ |
| 56 | +│ └── mat # CLI 入口文件 |
| 57 | +├── lib/ |
| 58 | +│ └── middleware/ # 中间件模块 |
| 59 | +│ ├── combo.js # Combo URL 处理 |
| 60 | +│ ├── error.js # 错误处理 |
| 61 | +│ ├── logger.js # 日志记录 |
| 62 | +│ ├── proxy.js # 反向代理 |
| 63 | +│ ├── static.js # 静态文件服务 |
| 64 | +│ └── url.js # URL 规则匹配 |
| 65 | +├── util/ # 工具函数 |
| 66 | +├── index.js # 主模块 |
| 67 | +└── package.json # 项目配置 |
| 68 | +``` |
| 69 | + |
| 70 | +## 💡 使用场景 |
| 71 | + |
| 72 | +### 1. **前端开发调试** |
| 73 | +```javascript |
| 74 | +// 开发环境代理配置 |
| 75 | +mat.task('daily', function () { |
| 76 | + mat.url([/\.json/]) |
| 77 | + .use(proxy({ |
| 78 | + proxyPass: 'your.proxy.host' |
| 79 | + })) |
| 80 | +}) |
| 81 | +``` |
| 82 | + |
| 83 | +### 2. **资源合并服务** |
| 84 | +```javascript |
| 85 | +// Combo URL 处理 |
| 86 | +mat.task('combohandler', function () { |
| 87 | + mat.env({ |
| 88 | + combohandler: true |
| 89 | + }) |
| 90 | + |
| 91 | + mat.url([/\.js/]) |
| 92 | + .rewrite([ |
| 93 | + [/-min/g, ''] |
| 94 | + ]) |
| 95 | +}) |
| 96 | +``` |
| 97 | + |
| 98 | +### 3. **环境切换** |
| 99 | +```javascript |
| 100 | +// URL 重写实现环境切换 |
| 101 | +mat.task('online', function () { |
| 102 | + mat.url([/\.js/]) |
| 103 | + .rewrite([ |
| 104 | + [/-min\.js/g, '.js'] |
| 105 | + ]) |
| 106 | +}) |
| 107 | +``` |
| 108 | + |
| 109 | +### 4. **NEW: SSE (Server-Sent Events) 代理** |
| 110 | +```javascript |
| 111 | +// SSE 长连接代理配置 |
| 112 | +mat.task('sse', function () { |
| 113 | + // SSE 接口代理,支持流式传输 - 通过 Accept 头自动检测 |
| 114 | + mat.url([/\/api\/events/, /\/stream/]) |
| 115 | + .use(proxy({ |
| 116 | + proxyPass: 'http://api.example.com', |
| 117 | + isChangeOrigin: true |
| 118 | + })) |
| 119 | + |
| 120 | + // 或者显式启用 SSE |
| 121 | + mat.url([/\/api\/sse/]) |
| 122 | + .sse({ |
| 123 | + enabled: true, |
| 124 | + timeout: 0, // 无超时限制 |
| 125 | + keepAlive: true |
| 126 | + }) |
| 127 | + .use(proxy({ |
| 128 | + proxyPass: 'http://api.example.com', |
| 129 | + isChangeOrigin: true |
| 130 | + })) |
| 131 | +}) |
| 132 | +``` |
| 133 | + |
| 134 | +## 🔧 API 接口 |
| 135 | + |
| 136 | +### Mat 类主要方法 |
| 137 | + |
| 138 | +#### `mat.env(options)` |
| 139 | +配置运行环境参数 |
| 140 | +- `port`: 服务端口 |
| 141 | +- `root`: 静态文件根目录 |
| 142 | +- `isHttps`: 是否启用 HTTPS |
| 143 | +- `combohandler`: 是否启用 Combo URL 处理 |
| 144 | +- `timeout`: 请求超时时间 |
| 145 | +- `limit`: 请求体大小限制 |
| 146 | + |
| 147 | +#### `mat.url(rules)` |
| 148 | +创建 URL 规则匹配器 |
| 149 | +- `rules`: 正则表达式数组或函数数组 |
| 150 | + |
| 151 | +#### `mat.task(name, fn)` |
| 152 | +定义任务 (继承自 Orchestrator) |
| 153 | +- `name`: 任务名称 |
| 154 | +- `fn`: 任务执行函数 |
| 155 | + |
| 156 | +#### `mat.launch()` |
| 157 | +启动服务器 |
| 158 | + |
| 159 | +### URL 中间件方法 |
| 160 | + |
| 161 | +#### `url.use(middleware)` |
| 162 | +添加中间件到 URL 规则 |
| 163 | + |
| 164 | +#### `url.rewrite(rules)` |
| 165 | +配置 URL 重写规则 |
| 166 | +- `rules`: 重写规则数组 `[[pattern, replacement], ...]` |
| 167 | + |
| 168 | +#### `url.sse(sseConfig)` ⭐ **新增** |
| 169 | +配置 SSE (Server-Sent Events) 支持 |
| 170 | +- `sseConfig.enabled`: 是否显式启用 SSE (boolean) |
| 171 | +- `sseConfig.timeout`: SSE 专用超时时间,0 表示无限制 (number) |
| 172 | +- `sseConfig.keepAlive`: 是否保持连接活跃 (boolean) |
| 173 | + |
| 174 | +## 📈 版本历史 |
| 175 | + |
| 176 | +- **1.0.20** (当前版本): 稳定版本,完整功能支持 |
| 177 | +- **0.1.15**: 支持 ready 参数回调 |
| 178 | +- **0.1.14**: 修复 gzip 内容解析问题 |
| 179 | +- **0.1.13**: 增加超时配置 |
| 180 | +- **0.1.8-0.1.9**: 增加 Combo URL 支持 |
| 181 | +- **0.1.0**: 第一个稳定版本,基础功能 |
| 182 | + |
| 183 | +## 🎪 适用场景 |
| 184 | + |
| 185 | +1. **前端项目本地开发**: 提供静态文件服务 |
| 186 | +2. **接口代理调试**: 代理到开发/测试环境的 API |
| 187 | +3. **资源合并优化**: 处理多文件合并请求 |
| 188 | +4. **跨域问题解决**: 通过代理解决开发中的跨域问题 |
| 189 | +5. **路径映射**: 开发环境与生产环境的路径转换 |
| 190 | + |
| 191 | +## ⚡ 技术优势 |
| 192 | + |
| 193 | +- **轻量级**: 依赖精简,启动快速 |
| 194 | +- **扩展性**: 基于中间件的架构易于扩展 |
| 195 | +- **配置灵活**: 支持多种配置方式 |
| 196 | +- **集成友好**: 可作为其他工具链的一部分 |
| 197 | +- **任务管理**: 基于 Orchestrator 的任务系统 |
| 198 | + |
| 199 | +## 🚀 快速开始 |
| 200 | + |
| 201 | +### 安装 |
| 202 | +```bash |
| 203 | +npm install mat |
| 204 | +``` |
| 205 | + |
| 206 | +### 基本使用 |
| 207 | +```javascript |
| 208 | +var mat = require('mat') |
| 209 | + |
| 210 | +// 基本静态服务 |
| 211 | +mat.task('default', function() { |
| 212 | + mat.env({ |
| 213 | + port: 8989, |
| 214 | + root: './' |
| 215 | + }) |
| 216 | +}) |
| 217 | + |
| 218 | +// 启动服务 |
| 219 | +mat.start(['default'], function() { |
| 220 | + mat.launch() |
| 221 | +}) |
| 222 | +``` |
| 223 | + |
| 224 | +### 命令行使用 |
| 225 | +```bash |
| 226 | +# 启动默认任务 |
| 227 | +mat |
| 228 | + |
| 229 | +# 启动指定任务 |
| 230 | +mat taskname |
| 231 | + |
| 232 | +# 指定配置文件 |
| 233 | +mat --matfile path/to/matfile.js |
| 234 | + |
| 235 | +# 快速代理模式 |
| 236 | +mat -p 8080 |
| 237 | +``` |
| 238 | + |
| 239 | +## 📝 配置文件示例 |
| 240 | + |
| 241 | +典型的 matfile.js: |
| 242 | +```javascript |
| 243 | +var mat = require('mat') |
| 244 | +var proxy = require('mat-proxy') |
| 245 | + |
| 246 | +// 开发环境配置 |
| 247 | +mat.task('dev', function() { |
| 248 | + mat.env({ |
| 249 | + port: 8989, |
| 250 | + root: './src', |
| 251 | + combohandler: true |
| 252 | + }) |
| 253 | + |
| 254 | + // API 代理 |
| 255 | + mat.url([/\/api\//]) |
| 256 | + .use(proxy({ |
| 257 | + proxyPass: 'http://dev.example.com' |
| 258 | + })) |
| 259 | + |
| 260 | + // 静态资源重写 |
| 261 | + mat.url([/\.js$/]) |
| 262 | + .rewrite([ |
| 263 | + [/\/build\//, '/src/'] |
| 264 | + ]) |
| 265 | +}) |
| 266 | + |
| 267 | +// 生产环境配置 |
| 268 | +mat.task('prod', function() { |
| 269 | + mat.env({ |
| 270 | + port: 8080, |
| 271 | + root: './dist' |
| 272 | + }) |
| 273 | +}) |
| 274 | +``` |
| 275 | + |
| 276 | +--- |
| 277 | + |
| 278 | +*本规格说明基于 Mat v1.0.20 版本分析生成* |
0 commit comments