import childProcess from 'child_process' ; import path from 'path' ; import { logger , SERVER_BUNDLE_DIRECTORY } from '@modern-js/utils' ; import { NormalizedConfig , useAppContext } from '@modern-js/core' ; import { ServerRoute as ModernRoute } from '@modern-js/types' ; import { SsgRoute } from '../types' ; import { CLOSE_SIGN } from './consts' ; export const createServer = ( ssgRoutes , apiRoutes , options , appDirectory ) : Promise < string [ ] > => new Promise ( ( resolve , reject ) => { const backup = ssgRoutes . map ( ssgRoute => ( { ... ssgRoute , isSSR : true , bundle : `${ SERVER_BUNDLE_DIRECTORY }/${ ssgRoute . entryName as string }.js` , } ) ) ; const total = backup . concat ( apiRoutes ) ; const cp = childProcess . fork ( path . join ( __dirname , 'process' ) , { cwd : appDirectory , silent : true , } ) ; const appContext = useAppContext ( ) ; const serverPlugins = appContext . plugins . filter ( ( p ) => p . server ) . map ( ( p ) => p . server ) ; const plugins = serverPlugins . map ( ( p ) => p . name ) ; cp . send ( JSON . stringify ( { options , routes : total , appDirectory , plugins , } ) ) ; const htmlChunks = [ ] ; const htmlAry = [ ] ; cp . on ( 'message' , ( chunk ) => { if ( chunk !== null ) { htmlChunks . push ( chunk ) ; } else { const html = htmlChunks . join ( '' ) ; htmlAry . push ( html ) ; htmlChunks . length = 0 ; } if ( htmlAry . length === backup . length ) { cp . send ( CLOSE_SIGN ) ; resolve ( htmlAry ) ; } } ) ; cp . stderr ! . on ( 'data' , chunk => { const str = chunk . toString ( ) ; if ( str . includes ( 'Error' ) ) { logger . error ( str ) ; reject ( new Error ( 'ssg render failed' ) ) ; cp . kill ( 'SIGKILL' ) ; } else { logger . info ( str . replace ( /[^\S\n]+/g , ' ' ) ) ; } } ) ; cp . stdout ! . on ( 'data' , chunk => { const str = chunk . toString ( ) ; if ( str . includes ( 'Error' ) ) { logger . error ( str ) ; reject ( new Error ( 'ssg render failed' ) ) ; cp . kill ( 'SIGKILL' ) ; } else { logger . info ( str . replace ( /[^\S\n]+/g , ' ' ) ) ; } } ) ; } ) ;