Skip to content

Commit 67743a3

Browse files
fix: EPERM error on Windows when processing dependencies (#8235)
Co-authored-by: patak-dev <[email protected]>
1 parent 505f75e commit 67743a3

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
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
@@ -534,7 +535,7 @@ export async function runOptimizeDeps(
534535
async function commitProcessingDepsCacheSync() {
535536
// Processing is done, we can now replace the depsCacheDir with processingCacheDir
536537
// Rewire the file paths from the temporal processing dir to the final deps cache dir
537-
removeDirSync(depsCacheDir)
538+
await removeDir(depsCacheDir)
538539
await renameDir(processingCacheDir, depsCacheDir)
539540
}
540541

packages/vite/src/node/utils.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ export function removeDirSync(dir: string) {
539539
}
540540
}
541541

542+
export const removeDir = isWindows
543+
? promisify(gracefulRemoveDir)
544+
: removeDirSync
542545
export const renameDir = isWindows ? promisify(gracefulRename) : fs.renameSync
543546

544547
export function ensureWatchedFile(
@@ -834,6 +837,38 @@ function gracefulRename(
834837
})
835838
}
836839

840+
const GRACEFUL_REMOVE_DIR_TIMEOUT = 5000
841+
function gracefulRemoveDir(
842+
dir: string,
843+
cb: (error: NodeJS.ErrnoException | null) => void
844+
) {
845+
const rmdir = fs.rm ?? fs.rmdir // TODO: Remove after support for Node 12 is dropped
846+
const start = Date.now()
847+
let backoff = 0
848+
rmdir(dir, { recursive: true }, function CB(er) {
849+
if (er) {
850+
if (
851+
(er.code === 'ENOTEMPTY' ||
852+
er.code === 'EACCES' ||
853+
er.code === 'EPERM') &&
854+
Date.now() - start < GRACEFUL_REMOVE_DIR_TIMEOUT
855+
) {
856+
setTimeout(function () {
857+
rmdir(dir, { recursive: true }, CB)
858+
}, backoff)
859+
if (backoff < 100) backoff += 10
860+
return
861+
}
862+
863+
if (er.code === 'ENOENT') {
864+
er = null
865+
}
866+
}
867+
868+
if (cb) cb(er)
869+
})
870+
}
871+
837872
export function emptyCssComments(raw: string) {
838873
return raw.replace(multilineCommentsRE, (s) => ' '.repeat(s.length))
839874
}

0 commit comments

Comments
 (0)