作为 PowerShell 构建过程的一部分,如何对 javascript 和 css 文件进行版本控制? [英] How to version javascript and css files as part of a powershell build process?

查看:21
本文介绍了作为 PowerShell 构建过程的一部分,如何对 javascript 和 css 文件进行版本控制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 servicestack/bundler 来组合和缩小我的 js &来自 powershell 构建脚本中的 css 文件.

I'm using servicestack/bundler to combine and minify my js & css files from within a powershell build script.

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

As a part of this build process I'd like to find the resulting javascript and css files in my _Layout file, and append a querystring version automagically.

例如

<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 中执行此操作的最有效方法是什么?

What would be the most efficient way to do this in powershell?

推荐答案

我已经想通了,并将解决方案上传到 github.我选择在文件名中使用 MD5 哈希值 而不是在文件末尾附加查询字符串参数.这是因为某些代理没有缓存带有查询字符串的文件.

I've figured it out, and have uploaded the solution to github. I've chosen to use an MD5 hash within the file name instead of appending a querystring parameter at the end of the file. The reason for this is because of some proxy's not caching files with querystrings.

如果文件没有改变,这个解决方案也不会版本文件.

This solution also does NOT version files if they have not changed.

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

Here's the solution with comments for readability.

#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 构建过程的一部分,如何对 javascript 和 css 文件进行版本控制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆