@@ -530,6 +530,9 @@ export function removeDirSync(dir: string) {
530530 }
531531}
532532
533+ export const removeDir = isWindows
534+ ? promisify ( gracefulRemoveDir )
535+ : removeDirSync
533536export const renameDir = isWindows ? promisify ( gracefulRename ) : fs . renameSync
534537
535538export function ensureWatchedFile (
@@ -804,6 +807,38 @@ function gracefulRename(
804807 } )
805808}
806809
810+ const GRACEFUL_REMOVE_DIR_TIMEOUT = 5000
811+ function gracefulRemoveDir (
812+ dir : string ,
813+ cb : ( error : NodeJS . ErrnoException | null ) => void
814+ ) {
815+ const rmdir = fs . rm ?? fs . rmdir // TODO: Remove after support for Node 12 is dropped
816+ const start = Date . now ( )
817+ let backoff = 0
818+ rmdir ( dir , { recursive : true } , function CB ( er ) {
819+ if ( er ) {
820+ if (
821+ ( er . code === 'ENOTEMPTY' ||
822+ er . code === 'EACCES' ||
823+ er . code === 'EPERM' ) &&
824+ Date . now ( ) - start < GRACEFUL_REMOVE_DIR_TIMEOUT
825+ ) {
826+ setTimeout ( function ( ) {
827+ rmdir ( dir , { recursive : true } , CB )
828+ } , backoff )
829+ if ( backoff < 100 ) backoff += 10
830+ return
831+ }
832+
833+ if ( er . code === 'ENOENT' ) {
834+ er = null
835+ }
836+ }
837+
838+ if ( cb ) cb ( er )
839+ } )
840+ }
841+
807842export function emptyCssComments ( raw : string ) {
808843 return raw . replace ( multilineCommentsRE , ( s ) => ' ' . repeat ( s . length ) )
809844}
0 commit comments