import type * as d from '../../declarations' ; import { generateBuildResults } from './build-results' ; import { generateBuildStats , writeBuildStats } from './build-stats' ; import { isFunction , isRemoteUrl } from '@utils' ; import { IS_NODE_ENV } from '../sys/environment' ; import { relative } from 'path' ; param buildCtx returns export const buildFinish = async ( buildCtx ) : Promise < d . CompilerBuildResults > => { const results = await buildDone ( buildCtx . config , buildCtx . compilerCtx , buildCtx , false ) ; const buildLog = { buildId : buildCtx . buildId , messages : buildCtx . buildMessages . slice ( ) , progress : 1 , } ; buildCtx . compilerCtx . events . emit ( 'buildLog' , buildLog ) ; return results ; } ; param buildCtx returns export const buildAbort = ( buildCtx ) : Promise < d . CompilerBuildResults > => { return buildDone ( buildCtx . config , buildCtx . compilerCtx , buildCtx , true ) ; } ; param config param compilerCtx param buildCtx param aborted returns const buildDone = async ( config , compilerCtx , buildCtx , aborted ) : Promise < d . CompilerBuildResults > => { if ( buildCtx . hasFinished && buildCtx . buildResults ) { return buildCtx . buildResults ; } buildCtx . buildResults = generateBuildResults ( config , compilerCtx , buildCtx ) ; buildCtx . buildStats = generateBuildStats ( config , buildCtx ) ; await writeBuildStats ( config , buildCtx . buildStats ) ; buildCtx . debug ( `${ aborted ? 'aborted' : 'finished' } build, ${ buildCtx . buildResults . duration }ms` ) ; if ( ! buildCtx . hasFinished ) { if ( ! buildCtx . hasPrintedResults ) { cleanDiagnosticsRelativePath ( config , buildCtx . buildResults . diagnostics ) ; config . logger . printDiagnostics ( buildCtx . buildResults . diagnostics ) ; } const hasChanges = buildCtx . hasScriptChanges || buildCtx . hasStyleChanges ; if ( buildCtx . isRebuild && hasChanges && buildCtx . buildResults . hmr && ! aborted ) { logHmr ( config . logger , buildCtx ) ; } const buildText = buildCtx . isRebuild ? 'rebuild' : 'build' ; const watchText = config . watch ? ', watching for changes...' : '' ; let buildStatus = 'finished' ; let statusColor = 'green' ; if ( buildCtx . hasError ) { buildStatus = 'failed' ; statusColor = 'red' ; } else { compilerCtx . changedFiles . clear ( ) ; compilerCtx . hasSuccessfulBuild = true ; buildCtx . buildResults . hasSuccessfulBuild = true ; } if ( ! buildCtx . hasPrintedResults ) { buildCtx . timeSpan . finish ( `${ buildText } ${ buildStatus }${ watchText }` , statusColor , true , true ) ; buildCtx . hasPrintedResults = true ; } compilerCtx . events . emit ( 'buildFinish' , buildCtx . buildResults ) ; if ( isFunction ( config . logger . writeLogs ) ) { config . logger . writeLogs ( buildCtx . isRebuild ) ; } } buildCtx . hasFinished = true ; if ( ! config . watch ) { compilerCtx . reset ( ) ; if ( IS_NODE_ENV && global . gc ) { buildCtx . debug ( `triggering forced gc` ) ; global . gc ( ) ; buildCtx . debug ( `forced gc finished` ) ; } } return buildCtx . buildResults ; } ; const logHmr = ( logger , buildCtx ) => { const hmr = buildCtx . buildResults . hmr ; if ( hmr . componentsUpdated ) { cleanupUpdateMsg ( logger , `updated component` , hmr . componentsUpdated ) ; } if ( hmr . inlineStylesUpdated ) { const inlineStyles = hmr . inlineStylesUpdated . map ( ( s ) => s . styleTag ) . reduce ( ( arr , v ) => { if ( ! arr . includes ( v ) ) { arr . push ( v ) ; } return arr ; } , [ ] as string [ ] ) ; cleanupUpdateMsg ( logger , `updated style` , inlineStyles ) ; } if ( hmr . externalStylesUpdated ) { cleanupUpdateMsg ( logger , `updated stylesheet` , hmr . externalStylesUpdated ) ; } if ( hmr . imagesUpdated ) { cleanupUpdateMsg ( logger , `updated image` , hmr . imagesUpdated ) ; } } ; const cleanupUpdateMsg = ( logger , msg , fileNames ) => { if ( fileNames . length > 0 ) { let fileMsg = '' ; if ( fileNames . length > 7 ) { const remaining = fileNames . length - 6 ; fileNames = fileNames . slice ( 0 , 6 ) ; fileMsg = fileNames . join ( ', ' ) + `, +${ remaining } others` ; } else { fileMsg = fileNames . join ( ', ' ) ; } if ( fileNames . length > 1 ) { msg += 's' ; } logger . info ( `${ msg }: ${ logger . cyan ( fileMsg ) }` ) ; } } ; param config param diagnostics const cleanDiagnosticsRelativePath = ( config , diagnostics ) : void => { diagnostics . forEach ( ( diagnostic ) => { if ( ! diagnostic . relFilePath && ! isRemoteUrl ( diagnostic . absFilePath ) && diagnostic . absFilePath && config . rootDir ) { diagnostic . relFilePath = relative ( config . rootDir , diagnostic . absFilePath ) ; } } ) ; } ;