平时写代码,工作目录中的node_modules会占用很大的空间有时需要清理。而直接使用Windows的删除会很慢,以下是基于PowerShell的几种删除方法
1.单条命令的方式
- 在当前目录下执行,递归查找所有的node_modules目录递归删除
Get-ChildItem -Path . -Filter node_modules -Recurse | Remove-Item -Force -Recurse
2.简单脚本封装
- 还是使用PowerShell的Remove-Item
- 先查找到所有的node_modules路径然后计算大小,最后用户确认删除的同时计算删除时间
# 查询指定路径下的所有node_modules路径
function Find-TargetDirectories {
param (
[Parameter(Mandatory = $true)]
[string]$Path
)
$directories = Get-ChildItem -Path $Path -Directory
foreach ($directory in $directories) {
if ($directory.Name -eq "node_modules") {
Write-Output $directory.FullName
}
else {
Find-TargetDirectories -Path $directory.FullName
}
}
}
# 打印所有路径和大小
$dirs = Find-TargetDirectories -Path (Get-Location)
Write-Host "The following path will be deleted:"
$fso = New-Object -ComObject Scripting.FileSystemObject
$dirs | ForEach-Object {
$dir_size = ($fso.GetFolder($_).Size/1MB).ToString("F2") + "MB"
Write-Host "Size: $dir_size Path: $_"
}
# 用户确认
$continue = Read-Host "Do you want to continue with the deletion operation? (Y/N)"
if ($continue -eq "N") {
Write-Host "The deletion operation has been canceled."
exit
}
# 开始删除
$start_time = (Get-Date)
foreach ($dir in $dirs) {
Remove-Item -Path $dir -Recurse -Force
}
$total_time = (New-TimeSpan $start_time).totalseconds.ToString("F2")
Write-Host "Delete completed, time taken: $total_time s"
3.使用robocopy
- 有人说在像PowerShell这样的解释性语言中重新发明轮子会比本地已有的实现慢。然后推荐了robocopy。
- Robocopy是Windows中自带的一个复制工具,但也可以用来删除文件。
- 原理是使用它的
/mir
镜像目录树命令,通过把一个空目录镜像到指定要删除的目录位置,那个目录的所有内容将会删除。
# 查询指定路径下的所有node_modules路径
function Find-TargetDirectories {
param (
[Parameter(Mandatory = $true)]
[string]$Path
)
$directories = Get-ChildItem -Path $Path -Directory
foreach ($directory in $directories) {
if ($directory.Name -eq "node_modules") {
Write-Output $directory.FullName
}
else {
Find-TargetDirectories -Path $directory.FullName
}
}
}
# 在TEMP目录下生成待创建空文件夹名称
function GetRandomTempPath {
Do {
$randomFileName = [System.IO.Path]::GetRandomFileName()
$fullPath = Join-Path -Path $env:TEMP -ChildPath $randomFileName
} While (Test-Path $fullPath);
Return $fullPath;
}
# 打印所有路径和大小
$dirs = Find-TargetDirectories -Path (Get-Location)
Write-Host "The following path will be deleted:"
$fso = New-Object -ComObject Scripting.FileSystemObject
$dirs | ForEach-Object {
$dir_size = ($fso.GetFolder($_).Size / 1MB).ToString("F2") + "MB"
Write-Host "Size: $dir_size Path: $_"
}
# 用户确认
$continue = Read-Host "Do you want to continue with the deletion operation? (Y/N)"
if ($continue -eq "N") {
Write-Host "The deletion operation has been canceled."
exit
}
# 创建空文件夹
$emptyDir = GetRandomTempPath
mkdir $emptyDir | Out-Null
# 开始删除
$start_time = (Get-Date)
foreach ($dir in $dirs) {
robocopy /mir $emptyDir $dir /MT:32 | Out-Null
Remove-Item -Path $dir
}
Remove-Item -Path $emptyDir
$total_time = (New-TimeSpan $start_time).totalseconds.ToString("F2")
Write-Host "Delete completed, time taken: $total_time s"
4.使用.NET的方法
- 还有一种方法是,让PowerShell使用.NET的方法进行文件和文件夹操作,据说可能比等效的PowerShell命令更快。
- 以下使用System.IO.Directory中的Delete(String,Boolean)方法递归删除指定目录路径的所有内容。
# 查询指定路径下的所有node_modules路径
function Find-TargetDirectories {
param (
[Parameter(Mandatory = $true)]
[string]$Path
)
$directories = Get-ChildItem -Path $Path -Directory
foreach ($directory in $directories) {
if ($directory.Name -eq "node_modules") {
Write-Output $directory.FullName
}
else {
Find-TargetDirectories -Path $directory.FullName
}
}
}
# 打印所有路径和大小
$dirs = Find-TargetDirectories -Path (Get-Location)
Write-Host "The following path will be deleted:"
$fso = New-Object -ComObject Scripting.FileSystemObject
$dirs | ForEach-Object {
$dir_size = ($fso.GetFolder($_).Size / 1MB).ToString("F2") + "MB"
Write-Host "Size: $dir_size Path: $_"
}
# 用户确认
$continue = Read-Host "Do you want to continue with the deletion operation? (Y/N)"
if ($continue -eq "N") {
Write-Host "The deletion operation has been canceled."
exit
}
# 开始删除
$start_time = (Get-Date)
foreach ($dir in $dirs) {
[System.IO.Directory]::Delete($dir, $true)
}
$total_time = (New-TimeSpan $start_time).totalseconds.ToString("F2")
Write-Host "Delete completed, time taken: $total_time s"
- 简单测试:我复制了3个相同大小的前端项目分别使用3种方法清理,结果是最后这个方法最快。