将VB.Net MVC Razor样式/脚本包结合到剃须刀页面内的新包中

时间:2018-04-16 13:31:20

标签: asp.net-mvc vb.net razor

有没有办法将任意数量的已定义的包组合成一个在剃刀页面中即时创建的新包?

例如,在剃刀页面上采取类似的方式:

@section scripts
   @Scripts.Render("~/plugins/bundle1")
   @Scripts.Render("~/plugins/bundle2") 
   @Scripts.Render("~/plugins/bundle3") 
   @Scripts.Render("~/plugins/bundle4")
   @Scripts.Render("~/plugins/bundle5")
End Section

做这样的事情,显然已经破了,代码:

bundles.Add(New ScriptBundle("~/plugins/onTheFly").Include(
  "~/plugins/bundle1",
  "~/plugins/bundle2",
  "~/plugins/bundle3",
  "~/plugins/bundle4",
  "~/plugins/bundle5"
))
@section scripts
   @* only one script file for the browser to download *@
   @Scripts.Render("~/plugins/onTheFly")

以及类似风格包的类似内容。

1 个答案:

答案 0 :(得分:1)

我在https://devblog.appriver.com/easy-cssjs-bundles-for-webforms-mvc-apps/找到了代码,我将其作为下面解决方案的起点。

此解决方案允许您将单个文件添加到新捆绑包中,就像上面给出的链接中找到的类一样。

但是,此解决方案还允许您指定要添加到此新捆绑包的其他捆绑包。当给出包路径时,该类将获得在包中定义的文件路径,并将这些文件包含到创建的新包中。

从其他现有样式包创建新样式包时,此类将检测指定了CssRewriteUrlTransform类的文件路径,并将该转换应用于新创建的包中的同一文件。

<强>用法:

我在同一个文件的末尾添加了这个类,我定义了包含我们创建的所有各种包的BundleConfig类:

Public Class BundleManager
#Region "Script Bundling"
    Public Overloads Shared Function ScriptBundle(newBundlePath As String, ParamArray bundleOrFilePaths As String()) As IHtmlString

        ' used when looping dictionaries below
        Dim pair As KeyValuePair(Of String, Boolean)

        ' Loops through all bundleOrFilePaths given and:
        ' --If the path is for a bundle then adds the filepaths in that bundle to the allFilePaths list
        ' --If the path is for a single file then adds that file path to the allFilePaths list
        ' The end result is a list of individual files to include in the new on-the-fly bundle
        Dim allFilePaths As New Dictionary(Of String, Boolean)
        For idx As Integer = 0 To bundleOrFilePaths.Length - 1
            Dim filepaths As Dictionary(Of String, Boolean) = GetFilepathsInBundle(bundleOrFilePaths(idx), False)
            For Each pair In filepaths
                If allFilePaths.ContainsKey(pair.Key) = False Then
                    allFilePaths.Add(pair.Key, pair.Value)
                End If
            Next
        Next

        Dim thisBundle = New ScriptBundle(newBundlePath)
        For Each pair In allFilePaths
            thisBundle.Include(pair.Key)
        Next
        BundleTable.Bundles.Add(thisBundle)
        Return Scripts.Render(newBundlePath)
    End Function
#End Region

#Region "Style Bundling"
    Public Overloads Shared Function StyleBundle(newBundlePath As String, ParamArray bundleOrFilePaths As String()) As IHtmlString

        ' used when looping dictionaries below
        Dim pair As KeyValuePair(Of String, Boolean)

        ' Loops through all bundleOrFilePaths given and:
        ' --If the path is for a bundle then adds the filepaths in that bundle to the allFilePaths list
        ' --If the path is for a single file then adds that file path to the allFilePaths list
        ' The end result is a list of individual files to include in the new on-the-fly bundle
        Dim allFilePaths As New Dictionary(Of String, Boolean)
        For idx As Integer = 0 To bundleOrFilePaths.Length - 1
            Dim filepaths As Dictionary(Of String, Boolean) = GetFilepathsInBundle(bundleOrFilePaths(idx), True)
            For Each pair In filepaths
                If allFilePaths.ContainsKey(pair.Key) = False Then
                    allFilePaths.Add(pair.Key, pair.Value)
                End If
            Next
        Next

        Dim thisBundle = New StyleBundle(newBundlePath)
        For Each pair In allFilePaths
            If pair.Value = True Then
                thisBundle.Include(pair.Key, New CssRewriteUrlTransform())
            Else
                thisBundle.Include(pair.Key)
            End If
        Next
        BundleTable.Bundles.Add(thisBundle)
        Return Styles.Render(newBundlePath)
    End Function
#End Region

    Public Shared Function GetFilepathsInBundle(ByVal bundleOrFilePath As String, Optional ByVal lookForCssRewriteUrlTransform As Boolean = False) As Dictionary(Of String, Boolean)
        Dim filepaths As New Dictionary(Of String, Boolean)

        Dim myBundle As System.Web.Optimization.Bundle
        myBundle = BundleTable.Bundles.GetBundleFor(bundleOrFilePath)
        If myBundle Is Nothing Then
            ' This isn't a bundle path so it's just a file path, add it to the filepaths list and return
            filepaths.Add(bundleOrFilePath, False)
            Return filepaths
        End If

        Dim currentContext As HttpContext = HttpContext.Current

        Dim httpCtxt As HttpContextWrapper
        httpCtxt = New HttpContextWrapper(currentContext)

        Dim myContext As BundleContext
        myContext = New BundleContext(httpCtxt, BundleTable.Bundles, bundleOrFilePath)

        Dim myIEnumerable As IEnumerable(Of BundleFile)
        myIEnumerable = myBundle.EnumerateFiles(myContext)

        For Each bundlefile In myIEnumerable.ToArray
            Dim useCssRewriteUrlTransform As Boolean = False
            If lookForCssRewriteUrlTransform = True AndAlso bundlefile.Transforms.Count > 0 Then
                useCssRewriteUrlTransform = True
            End If
            filepaths.Add(bundlefile.IncludedVirtualPath, useCssRewriteUrlTransform)
        Next

        Return filepaths

    End Function

End Class    

**在您的剃刀页面** 为浏览器创建单个样式和单个脚本包以进行下载 通过组合此特定剃刀页面使用的所有包和单个文件。

请注意,StyleBundle / ScriptBundle的第一个参数是 NEW 捆绑包的路径,该捆绑包将在运行中创建和使用。

将其放在您要在页面上包含样式的位置:

@BundleManager.StyleBundle("~/styles/onTheFly",
    "~/existing/style/bundle1",
    "~/existing/style/bundle2",
    "~/path/to/individual/file.css",    
    "~/existing/style/bundle3",
    "~/path/to/another/individual/file.css"    
)
' will result in something like:
' <link href="/styles/onthefly?v=tNdHeAW5fTG_oge_eQoH0xgkG9tvARsxlz864XQUBBk1" rel="stylesheet" />

将其放在您要在页面上包含脚本的位置:

@BundleManager.ScriptBundle("~/scripts/onTheFly",
    "~/existing/script/bundle1",
    "~/existing/script/bundle2",
    "~/path/to/individual/file.js",
    "~/existing/script/bundle3",
    "~/path/to/another/individual/file.js"
)
' Will result in something like:
' <link href="/scripts/onthefly?v=tNdHeAW5fTG_oge_eQoH0xgkG9tvARsxlz864XQUBBk1" rel="stylesheet" />