Skip to content

Commit dfe4307

Browse files
mattnathanpatak-dev
andcommitted
fix: EPERM error on Windows when processing dependencies (#8235)
Co-authored-by: patak-dev <matias.capeletto@gmail.com>
1 parent 8d7bac4 commit dfe4307

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

packages/vite/src/node/optimizer/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
lookupFile,
1616
normalizeId,
1717
normalizePath,
18+
removeDir,
1819
removeDirSync,
1920
renameDir,
2021
writeFile
@@ -539,7 +540,7 @@ export async function runOptimizeDeps(
539540
async function commitProcessingDepsCacheSync() {
540541
// Processing is done, we can now replace the depsCacheDir with processingCacheDir
541542
// Rewire the file paths from the temporal processing dir to the final deps cache dir
542-
removeDirSync(depsCacheDir)
543+
await removeDir(depsCacheDir)
543544
await renameDir(processingCacheDir, depsCacheDir)
544545
}
545546

packages/vite/src/node/utils.ts

+35
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,9 @@ export function removeDirSync(dir: string) {
530530
}
531531
}
532532

533+
export const removeDir = isWindows
534+
? promisify(gracefulRemoveDir)
535+
: removeDirSync
533536
export const renameDir = isWindows ? promisify(gracefulRename) : fs.renameSync
534537

535538
export 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+
807842
export function emptyCssComments(raw: string) {
808843
return raw.replace(multilineCommentsRE, (s) => ' '.repeat(s.length))
809844
}

0 commit comments

Comments
 (0)