import Server from '@modern-js/server' ; import { ServerRoute as ModernRoute } from '@modern-js/types' ; import portfinder from 'portfinder' ; import { NormalizedConfig } from '@modern-js/core' ; import { compatRequire } from '@modern-js/utils' ; import { makeRender } from '../libs/make' ; import { SsgRoute } from '../types' ; import { compile as createRender } from './prerender' ; import { CLOSE_SIGN } from './consts' ; type Then < T > = T extends PromiseLike < infer U > ? U : T ; type ModernServer = Then < ReturnType < typeof Server > > ; const safetyRequire = ( filename , base ) => { try { return compatRequire ( require . resolve ( `${ filename }/server` , { paths : [ base ] } ) ) ; } catch ( e ) { return compatRequire ( require . resolve ( filename , { paths : [ base ] } ) ) ; } } ; process . on ( 'message' , async ( chunk ) => { if ( chunk === CLOSE_SIGN ) { process . exit ( ) ; } const context = JSON . parse ( chunk as any ) ; const { routes , options , appDirectory , plugins , } = context ; const instances = plugins . map ( plugin => safetyRequire ( plugin , appDirectory ) ) ; let modernServer = null ; try { const { server } = options ; const defaultPort = Number ( process . env . PORT ) || server . port ; portfinder . basePort = defaultPort ! ; const port = await portfinder . getPortPromise ( ) ; modernServer = await Server ( { pwd : appDirectory , config : options , routes , staticGenerate : true , plugins : instances , } ) ; modernServer . listen ( port , async ( err ) => { if ( err ) { throw err ; } if ( ! modernServer ) { return ; } const render = createRender ( modernServer . getRequestHandler ( ) ) ; const renderPromiseAry = makeRender ( routes . filter ( route => ! route . isApi ) as SsgRoute [ ] , render , port ) ; const htmlAry = await Promise . all ( renderPromiseAry ) ; htmlAry . forEach ( ( html ) => { process . send ! ( html ) ; process . send ! ( null ) ; } ) ; modernServer . close ( ) ; } ) ; } catch ( e ) { modernServer ?. close ( ) ; throw e ; } } ) ;