@@ -8,14 +8,14 @@ var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
8
8
9
9
var _defineProperty3 = _interopRequireDefault ( _defineProperty2 ) ;
10
10
11
- var _keys = require ( 'babel-runtime/core-js/object/keys' ) ;
12
-
13
- var _keys2 = _interopRequireDefault ( _keys ) ;
14
-
15
11
var _stringify = require ( 'babel-runtime/core-js/json/stringify' ) ;
16
12
17
13
var _stringify2 = _interopRequireDefault ( _stringify ) ;
18
14
15
+ var _keys = require ( 'babel-runtime/core-js/object/keys' ) ;
16
+
17
+ var _keys2 = _interopRequireDefault ( _keys ) ;
18
+
19
19
var _typeof2 = require ( 'babel-runtime/helpers/typeof' ) ;
20
20
21
21
var _typeof3 = _interopRequireDefault ( _typeof2 ) ;
@@ -36,6 +36,7 @@ var connect = require('connect'),
36
36
logSymbols = require ( 'log-symbols' ) ,
37
37
favicon = require ( 'serve-favicon' ) ,
38
38
webpackDevMiddleware = require ( 'webpack-dev-middleware' ) ,
39
+ Mock = require ( 'mockjs' ) ,
39
40
httpProxy = require ( 'http-proxy-middleware' ) ;
40
41
41
42
var Manager = require ( '../modules/manager.js' ) ;
@@ -56,8 +57,10 @@ exports.setOptions = function (optimist) {
56
57
optimist . describe ( 'hot' , '开启 hot-reload' ) ;
57
58
optimist . alias ( 'v' , 'verbose' ) ;
58
59
optimist . describe ( 'v' , '显示详细编译信息' ) ;
59
- optimist . alias ( 'm' , 'middlewares' ) ;
60
- optimist . describe ( 'm' , '加载项目中间件' ) ;
60
+ optimist . alias ( 'mw' , 'middlewares' ) ;
61
+ optimist . describe ( 'mw' , '加载项目中间件' ) ;
62
+ optimist . alias ( 'm' , 'mock' ) ;
63
+ optimist . describe ( 'm' , '启用 mock 服务' ) ;
61
64
} ;
62
65
63
66
exports . run = function ( options ) {
@@ -66,12 +69,15 @@ exports.run = function (options) {
66
69
verbose = options . v || options . verbose ,
67
70
proxy = options . x || options . proxy ,
68
71
hot = options . hot ,
69
- middlewares = options . m || options . middlewares ,
72
+ middlewares = options . mw || options . middlewares ,
73
+ mock = options . m || options . mock ,
70
74
isHttps = options . s || options . https ,
71
75
port = options . p || options . port || 80 ;
72
76
73
77
var middlewareCache = { } ,
74
78
promiseCache = { } ,
79
+ mockCache = { } ,
80
+ mockRules = { } ,
75
81
allAssetsEntry = { } ,
76
82
watchCacheNames = { } ;
77
83
@@ -92,39 +98,6 @@ exports.run = function (options) {
92
98
} ) ;
93
99
}
94
100
95
- // proxy
96
- var currentProxy = [ ] ;
97
- app . use ( function ( req , res , next ) {
98
- try {
99
- var projectInfo = getProjectInfo ( req ) ;
100
- var project = Manager . getProject ( projectInfo . projectCwd , { cache : false } ) ;
101
-
102
- if ( project . proxy && project . proxy . length !== currentProxy . length && project . proxy [ 0 ] !== currentProxy [ 0 ] ) {
103
- currentProxy = project . proxy ;
104
- currentProxy . map ( function ( proxyItem ) {
105
- // hacky way to add middleware
106
- if ( typeof proxyItem === 'string' ) {
107
- app . stack . unshift ( {
108
- route : '' , handle : httpProxy ( proxyItem )
109
- } ) ;
110
- } else {
111
- if ( ( typeof proxyItem === 'undefined' ? 'undefined' : ( 0 , _typeof3 . default ) ( proxyItem ) ) !== 'object' || ! proxyItem . route || ! proxyItem . options ) {
112
- logWarn ( 'Not valid proxy: ' + ( 0 , _stringify2 . default ) ( proxyItem ) ) ;
113
- } else {
114
- app . stack . unshift ( {
115
- route : proxyItem . route , handle : httpProxy ( proxyItem . options )
116
- } ) ;
117
- }
118
- }
119
- } ) ;
120
- }
121
- } catch ( e ) {
122
- logError ( e ) ;
123
- }
124
-
125
- next ( ) ;
126
- } ) ;
127
-
128
101
// a simple middleware
129
102
app . use ( favicon ( sysPath . join ( __dirname , '../../static/imgs/favicon.ico' ) ) ) ;
130
103
@@ -162,16 +135,16 @@ exports.run = function (options) {
162
135
163
136
function parse ( req , res , format ) {
164
137
/* eslint-disable */
165
- var status = function ( ) {
138
+ var statusColor = function ( ) {
166
139
switch ( true ) {
167
140
case 500 <= res . statusCode :
168
- return '\x1b[31m ' ;
141
+ return 'red ' ;
169
142
case 400 <= res . statusCode :
170
- return '\x1b[33m ' ;
143
+ return 'yellow ' ;
171
144
case 300 <= res . statusCode :
172
- return '\x1b[36m ' ;
145
+ return 'cyan ' ;
173
146
case 200 <= res . statusCode :
174
- return '\x1b[32m ' ;
147
+ return 'green ' ;
175
148
}
176
149
} ( ) ;
177
150
/* eslint-enable */
@@ -182,11 +155,11 @@ exports.run = function (options) {
182
155
contentLength = '( ' + contentLength + ' )' ;
183
156
}
184
157
185
- format = format . replace ( / % d a t e / g, '\x1b[90m ' + '[' + moment ( ) . format ( dateFormat ) + ']' + '\x1b[0m' ) ;
186
- format = format . replace ( / % m e t h o d / g, '\x1b[35m ' + req . method . toUpperCase ( ) + '\x1b[0m' ) ;
158
+ format = format . replace ( / % d a t e / g, ( '[ ' + moment ( ) . format ( dateFormat ) + ']' ) . grey ) ;
159
+ format = format . replace ( / % m e t h o d / g, '' + req . method . toUpperCase ( ) . magenta + ( req . mock ? '(mock)' . cyan : '' ) ) ;
187
160
format = format . replace ( / % u r l / g, decodeURI ( req . originalUrl ) ) ;
188
- format = format . replace ( / % s t a t u s / g, '' + status + res . statusCode + '\x1b[0m' ) ;
189
- format = format . replace ( / % c o n t e n t L e n g t h / g, '\x1b[90m' + contentLength + '\x1b[31m' + '\x1b[0m' ) ;
161
+ format = format . replace ( / % s t a t u s / g, String ( res . statusCode ) [ statusColor ] ) ;
162
+ format = format . replace ( / % c o n t e n t L e n g t h / g, contentLength . grey ) ;
190
163
191
164
return {
192
165
message : format ,
@@ -197,6 +170,127 @@ exports.run = function (options) {
197
170
return next ( ) ;
198
171
} ) ;
199
172
173
+ // mock
174
+ app . use ( function ( req , res , next ) {
175
+ var projectInfo = getProjectInfo ( req ) ;
176
+ var project = Manager . getProject ( projectInfo . projectCwd , { cache : false } ) ;
177
+ var cwd = projectInfo . projectCwd ;
178
+ var shouldMock = mock || project . server && project . server . mock ;
179
+
180
+ if ( ! shouldMock ) {
181
+ next ( ) ;
182
+ }
183
+
184
+ if ( req . headers [ 'x-requested-with' ] !== 'XMLHttpRequest' ) {
185
+ if ( ! mockCache [ projectInfo . projectName ] ) {
186
+ mockCache [ projectInfo . projectName ] = true ;
187
+
188
+ // get mock file
189
+ var mockFile = '' ;
190
+ if ( typeof mock === 'string' ) {
191
+ if ( UtilFs . fileExists ( mock ) ) {
192
+ mockFile = mock ;
193
+ } else {
194
+ logError ( 'Mock file ' + mock . bold + ' not found in ' + cwd . bold ) ;
195
+ }
196
+ } else {
197
+ var localConfigFiles = getMockFiles ( [ 'mock.js' , 'mock.json' ] ) ;
198
+ if ( localConfigFiles . length > 0 ) {
199
+ mockFile = localConfigFiles [ 0 ] ;
200
+ }
201
+ }
202
+
203
+ // get mock rules
204
+ if ( mockFile ) {
205
+ var ext = sysPath . extname ( mockFile ) ;
206
+ if ( ext === '.js' ) {
207
+ var appMockRules = require ( sysPath . join ( cwd , mockFile ) ) ;
208
+ var formattedRules = [ ] ;
209
+ if ( ( typeof appMockRules === 'undefined' ? 'undefined' : ( 0 , _typeof3 . default ) ( appMockRules ) ) === 'object' ) {
210
+ log ( ( 'Start using ' + mockFile + ' for simulation.' ) . cyan ) ;
211
+ ( 0 , _keys2 . default ) ( appMockRules ) . map ( function ( itemKey ) {
212
+ if ( itemKey === 'rules' ) {
213
+ formattedRules = formattedRules . concat ( appMockRules [ itemKey ] ) ;
214
+ } else {
215
+ formattedRules . push ( {
216
+ pattern : itemKey ,
217
+ respondwith : appMockRules [ itemKey ]
218
+ } ) ;
219
+ }
220
+ } ) ;
221
+ mockRules [ projectInfo . projectName ] = formattedRules . map ( function ( r ) {
222
+ return extend ( r , { cwd : cwd } ) ;
223
+ } ) ;
224
+ } else {
225
+ logError ( 'Invalid mock rules, please check your mock config.' ) ;
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ next ( ) ;
232
+ } else {
233
+ var mockResult = void 0 ;
234
+ var mockAction = function mockAction ( rule , req , res ) {
235
+ var rw = rule . respondwith ;
236
+ var cwd = rule . cwd ; // different from current req cwd
237
+
238
+ var resObj = { } ;
239
+
240
+ // TODO handle object
241
+
242
+ // handle file
243
+ var mockPath = sysPath . join ( cwd , rw ) ;
244
+ if ( UtilFs . fileExists ( mockPath ) ) {
245
+ if ( sysPath . extname ( rw ) === '.js' || sysPath . extname ( rw ) === '.json' ) {
246
+ resObj = Mock . mock ( require ( mockPath ) ) ;
247
+ } else if ( sysPath . extname ( rw ) ) {
248
+ try {
249
+ resObj = Mock . mock ( JSON . parse ( fs . readFileSync ( mockPath , 'utf-8' ) ) ) ;
250
+ } catch ( e ) {
251
+ logError ( 'Parse error in ' + mockPath . bold + ' \n' + e ) ;
252
+ }
253
+ }
254
+ } else {
255
+ logError ( 'Not found ' + mockPath . bold ) ;
256
+ }
257
+
258
+ req . mock = true ;
259
+ res . writeHead ( 200 , { 'Content-Type' : 'application/json' } ) ;
260
+ res . end ( ( 0 , _stringify2 . default ) ( resObj ) ) ;
261
+ } ;
262
+
263
+ ( 0 , _keys2 . default ) ( mockRules ) . map ( function ( mockApp ) {
264
+ mockRules [ mockApp ] . map ( function ( rule ) {
265
+ var isReg = Object . prototype . toString . call ( rule . pattern ) . indexOf ( 'RegExp' ) > - 1 ;
266
+ var result = void 0 ;
267
+
268
+ if ( isReg ) {
269
+ result = req . url . match ( rule . pattern ) ;
270
+ } else {
271
+ result = req . url . indexOf ( rule . pattern ) === 0 ;
272
+ }
273
+
274
+ if ( result ) {
275
+ mockResult = mockAction ( rule , req , res ) ;
276
+ }
277
+ } ) ;
278
+ } ) ;
279
+
280
+ if ( ! mockResult ) {
281
+ next ( ) ;
282
+ }
283
+ }
284
+
285
+ function getMockFiles ( ) {
286
+ var names = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : [ ] ;
287
+ var searchPath = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : '' ;
288
+
289
+ console . log ( ) ;
290
+ return globby . sync ( [ 'mock.js' , 'mock.json' ] , { cwd : sysPath . join ( cwd , searchPath ) } ) ;
291
+ }
292
+ } ) ;
293
+
200
294
app . use ( function ( req , res , next ) {
201
295
try {
202
296
var projectInfo = getProjectInfo ( req ) ;
0 commit comments