You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Kill process with SIGKILL if it didn't stop during timeout
Example:
import{ChildProcess,fork}from'child_process';import{Compilation,Compiler,WebpackPluginInstance}from'webpack';constkillProcess=async({pid, signal ='SIGTERM', timeout})=>{process.kill(pid,signal);letcount=0;do{try{process.kill(pid,0);}catch(e){return;}if((count+=100)>timeout){break;}awaitnewPromise(cb=>setTimeout(cb,100));}while(true);try{process.kill(pid,'SIGKILL');}catch(e){return;}count=0;do{try{process.kill(pid,0);}catch(e){return;}if((count+=100)>timeout){thrownewError('Timeout process kill');}awaitnewPromise(cb=>setTimeout(cb,100));}while(true);};exporttypeRunScriptWebpackPluginOptions={autoRestart?: boolean;args: string[];cwd?: string;keyboard: boolean;name?: string;nodeArgs: string[];restartable?: boolean;signal: boolean|string;killTimeoutMs?: number;};functiongetSignal(signal: string|boolean){// allow users to disable sending a signal by setting to `false`...if(signal===false)return;if(signal===true)return'SIGUSR2';returnsignal;}exportclassRunScriptWebpackPluginimplementsWebpackPluginInstance{privatereadonlyoptions: RunScriptWebpackPluginOptions;privateworker?: ChildProcess;private_entrypoint?: string;constructor(options: Partial<RunScriptWebpackPluginOptions>={}){this.options={autoRestart: true,signal: false,killTimeoutMs: 5000,// Only listen on keyboard in development, so the server doesn't hang foreverkeyboard: process.env.NODE_ENV==='development',
...options,args: [...(options.args||[])],nodeArgs: options.nodeArgs||process.execArgv,};if(this.options.restartable){this._enableRestarting();}}private_enableRestarting(): void{if(this.options.keyboard){process.stdin.setEncoding('utf8');process.stdin.on('data',(data: string)=>{if(data.trim()==='rs'){this._restartServer();}});}}privateasync_restartServer(): Promise<void>{console.log('Restarting app...');if(this.worker?.pid){constsignal=getSignal(this.options.signal);awaitkillProcess({pid: this.worker.pid,
signal,timeout: this.options.killTimeoutMs,});}this._startServer((worker)=>{this.worker=worker;});}privateafterEmit=(compilation: Compilation,cb: (err?: any)=>void): void=>{if(this.worker&&this.worker.connected&&this.worker?.pid){if(this.options.autoRestart){this._restartServer().then(()=>cb()).catch(err=>cb(err));return;}constsignal=getSignal(this.options.signal);if(signal){killProcess({pid: this.worker.pid,
signal,timeout: this.options.killTimeoutMs,}).then(()=>cb()).catch(err=>cb(err));}cb();return;}this.startServer(compilation,cb);};apply=(compiler: Compiler): void=>{compiler.hooks.afterEmit.tapAsync({name: 'RunScriptPlugin'},this.afterEmit,);};privatestartServer=(compilation: Compilation,cb: ()=>void): void=>{const{assets, compiler}=compilation;const{options}=this;letname;constnames=Object.keys(assets);if(options.name){name=options.name;if(!assets[name]){console.error(`Entry ${name} not found. Try one of: ${names.join(' ')}`,);}}else{name=names[0];if(names.length>1){console.log(`More than one entry built, selected ${name}. All names: ${names.join(' ',)}`,);}}if(!compiler.options.output||!compiler.options.output.path){thrownewError('output.path should be defined in webpack config!');}this._entrypoint=`${compiler.options.output.path}/${name}`;this._startServer((worker)=>{this.worker=worker;cb();});};private_startServer(cb: (arg0: ChildProcess)=>void): void{const{args, nodeArgs, cwd}=this.options;if(!this._entrypoint)thrownewError('run-script-webpack-plugin requires an entrypoint.');constchild=fork(this._entrypoint,args,{execArgv: nodeArgs,stdio: 'inherit',
cwd,});setTimeout(()=>cb(child),0);}}
The text was updated successfully, but these errors were encountered:
These features would be really nice to have:
Example:
The text was updated successfully, but these errors were encountered: