1+ const compression = require ( 'compression' ) ;
2+ const Express = require ( 'express' ) ;
3+ const helmet = require ( 'helmet' ) ;
4+ const http2 = require ( 'spdy' ) ;
5+ const fs = require ( 'fs' ) ;
6+ 7+ class Server {
8+ static async start ( ) {
9+ try {
10+ const address = process . env . ADDRESS || 'localhost' ;
11+ const port = parseInt ( process . env . PORT , 10 ) || 8080 ;
12+ 13+ const app = new Express ( ) ;
14+ 15+ const manifest = JSON . parse ( fs . readFileSync ( process . env . BUILD_DIR + '/asset-manifest.json' , 'utf-8' ) ) ;
16+ 17+ if ( ! manifest ) {
18+ throw new Error ( "You've to build the project, please, run `npm run build` or `yarn build`." ) ;
19+ }
20+ 21+ app . use ( helmet ( ) ) ;
22+ app . use ( compression ( { threshold : 0 } ) ) ;
23+ app . use ( '/static' , Express . static ( process . env . BUILD_DIR + '/static' ) ) ;
24+ 25+ app . get ( '*' , ( req , res , next ) => {
26+ res . header ( 'X-Powered-By' , null ) ;
27+ next ( ) ;
28+ } )
29+ 30+ app . get ( '/' , ( req , res ) => {
31+ res . header ( 'Content-Type' , 'text/html' ) ;
32+ res . send ( fs . readFileSync ( process . env . BUILD_DIR + '/index.html' , 'utf-8' ) ) ;
33+ res . end ( ) ;
34+ } ) ;
35+ 36+ let options = null ;
37+ 38+ if ( process . env . ENABLE_HTTPS === 'true' ) {
39+ options = {
40+ key : fs . readFileSync ( process . env . CERT_DIR + '/server.key' ) ,
41+ cert : fs . readFileSync ( process . env . CERT_DIR + '/server.crt' ) ,
42+ ca : fs . readFileSync ( process . env . CERT_DIR + '/server.csr' )
43+ } ;
44+ } else {
45+ options = {
46+ spdy : {
47+ plain : true ,
48+ ssl : false
49+ }
50+ } ;
51+ }
52+ 53+ const http2Server = http2 . createServer ( options , ( req , res ) => {
54+ if ( res . push ) {
55+ console . info ( '> Pushing ' , req . url ) ;
56+ 57+ [
58+ {
59+ url : '/' ,
60+ contentType : 'text/html' ,
61+ filePath : `${ process . env . BUILD_DIR } /index.html`
62+ } ,
63+ {
64+ url : '/service-worker.js' ,
65+ contentType : 'application/javascript' ,
66+ filePath : `${ process . env . BUILD_DIR } /service-worker.js`
67+ } ,
68+ {
69+ url : `/${ manifest [ 'main.js' ] } ` ,
70+ contentType : 'application/javascript' ,
71+ filePath : `${ process . env . BUILD_DIR } /${ manifest [ 'main.js' ] } `
72+ } ,
73+ {
74+ url : `/${ manifest [ 'main.css' ] } ` ,
75+ contentType : 'text/css' ,
76+ filePath : `${ process . env . BUILD_DIR } /${ manifest [ 'main.css' ] } `
77+ }
78+ ] . map ( ( { url, contentType, filePath } ) => {
79+ const stream = res . push ( url , {
80+ status : 200 ,
81+ method : "GET" ,
82+ request : {
83+ accept : "*/*"
84+ } ,
85+ response : {
86+ "content-type" : contentType
87+ }
88+ } ) ;
89+ 90+ stream . on ( "error" , error => console . info ( error ) ) ;
91+ stream . end ( fs . readFileSync ( filePath , 'utf-8' ) ) ;
92+ } ) ;
93+ }
94+ 95+ return app ( req , res ) ;
96+ } ) ;
97+ 98+ 99+ http2Server . listen ( port , address , error => {
100+ if ( error ) {
101+ console . info ( `> Ups, something went wrong: ${ error } ` ) ;
102+ }
103+ 104+ console . info ( `> Ready on http://localhost:${ port } ` ) ;
105+ } ) ;
106+ } catch ( error ) {
107+ console . info ( `> Ups, something went wrong: ${ error } ` ) ;
108+ }
109+ }
110+ }
111+ 112+ module . exports = Server ;
0 commit comments