1- var RSVP = require ( 'rsvp' ) ;
2- var exec = RSVP . denodeify ( require ( 'child_process' ) . exec ) ;
1+ 'use strict' ;
2+ const RSVP = require ( 'rsvp' ) ;
3+ const getPort = RSVP . denodeify ( require ( 'portfinder' ) . getPort ) ;
4+ const ServerTask = require ( '../tasks/fastboot-server' ) ;
5+ const SilentError = require ( 'silent-error' ) ;
6+
7+ const blockForever = ( ) => ( new RSVP . Promise ( ( ) => { } ) ) ;
8+ const noop = function ( ) { } ;
39
410module . exports = {
511 name : 'fastboot' ,
6- description : 'Runs a server to render your app using FastBoot .' ,
12+ description : 'Builds and serves your FastBoot app, rebuilding on file changes .' ,
713
814 availableOptions : [
915 { name : 'build' , type : Boolean , default : true } ,
10- { name : 'watch' , type : Boolean , default : false , aliases : [ 'w' ] } ,
16+ { name : 'watch' , type : Boolean , default : true , aliases : [ 'w' ] } ,
1117 { name : 'environment' , type : String , default : 'development' , aliases : [ 'e' , { 'dev' : 'development' } , { 'prod' : 'production' } ] } ,
1218 { name : 'serve-assets' , type : Boolean , default : false } ,
1319 { name : 'host' , type : String , default : '::' } ,
@@ -16,91 +22,48 @@ module.exports = {
1622 { name : 'assets-path' , type : String , default : 'dist' }
1723 ] ,
1824
19- startServer : function ( options ) {
20- var ui = this . ui ;
21- var self = this ;
22-
23- if ( this . _fastBootListener ) {
24- this . _fastBootListener . close ( ) ;
25- }
26-
27- ui . writeLine ( 'Installing FastBoot npm dependencies' ) ;
28-
29- return exec ( 'npm install' , { cwd : options . outputPath } )
30- . then ( function ( ) {
31- var fastbootMiddleware = require ( 'fastboot-express-middleware' ) ;
32- var RSVP = require ( 'rsvp' ) ;
33- var express = require ( 'express' ) ;
34-
35- var middleware = fastbootMiddleware ( options . outputPath ) ;
36-
37- var app = express ( ) ;
25+ blockForever,
26+ getPort,
27+ ServerTask,
3828
39- if ( options . serveAssets ) {
40- app . get ( '/' , middleware ) ;
41- app . use ( express . static ( options . assetsPath ) ) ;
42- }
43-
44- app . get ( '/*' , middleware ) ;
45-
46- app . use ( function ( req , res ) {
47- res . sendStatus ( 404 ) ;
48- } ) ;
29+ run ( options ) {
30+ const runBuild = ( ) => this . runBuild ( options ) ;
31+ const runServer = ( ) => this . runServer ( options ) ;
32+ const blockForever = this . blockForever ;
4933
50- var listener = app . listen ( options . port , options . host , function ( ) {
51- var host = listener . address ( ) . address ;
52- var port = listener . address ( ) . port ;
53- var family = listener . address ( ) . family ;
54-
55- if ( family === 'IPv6' ) { host = '[' + host + ']' ; }
34+ return this . checkPort ( options )
35+ . then ( runServer ) // starts on postBuild SIGHUP
36+ . then ( options . build ? runBuild : noop )
37+ . then ( blockForever ) ;
38+ } ,
5639
57- ui . writeLine ( 'Ember FastBoot running at http://' + host + ":" + port ) ;
58- self . _fastBootListener = listener ;
59- } ) ;
60- } ) ;
40+ runServer ( options ) {
41+ const ServerTask = this . ServerTask ;
42+ const serverTask = new ServerTask ( {
43+ ui : this . ui ,
44+ } ) ;
45+ return serverTask . run ( options ) ;
6146 } ,
6247
63- triggerBuild : function ( options ) {
64- var BuildTask = this . buildTaskFor ( options ) ;
65- var buildTask = new BuildTask ( {
48+ runBuild ( options ) {
49+ const BuildTask = options . watch ? this . tasks . BuildWatch : this . tasks . Build ;
50+ const buildTask = new BuildTask ( {
6651 ui : this . ui ,
6752 analytics : this . analytics ,
68- project : this . project
53+ project : this . project ,
6954 } ) ;
70-
71- return buildTask . run ( options ) ;
55+ buildTask . run ( options ) ; // no return, BuildWatch.run blocks forever
7256 } ,
7357
74- buildTaskFor : function ( options ) {
75- if ( options . watch ) {
76- return this . tasks . BuildWatch ;
77- } else {
78- return this . tasks . Build ;
79- }
58+ checkPort ( options ) {
59+ return this . getPort ( { port : options . port , host : options . host } )
60+ . then ( ( foundPort ) => {
61+ if ( options . port !== foundPort && options . port !== 0 ) {
62+ const message = `Port ${ options . port } is already in use.` ;
63+ return Promise . reject ( new SilentError ( message ) ) ;
64+ }
65+ options . port = foundPort ;
66+ } ) ;
8067 } ,
8168
82- run : function ( options ) {
83- var startServer = function ( ) {
84- this . startServer ( options ) ;
85- } . bind ( this ) ;
86-
87- var blockForever = function ( ) {
88- return new RSVP . Promise ( function ( ) { } ) ;
89- } ;
90-
91- process . on ( 'SIGUSR1' , startServer ) ;
92-
93- if ( options . build ) {
94- return this . triggerBuild ( options )
95- . then ( startServer )
96- . then ( blockForever ) ;
97- }
98-
99- if ( options . watch ) {
100- this . ui . writeWarnLine ( 'The `watch` option is not supported when `build` is disabled.' ) ;
101- }
102-
103- return startServer ( )
104- . then ( blockForever ) ;
105- }
10669} ;
0 commit comments