使用PowerShell自动压缩JavaScript

6
我想要编写一个脚本,它可以将一堆.js文件进行压缩,然后在同一个文件夹中用新的文件替换旧的文件。我尝试过几种方法,但总是遇到各种问题,所以我认为最好向那些比我更了解这个领域的人寻求帮助并重新开始。
有人能指点我该如何做吗?
更新: 我正在使用类似于以下命令集合:
>Get-ChildItem c:\NewFolder\ -recurse |
&java -jar yuicompressor-2.4.6

不过,它似乎不想允许这些输出用法。我相信有一种方法可以使其工作,但由于我对PowerShell还是比较新,所以我不太自信能够自己解决它。

更新: 使用下面建议的命令字符串,我可以让PowerShell给我一个看起来像是新压缩的.js文件的读取,但它不会替换现有的文件,也不会将其写入标准输出,我认为它们在同一个目录中,格式为[filename].min.js。

更新: 建议命令的修改版本似乎可以解决问题!

>Get-ChildItem c:\NewFolder\ -exclude jquery*.js,*min.js -recurse | %{java -jar yuicompressor-2.4.6.jar ($_.fullname) -o ($_.fullname)}

然而,当该命令在PowerShell中运行时,奇怪的是,我从PowerShell那里收到了有关Java命令的错误消息...

java.exe:在第4行第72个字符处 + Get-ChildItem c:\Scripts\ -exclude jquery*.js,*min.js -recurse | %{java <<<< -jar yuicompressor-2.4.6.jar ($.fullname) -o ($.fullname)} + CategoryInfo:未指定:(:String)[],RemoteException + FullyQualifiedErrorId:NativeCommandError 用法:java -jar yuicompressor-x.y.z.jar [选项] [输入文件]

全局选项 -h, --help 显示此信息 --type 指定输入文件的类型 --charset 使用指定的字符集读取输入文件 --line-break 在指定的列数后插入换行符 -v, --verbose 显示信息和警告 -o 将输出置于。默认为stdout。 可以使用以下语法处理多个文件: java -jar yuicompressor.jar -o '.css$:-min.css' *.css java -jar yuicompressor.jar -o '.js$:-min.js' *.js

JavaScript选项 nomunge 仅缩小,不要 混淆 preserve-semi 保留所有分号 disable-optimizations 禁用所有微优化

如果未指定输入文件,则默认为stdin。在这种情况下,需要“类型”选项。 否则,仅当输入文件扩展名既不是'js'也不是'css'时,需要“类型”选项。

您有什么想法,PowerShell想告诉我什么?

3个回答

6

试试这样做:

Get-ChildItem c:\NewFolder\ -recurse | %{java -jar yuicompressor-x.y.z.jar $_.fullname}

%{..}foreach-object的别名。你从c:\Newfolder(及其子目录)获取一组文件,并将每个文件作为对象传递到管道中的下一个组件中。由于该部分是不支持管道和对象的外部组件,因此您需要用foreach对其进行封装,并以它可以理解的形式提供文件-文件的完整名称(包括路径)。


非常感谢您的建议 - 它确实让我接近了解决方案,但还没有完全达到目标。您的命令似乎会针对每个文件运行压缩操作,但并不会将其写入输出的 .js 文件中来替换之前未压缩的文件,甚至不会将其保存为不同名称的 [文件名].min.js。我将在原问题上方添加更多信息。 - ShowStopper
1
你的回答让我离答案更近了,比我想象的要更接近。manojlds,你实际上给了我答案,再次感谢你的帮助!我认识你的名字,所以我有一种感觉,虽然我以前没有在我的任何问题中得到过你的答案,但你无疑通过回答其他人的问题来帮助过我,所以我也想感谢你在stackoverflow.com上的角色。我相信这经常被忽略了,但我认为社区非常感激你的帮助。 - ShowStopper
@ShowStopper - 如果这个回答解决了你的问题,你应该将其标记为答案(每个答案旁边都有一个复选框)。如果你愿意,你还可以给答案点赞。 - Brandon Boone

3

好的,这绝对是一个开始,在尝试了YUI和Google的Closure Compiler之后,我觉得我离用PowerShell完成所有操作已经很接近了,但我在一个关键元素上遇到了麻烦。 - ShowStopper

1
因此,我想最终向这个社区做出一些贡献。首先,我应该说我以前从未使用过Powershell,并且真的不喜欢它。我很高兴bash现在与Windows一起发送。但是,我为一个运行在win服务器上的朋友有一个小型有趣的项目,需要编写一些内容,在他的.ec2实例上部署完他的.net应用程序后运行。我知道使用真正的构建工具有大约十几种更好的方法来完成这项工作,但是......有时候脚本就是你想要的。希望你们觉得它有用。它需要您安装Java并拥有闭包jar;您可以尝试其他缩小工具。
我需要在这篇文章中给Chase Florell致谢,因为他让我朝着正确的方向开始:如何将JavaScript和CSS文件版本化作为PowerShell构建过程的一部分?
##################################################################
# minimizeJS.ps1                                                 #
# This file removes all non-minified javascript resources        #
# and then updates all html and aspx pages to point to the       #
# minified js if they are not already.                           #
#                                                                #
# Version 1.0                                                    #
# Usage: minimizeJS.ps1 -debug true|false                        #
##################################################################
param($debug=$true)  #you can remove the =$true to force a user to specify
$maxFiles = Get-ChildItem -Path ./* -Include *.js -Exclude *.min.js, *.min.comp.js -Recurse 
$filesContainingResourceRefs = Get-ChildItem -Path ./* -Include *.html, *.aspx -Recurse 
$fileCollection = New-Object System.Collections.ArrayList

$closureJAR = 'C:\closure\compiler.jar'
$javaLocation = 'C:\Program Files\Java\jre1.8.0_131\bin\java.exe'

#Make sure debug flag is set one way or the other
if (!$debug){
  Write-Host "Debug has not been set.  Please use the -debug true|false argument."
  Exit
}elseif ($debug -eq $true){
  Write-host "Running with debug mode set to $debug."
}elseif ($debug -eq $false){
  Write-host "Running wiht debug mode set to $debug."
}else{
  Write-host "Debug has not been set properly.  Please use the -debug true|false argument."
  Exit
}

#First find everything we have a minified js version of, create an object of their names and paths, and delete the non-min file
Write-Host "Beginning minification of JS files.  Debug is $debug"
foreach ($file in $maxFiles)
    {
        $fileOld = $file.FullName
        $fileNew = $file.FullName.Replace(".js", ".min.js")
        if ($debug -eq $true){
          #Write-Host java -jar $closureJAR --js $fileOld --js_output_file $fileNew
          Write-Host "  ArgList is:  -jar  $closureJAR --js $fileOld --js_output_file $fileNew"
        }else{
            Write-Host "  Minifying: $fileOld"
            Start-Process -FilePath $javaLocation `
             -ArgumentList "-jar $closureJAR --js $fileOld --js_output_file $fileNew" `
             -RedirectStandardOutput '.\console.out' -RedirectStandardError '.\console.err'
        }
    }
Write-Host "End minification of JS files"


#Second find everything we have a minified js version of, create an object of their names and paths, and delete the non-min file
Write-Host "Beginning Removal of files...will display below"
$minFiles = Get-ChildItem -Path ./* -Filter *.min.js -Recurse 
foreach ($file in $minFiles)
    {
        #if ($file.FullName.Replace(".min.js", ".js") exists) {
        $private:nonMinifiedVersionFull = $file.FullName -replace ".min.js", ".js" #.ToString().Replace(".min.js", ".js")
        $private:nonMinifiedVersion = $file -Replace ".min.js", ".js" #.ToString().Replace(".min.js", ".js")
        Write-Host "  Removing: " $private:nonMinifiedVersion
        if ($debug -eq $false) {Remove-Item $private:nonMinifiedVersionFull -ErrorAction SilentlyContinue}

    $temp = New-Object System.Object
    $temp | Add-Member -MemberType NoteProperty -Name "minFileName" -Value $file.ToString()
    $temp | Add-Member -MemberType NoteProperty -Name "minFileFullName" -Value $file.FullName.ToString()
    $temp | Add-Member -MemberType NoteProperty -Name "maxFileName" -Value $private:nonMinifiedVersion.ToString()
    $temp | Add-Member -MemberType NoteProperty -Name "maxFileFullName" -Value $private:nonMinifiedVersionFull.ToString()
    $fileCollection.Add($temp) | Out-Null
    }
Write-Host "End Removal of Files"

if ($debug -eq $true) {
   Write-Host "The fileCollection is:"
   $fileCollection
   }

Write-Host "Beginning update of references to point to minified"
#now go through all the files that could reference them and update the references
foreach ($file2 in $filesContainingResourceRefs)
    {
        $private:file = $file2.FullName

            $fixedContent = [System.IO.File]::ReadAllText($private:file)

            #Now loop through all the min and max files in the collection
           foreach ($line in $fileCollection) {

                    $strFind    = $line.maxFileName.ToString()
                    $strReplace = $line.minFileName.ToString()

                    $fixedContent = $fixedContent.replace($strFind, $strReplace)

            }            
            if ($debug -eq $false) {[System.IO.File]::WriteAllText($private:file, $fixedContent)}


           Write-Host "  Replaced non-minified references in: " $private:file

    }

Write-Host "End update of references to point to minified"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接