gpt4 book ai didi

javascript - 如何在不重新编译的情况下使用 ASP.NET 捆绑和缩小?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:49:45 25 4
gpt4 key购买 nike

约束:我没有使用 MVC,只是在我的 Web 应用程序中使用常规的 ol'.aspx 文件。也不使用母版页 - 每个页面都是不同的野兽,因此该解决方案不适合我。

我读过的关于捆绑和缩小的大多数示例都需要一些特殊的 MVC 标记,或者要求您预先识别捆绑的脚本/样式表,然后引用这些 bundle 。我想避免每次在 .aspx 页面中添加或修改 .js 引用时都重新编译 DLL。

我对阅读 Msft 文档有点困惑.. 有没有一种方法(比如 ASP.NET 控件)我可以只包装一系列 script 标签(或 链接 CSS 的 标签)来动态地创建和使用一个包?我不想重新发明轮子,而是认真考虑创建我自己的用户控件/自定义控件来处理这个问题。还有其他选择吗?

例如,寻找这样的东西:

<asp:AdHocScriptBundle id="mypage_bundle" runat="server">
<script type="text/javascript" src="~/scripts/mypage1.js"></script>
<script type="text/javascript" src="~/scripts/mypage2.js"></script>
<script type="text/javascript" src="~/scripts/mypage3.js"></script>
</asp:AdHocScriptBundle>

当启用捆绑时,自动将 asp:AdHocScriptBundle 的内容替换为单个 script 标记,类似于:

<script type="text/javascript" src="/webappname/bundles/mypage_bundle.js?v=dh120398dh1298dh192d8hd32d"></script>

当禁用 Bundling 时,通常会像这样输出内容:

<script type="text/javascript" src="/webappname/scripts/mypage1.js"></script>
<script type="text/javascript" src="/webappname/scripts/mypage2.js"></script>
<script type="text/javascript" src="/webappname/scripts/mypage3.js"></script>

有什么想法吗?

无论如何我都会自己动手,但是如果已经有解决方案请分享,谢谢!

最佳答案

我推出了自己的解决方案,效果很好!我创建了 4 个可用作自定义服务器控件的类:

  • 脚本包
  • 脚本
  • 样式包
  • 链接

这些调用函数围绕我的自定义捆绑库,它本身是 System.Web.Optimization API 的包装器。

ScriptBundleStyleBundle 的渲染过程中,我然后检查一个内部设置(与我在 System. Web.Optimization API)告诉页面要么使用捆绑,要么简单地写出正常的 script/link 标签。如果启用了捆绑,它会从我的自定义捆绑库中调用此函数(对于脚本,样式的类似代码。下面代码中的 Bundler 是我的自定义捆绑库的类 - 以防万一 Microsoft 更改系统.Web.Optimization API 我想要一个介于两者之间的层,这样我就不必更改我的代码太多):

    public static void AddScriptBundle(string virtualTargetPath, params string[] virtualSourcePaths)
{
var scriptBundle = new System.Web.Optimization.ScriptBundle(virtualTargetPath);
scriptBundle.Include(virtualSourcePaths);
System.Web.Optimization.BundleTable.Bundles.Add(scriptBundle);
}

为了确保我只创建尚不存在的 Bundle,我首先使用此方法检查 Bundle(在使用上述方法之前):

    public static bool BundleExists(string virtualTargetPath)
{
return System.Web.Optimization.BundleTable.Bundles.GetBundleFor(virtualTargetPath) != null;
}

然后我使用此函数通过 System.Web.Optimization 吐出 bundle 的 URL:

    public static System.Web.IHtmlString GetScriptBundleHTML(string virtualTargetPath)
{
return System.Web.Optimization.Scripts.Render(virtualTargetPath);
}

在我的 .aspx 文件中,我这样做:

<%@ Register TagPrefix="cc1" Namespace="AdHocBundler" Assembly="AdHocBundler" %>

...

<cc1:ScriptBundle name="MyBundle" runat="Server">
<cc1:script src='~/js/script1.js'/>
<cc1:script src='~/js/utils/script2.js'/>
</cc1:ScriptBundle>

我的诀窍是弄清楚我必须将 scriptlink 标签转换为 ScriptBundle 中的列表项,并且StyleBundle 控件,但之后效果很好,它让我可以使用波浪号运算符轻松引用应用程序根目录(使用 Page.ResolveClientUrl(),这有助于创建模块内容)。

感谢转到此 SO 答案帮助我弄清楚如何创建自定义集合控件:How do you build an ASP.NET custom control with a collection property?

更新:为了全面披露,我获得了共享 ScriptBundle 代码的许可(StyleBundle 几乎相同,因此没有包含它):

[DefaultProperty("Name")]
[ParseChildren(true, DefaultProperty = "Scripts")]
public class ScriptBundle : Control
{
public ScriptBundle()
{
this.Enabled = true;
this.Scripts = new List<Script>();
}

[PersistenceMode(PersistenceMode.Attribute)]
public String Name { get; set; }

[PersistenceMode(PersistenceMode.Attribute)]
[DefaultValue(true)]
public Boolean Enabled { get; set; }

[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public List<Script> Scripts { get; set; }

protected override void Render(HtmlTextWriter writer)
{
if (String.IsNullOrEmpty(this.Name))
{
// Name is used to generate the bundle; tell dev if he forgot it
throw new Exception("ScriptBundle Name is not defined.");
}

writer.BeginRender();

if (this.Enabled && Bundler.EnableOptimizations)
{
if (this.Scripts.Count > 0)
{
string bundleName = String.Format("~/bundles{0}/{1}.js",
HttpContext.Current.Request.FilePath,
this.Name).ToLower();

// create a bundle if not exists
if (!Bundler.BundleExists(bundleName))
{
string[] scriptPaths = new string[this.Scripts.Count];
int len = scriptPaths.Length;
for (int i = 0; i < len; i++)
{
if (!string.IsNullOrEmpty(this.Scripts[i].Src))
{
// no need for resolve client URL here - bundler already does it for us, so paths like "~/scripts" will already be expanded
scriptPaths[i] = this.Scripts[i].Src;
}
}
Bundler.AddScriptBundle(bundleName, scriptPaths);
}

// spit out a reference to bundle
writer.Write(Bundler.GetScriptBundleHTML(bundleName));
}
}
else
{
// do not use bundling. generate normal script tags for each Script
foreach (Script s in this.Scripts)
{
if (!string.IsNullOrEmpty(s.Src))
{
// render <script type='<type>' src='<src'>/> ... and resolve URL to expand tilde, which lets us use paths relative to app root
// calling writer.Write() directly since it has less overhead than using RenderBeginTag(), etc., assumption is no special/weird chars in the cc1:script attrs
writer.Write(String.Format(Script.TAG_FORMAT_DEFAULT,
s.Type,
Page.ResolveClientUrl(s.Src)));
}
}
}
writer.EndRender();
}
}

public class Script
{
public const String ATTR_TYPE_DEFAULT = "text/javascript";
public const String TAG_FORMAT_DEFAULT = "<script type=\"{0}\" src=\"{1}\"></script>";

public Script()
{
this.Type = ATTR_TYPE_DEFAULT;
this.Src = null;
}

public String Type { get; set; }
public String Src { get; set; }
public String Language { get; set; }
}

关于javascript - 如何在不重新编译的情况下使用 ASP.NET 捆绑和缩小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17437800/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com