powershell - 如何在 powershell 构建过程中对 javascript 和 css 文件进行版本控制?

标签 powershell versioning

我正在使用servicestack/bundler从 powershell 构建脚本中组合并缩小我的 js 和 css 文件。

作为此构建过程的一部分,我希望在我的 _Layout 文件中找到生成的 javascript 和 css 文件,并自动附加查询字符串版本。

例如

<link type="text/css" rel="stylesheet" href="/Content/app.min.css?v=1")" />
<script type="text/javascript" src="/Content/app.min.js?v=1")"></script>

变成了

<link type="text/css" rel="stylesheet" href="/Content/app.min.css?v=2")" />
<script type="text/javascript" src="/Content/app.min.js?v=2")"></script>

在 powershell 中执行此操作最有效的方法是什么?

最佳答案

我已经弄清楚了,并将解决方案上传到github 。我选择在文件名 instead of appending a querystring parameter at the end of the file 中使用 MD5 哈希值。出现这种情况的原因是某些代理没有使用查询字符串缓存文件。

如果文件未更改,此解决方案也不会对文件进行版本控制。

这是带有注释的解决方案,以提高可读性。

#region Variables
    $directoryPath = Split-Path ((Get-Variable MyInvocation).Value).MyCommand.Path   # directory the script is running from (document root)
    $jsFilePath = "assets\scripts\"                                                  # scripts path will end with trailing slash "\"
    $cssFilePath = "assets\css\"                                                     # css path will end with a trailing slash "\"
    $jsFileNameRegex = [regex] '(nameOfYourProject\.).*(\.min\.js)'                  # myApp.asdf1234.min.js
    $cssFileNameRegex = [regex] '(nameOfYourProject\.).*(\.min\.css)'                # myApp.asdf1234.min.js
    $filesContainingVersionedResourceRefs = @("$directoryPath\index.html")           # array of files to search for script/css references
#endregion


#region Functions

# Function which versions javascript and css files using the content hash.
# NOTE: this assumes that you have two "default" versions of your combined files
#    nameOfYourProject.css/js
#    nameOfYourProject.min.css/js
function versionResource($fileToVersionRegex, $filePath){

    # Gets the default file name from the regex
    $defaultFileName = $fileToVersionRegex.ToString() -replace "(\()|(\))|(\\)|(\*)", ""
    $defaultFileName = $defaultFileName -replace "\.\.\.", "."

    # Gets the content of the default file and creates a hash
    $fileContent = Get-Content $filePath\$defaultFileName
    $md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
    $utf8 = new-object -TypeName System.Text.UTF8Encoding
    $hash = [System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($fileContent)))
    $versionHash = $hash.Replace('-', '')

    # Creates a new file name based on the content hash
    $newFileName = $defaultFileName -replace "\.min", ".$versionHash.min"

    # Tries to get the old versioned file name
    $fileToVersion = Get-ChildItem $filePath | Where-Object {$_.Name -match $fileToVersionRegex}
    if($fileToVersion -ne $null) {
        $oldFileName = $fileToVersion.Name
    }

    # $newFileName is still just a string at this point.
    # If the new version name doesn't match the old version name,
    # then we know that we need to update everything to the new version.
    if($oldFileName -ne $newFileName) {

        # OPTIONAL
        # remove the obsolete version of the file to be versioned
        # You may choose to NOT remove the versioned file, however
        # since it "should" be in your version control, you can roll back if necessary
        if($fileToVersion -ne $null) {
            Remove-Item $filePath$oldFileName -Force -ErrorAction SilentlyContinue
        }

        # rename the default file with the new file name
        Rename-Item -literalPath $filePath$defaultFileName -NewName $newFileName

        # loop through all of the specified source files and replace with the appropriate versioned file
        foreach($private:file in $filesContainingVersionedResourceRefs){
            $fileContent = Get-Content $private:file
            Clear-Content $file

            if($oldFileName -ne $null){
                # replace the old version string if it exists
                $newFileContent = $fileContent -replace "$oldFileName","$newFileName"
            } else {
                # replace the default version string if it exists
                $newFileContent = $fileContent -replace "$defaultFileName","$newFileName"                
            }

            Add-Content $private:file $newFileContent

        }
    }

    # OPTIONAL: remove original files
    # this just keeps your directory clean and free of unneeded versions of the css/js
    $private:nonMinifiedVersion = $defaultFileName -replace ".min", ""
    Remove-Item -LiteralPath $filePath$defaultFileName -ErrorAction SilentlyContinue
    Remove-Item -LiteralPath $filePath$private:nonMinifiedVersion -ErrorAction SilentlyContinue

}

# version the Javascript
versionResource $jsFileNameRegex $jsFilePath


# version the css
versionResource $cssFileNameRegex $cssFilePath  

关于powershell - 如何在 powershell 构建过程中对 javascript 和 css 文件进行版本控制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15675345/

相关文章:

arrays - PowerShell执行速度的提高

powershell - 将PowerTime从Powershell转换为可用的方式,但无法使其正常工作

powershell - powershell 中是否有相当于 "... || die"的值?

powershell - 将Powershell脚本粘贴到Powershell中时运行,但从快捷方式运行时不运行

javascript - jQuery 文件名

powershell - 在powershell中返回消息而不是msi的退出代码

c++ - C++ 11 Cereal 序列化-版本控制

ruby-on-rails - 如何自定义 Rails 4 render() 查找文件的方式?

git - 将 svn 分支与旧的未跟踪代码 merge

python - 升级我的 python 环境时,类型为 'bytes' 的对象不是 JSON 可序列化的