@@ -8,6 +8,7 @@ var connect = require('connect'),
8
8
livereload = require ( 'livereload' ) ,
9
9
connectLivereload = require ( 'connect-livereload' ) ,
10
10
child_process = require ( 'child_process' ) ,
11
+ inquirer = require ( 'inquirer' ) ,
11
12
webpackDevMiddleware = require ( "webpack-dev-middleware" ) ;
12
13
13
14
var Manager = require ( '../modules/manager.js' ) ;
@@ -37,141 +38,175 @@ exports.run = function (options) {
37
38
enableLivereload = options . l || options . livereload ,
38
39
port = options . p || options . port || 80 ;
39
40
40
- var middlewareCache = { } ;
41
+ var isGoingToStartServer = true ;
41
42
42
- if ( middlewares ) {
43
- middlewares . split ( '|' ) . forEach ( function ( proName ) {
44
- var pro = Manager . getProject ( sysPath . join ( cwd , proName ) ) ;
45
- if ( pro . check ( ) && Array . isArray ( pro . middlewares ) ) {
46
- pro . middlewares . forEach ( function ( mw ) {
47
- return app . use ( mw ) ;
48
- } ) ;
49
- }
50
- } ) ;
43
+ // 检测预装插件
44
+ if ( proxy ) {
45
+ try {
46
+ require . resolve ( "@qnpm/jerryproxy-ykit" ) ;
47
+ } catch ( e ) {
48
+ var questions = [ {
49
+ type : 'confirm' ,
50
+ name : 'isInstallingProxy' ,
51
+ message : 'Prxoy plugin not installed yet, wounld you like to install it now?'
52
+ } ] ;
53
+
54
+ inquirer . prompt ( questions ) . then ( function ( answers ) {
55
+ if ( answers . isInstallingProxy ) {
56
+ var installCmd = 'npm i @qnpm/jerryproxy-ykit --registry http://registry.npm.corp.qunar.com/' ;
57
+ try {
58
+ log ( 'intalling @qnpm/jerryproxy-ykit ...' ) ;
59
+ child_process . execSync ( installCmd , { cwd : sysPath . resolve ( __dirname , '../../' ) } ) ;
60
+ } catch ( e ) {
61
+ error ( e ) ;
62
+ }
63
+ log ( '@qnpm/jerryproxy-ykit successfully installed' ) ;
64
+ }
65
+ } ) ;
66
+
67
+ isGoingToStartServer = false ;
68
+ }
51
69
}
52
70
53
- // logger
54
- app . use ( function ( req , res , next ) {
55
- var end = res . end ;
56
- req . _startTime = new Date ( ) ;
57
-
58
- res . end = function ( chunk , encoding ) {
59
- res . end = end ;
60
- res . end ( chunk , encoding ) ;
61
- var format = '%date %status %method %url (%route%contentLength%time)' ;
62
- var message = parse ( req , res , format ) ;
63
- return process . nextTick ( function ( ) {
64
- return info ( message ) ;
65
- } ) ;
66
- } ;
67
-
68
- function parse ( req , res , format ) {
69
- var dateFormat = 'YY.MM.DD HH:mm:ss' ;
70
- var status = function ( ) {
71
- switch ( true ) {
72
- case 500 <= res . statusCode :
73
- return '\x1b[31m' ;
74
- case 400 <= res . statusCode :
75
- return '\x1b[33m' ;
76
- case 300 <= res . statusCode :
77
- return '\x1b[36m' ;
78
- case 200 <= res . statusCode :
79
- return '\x1b[32m' ;
80
- }
81
- } ( ) ;
71
+ if ( isGoingToStartServer ) {
72
+ ( function ( ) {
73
+ var middlewareCache = { } ;
82
74
83
- var contentLength = res . _contentLength || '' ;
84
- if ( contentLength ) {
85
- contentLength = contentLength > 1024 ? ( contentLength / 1024 ) . toFixed ( 2 ) + 'kB ' : contentLength + 'bytes ' ;
75
+ if ( middlewares ) {
76
+ middlewares . split ( '|' ) . forEach ( function ( proName ) {
77
+ var pro = Manager . getProject ( sysPath . join ( cwd , proName ) ) ;
78
+ if ( pro . check ( ) && Array . isArray ( pro . middlewares ) ) {
79
+ pro . middlewares . forEach ( function ( mw ) {
80
+ return app . use ( mw ) ;
81
+ } ) ;
82
+ }
83
+ } ) ;
86
84
}
87
85
88
- format = format . replace ( / % d a t e / g, "\x1b[90m" + '[' + moment ( ) . format ( dateFormat ) + ']' + "\x1b[0m" ) ;
89
- format = format . replace ( / % m e t h o d / g, "\x1b[35m" + req . method . toUpperCase ( ) + "\x1b[0m" ) ;
90
- format = format . replace ( / % u r l / g, "\x1b[90m" + decodeURI ( req . originalUrl ) + "\x1b[0m" ) ;
91
- format = format . replace ( / % s t a t u s / g, "" + status + res . statusCode + "\x1b[0m" ) ;
92
- format = format . replace ( / % r o u t e / g, "\x1b[90m" + ( req . route ? req . route . path + ' ' : '\x1b[31m' ) + "\x1b[0m" ) ;
93
- format = format . replace ( / % c o n t e n t L e n g t h / g, "\x1b[90m" + contentLength + '\x1b[31m' + "\x1b[0m" ) ;
94
- format = format . replace ( / % ( d a t e | t i m e ) / g, "\x1b[90m" + ( new Date ( ) - req . _startTime ) + "ms\x1b[0m" ) ;
95
- return format ;
96
- } ;
97
-
98
- return next ( ) ;
99
- } ) ;
100
-
101
- app . use ( function ( req , res , next ) {
102
- var url = req . url ,
103
- keys = url . split ( '/' ) ;
104
-
105
- if ( keys [ 2 ] == 'prd' ) {
106
- var projectName = keys [ 1 ] ,
107
- projectCwd = sysPath . join ( cwd , projectName ) ,
108
- middleware = middlewareCache [ projectName ] ;
109
-
110
- if ( ! middleware ) {
111
- var project = Manager . getProject ( projectCwd ) ;
112
- if ( project . check ( ) ) {
113
- var compiler = project . getServerCompiler ( ) ;
114
- middleware = middlewareCache [ projectName ] = webpackDevMiddleware ( compiler , { quiet : true } ) ;
115
-
116
- // 输出server运行中 error/warning 信息
117
- compiler . watch ( { } , function ( err , stats ) {
118
- var statsInfo = stats . toJson ( { errorDetails : false } ) ,
119
- logMethods = {
120
- errors : error ,
121
- warnings : warn
122
- } ;
123
-
124
- Object . keys ( logMethods ) . map ( function ( typeId ) {
125
- statsInfo [ typeId ] . map ( function ( logInfo ) {
126
- logMethods [ typeId ] ( logInfo ) ;
127
- } ) ;
128
- } ) ;
86
+ // logger
87
+ app . use ( function ( req , res , next ) {
88
+ var end = res . end ;
89
+ req . _startTime = new Date ( ) ;
90
+
91
+ res . end = function ( chunk , encoding ) {
92
+ res . end = end ;
93
+ res . end ( chunk , encoding ) ;
94
+ var format = '%date %status %method %url (%route%contentLength%time)' ;
95
+ var message = parse ( req , res , format ) ;
96
+ return process . nextTick ( function ( ) {
97
+ return info ( message ) ;
129
98
} ) ;
99
+ } ;
100
+
101
+ function parse ( req , res , format ) {
102
+ var dateFormat = 'YY.MM.DD HH:mm:ss' ;
103
+ var status = function ( ) {
104
+ switch ( true ) {
105
+ case 500 <= res . statusCode :
106
+ return '\x1b[31m' ;
107
+ case 400 <= res . statusCode :
108
+ return '\x1b[33m' ;
109
+ case 300 <= res . statusCode :
110
+ return '\x1b[36m' ;
111
+ case 200 <= res . statusCode :
112
+ return '\x1b[32m' ;
113
+ }
114
+ } ( ) ;
115
+
116
+ var contentLength = res . _contentLength || '' ;
117
+ if ( contentLength ) {
118
+ contentLength = contentLength > 1024 ? ( contentLength / 1024 ) . toFixed ( 2 ) + 'kB ' : contentLength + 'bytes ' ;
119
+ }
120
+
121
+ format = format . replace ( / % d a t e / g, "\x1b[90m" + '[' + moment ( ) . format ( dateFormat ) + ']' + "\x1b[0m" ) ;
122
+ format = format . replace ( / % m e t h o d / g, "\x1b[35m" + req . method . toUpperCase ( ) + "\x1b[0m" ) ;
123
+ format = format . replace ( / % u r l / g, "\x1b[90m" + decodeURI ( req . originalUrl ) + "\x1b[0m" ) ;
124
+ format = format . replace ( / % s t a t u s / g, "" + status + res . statusCode + "\x1b[0m" ) ;
125
+ format = format . replace ( / % r o u t e / g, "\x1b[90m" + ( req . route ? req . route . path + ' ' : '\x1b[31m' ) + "\x1b[0m" ) ;
126
+ format = format . replace ( / % c o n t e n t L e n g t h / g, "\x1b[90m" + contentLength + '\x1b[31m' + "\x1b[0m" ) ;
127
+ format = format . replace ( / % ( d a t e | t i m e ) / g, "\x1b[90m" + ( new Date ( ) - req . _startTime ) + "ms\x1b[0m" ) ;
128
+ return format ;
129
+ } ;
130
+
131
+ return next ( ) ;
132
+ } ) ;
133
+
134
+ app . use ( function ( req , res , next ) {
135
+ var url = req . url ,
136
+ keys = url . split ( '/' ) ;
137
+
138
+ if ( keys [ 2 ] == 'prd' ) {
139
+ var projectName = keys [ 1 ] ,
140
+ projectCwd = sysPath . join ( cwd , projectName ) ,
141
+ middleware = middlewareCache [ projectName ] ;
142
+
143
+ if ( ! middleware ) {
144
+ var project = Manager . getProject ( projectCwd ) ;
145
+ if ( project . check ( ) ) {
146
+ var compiler = project . getServerCompiler ( ) ;
147
+ middleware = middlewareCache [ projectName ] = webpackDevMiddleware ( compiler , { quiet : true } ) ;
148
+
149
+ // 输出server运行中 error/warning 信息
150
+ compiler . watch ( { } , function ( err , stats ) {
151
+ var statsInfo = stats . toJson ( { errorDetails : false } ) ,
152
+ logMethods = {
153
+ errors : error ,
154
+ warnings : warn
155
+ } ;
156
+
157
+ Object . keys ( logMethods ) . map ( function ( typeId ) {
158
+ statsInfo [ typeId ] . map ( function ( logInfo ) {
159
+ logMethods [ typeId ] ( logInfo ) ;
160
+ } ) ;
161
+ } ) ;
162
+ } ) ;
163
+ } else {
164
+ next ( ) ;
165
+ return ;
166
+ }
167
+ }
168
+ req . url = '/' + keys . slice ( 3 ) . join ( '/' ) . replace ( / ( \@ [ \d \w ] + ) ? \. ( j s | c s s ) / , '.$2' ) ;
169
+ middleware ( req , res , next ) ;
130
170
} else {
131
171
next ( ) ;
132
- return ;
133
172
}
134
- }
135
- req . url = '/' + keys . slice ( 3 ) . join ( '/' ) . replace ( / ( \@ [ \d \w ] + ) ? \. ( j s | c s s ) / , '.$2' ) ;
136
- middleware ( req , res , next ) ;
137
- } else {
138
- next ( ) ;
139
- }
140
- } ) ;
173
+ } ) ;
141
174
142
- if ( enableLivereload ) {
143
- livereload . createServer ( ) . watch ( cwd ) ;
144
- app . use ( connectLivereload ( { port : 35729 } ) ) ;
145
- }
175
+ if ( enableLivereload ) {
176
+ livereload . createServer ( ) . watch ( cwd ) ;
177
+ app . use ( connectLivereload ( { port : 35729 } ) ) ;
178
+ }
146
179
147
- app . use ( serveStatic ( cwd , {
148
- redirect : false ,
149
- index : false
150
- } ) ) ;
180
+ app . use ( serveStatic ( cwd , {
181
+ redirect : false ,
182
+ index : false
183
+ } ) ) ;
151
184
152
- app . use ( serveIndex ( cwd ) ) ;
185
+ app . use ( serveIndex ( cwd ) ) ;
153
186
154
- var httpServer = http . createServer ( app ) ;
155
- httpServer . on ( 'error' , function ( e ) {
156
- if ( e . code === 'EACCES' ) {
157
- warn ( '权限不足, 请使用sudo执行' ) ;
158
- } else if ( e . code === 'EADDRINUSE' ) {
159
- warn ( '端口 ' + port + ' 已经被占用, 请关闭占用该端口的程序或者使用其它端口.' ) ;
160
- }
161
- process . exit ( 1 ) ;
162
- } ) ;
163
- httpServer . listen ( port , function ( ) {
164
- warn ( 'Listening on port ' + port ) ;
165
- } ) ;
187
+ var httpServer = http . createServer ( app ) ;
188
+ httpServer . on ( 'error' , function ( e ) {
189
+ if ( e . code === 'EACCES' ) {
190
+ warn ( '权限不足, 请使用sudo执行' ) ;
191
+ } else if ( e . code === 'EADDRINUSE' ) {
192
+ warn ( '端口 ' + port + ' 已经被占用, 请关闭占用该端口的程序或者使用其它端口.' ) ;
193
+ }
194
+ process . exit ( 1 ) ;
195
+ } ) ;
196
+ httpServer . listen ( port , function ( ) {
197
+ warn ( 'Listening on port ' + port ) ;
198
+ } ) ;
166
199
167
- // 代理
168
- if ( proxy ) {
169
- var proxyPath = sysPath . join ( require . resolve ( '@qnpm/jerryproxy-ykit' ) , '../bin/jerry.js' ) ;
170
- child_process . fork ( proxyPath ) ;
171
- }
200
+ // 代理
201
+ if ( proxy ) {
202
+ var proxyPath = sysPath . join ( require . resolve ( '@qnpm/jerryproxy-ykit' ) , '../bin/jerry.js' ) ;
203
+ child_process . fork ( proxyPath ) ;
204
+ }
172
205
173
- // 权限降级
174
- if ( process . env [ 'SUDO_UID' ] ) {
175
- process . setuid ( parseInt ( process . env [ 'SUDO_UID' ] ) ) ;
206
+ // 权限降级
207
+ if ( process . env [ 'SUDO_UID' ] ) {
208
+ process . setuid ( parseInt ( process . env [ 'SUDO_UID' ] ) ) ;
209
+ }
210
+ } ) ( ) ;
176
211
}
177
212
} ;
0 commit comments