使用PowerShell自动进行JavaScript压缩

时间:2011-09-20 15:07:20

标签: javascript powershell compression

我正在编写一个脚本,它将获取一堆.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行:char:72   + Get-ChildItem c:\ Scripts \ -exclude jquery * .js,* min.js -recurse | %{java<<<< -jar yuicompressor-2.4.6.jar($ .fullname)   -o($ .fullname)}   + CategoryInfo:NotSpecified:(:String)[],RemoteException   + FullyQualifiedErrorId:NativeCommandError用法:java -jar yuicompressor-x.y.z.jar [options] [输入文件]

     

全球选择   -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仅限Minify,不要   obfuscate preserve-semi保留所有分号   disable-optimizations禁用所有微优化

     

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

知道PowerShell试图告诉我什么吗?

3 个答案:

答案 0 :(得分:5)

尝试这样做:

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

%{..}foreach-object的别名。您从c:\ Newfolder(及其子目录)获取一组文件,并将其中的每一个作为对象传递给管道中的下一个组件。这部分是一个既不支持流水线也不支持对象的外部组件,你将它包装在foreach中,并以它能理解的形式提供文件 - 文件的全名(包括路径)。

答案 1 :(得分:2)

此主题可能会为您提供一些答案。 What do you use to minimize and compress JavaScript libraries?

那就是说,我相信YUI compressor有一个可以从PowerShell启动的独立可执行文件。

答案 2 :(得分:1)

所以,我想我最终会回馈这个社区。我应该首先说我之前从未使用过Powershell而且真的不喜欢它。我很高兴bash现在附带windows。但是,我为一个在win服务器上运行的朋友做了一个有趣的项目,并且需要在将他的.net应用程序代码部署到他的ec2实例后编写一些内容。我知道有十几种更好的方法可以使用真正的构建工具来实现这一点,但是......有时候脚本就是你想要的。希望你们发现它有用。它要求你安装java并拥有闭包jar;您可以尝试使用其他缩小工具。

我需要在这篇文章中赞美Chase Florell让我开始朝着正确的方向前进:How to version javascript and css files as part of a powershell build process?

##################################################################
# 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"