让我们假设我们的应用程序处于脱机状态,即我们无法使用第三方CDN,因此我们正在创建自己的应用程序。 我想在一个单独的(父)Web应用程序中托管所有供应商脚本,然后将它们包含在其他几个MVC应用程序的捆绑包中。
e.g。
http://localhost/parentWeb/Scripts/jquery.js
http://localhost/parentWeb/Scripts/jquery-ui.js
http://localhost/parentWeb/Scripts/globalize.js
我想要包含在位于http://localhost/parentWeb/childWeb
即。做这样的事情:
bundles.UseCdn = true;
bundles.Add(
new ScriptBundle(
"~/bundles/VendorScripts",
"http://localhost/parentWeb/Scripts/jquery.js",
"http://localhost/parentWeb/Scripts/jquery-ui.js",
"http://localhost/parentWeb/Scripts/globalize.js"));
......当然这是不可能的。有一个很好的解决方法吗?
答案 0 :(得分:13)
您无法捆绑外部资源。如果你仔细想想,为什么你不能这样做是有道理的。它需要捆绑器实际下载资源并在它可以使用之前将其保存到文件系统,当然如果无法访问外部资源,则可以异步进行某种回退。然后,它必须在每个页面加载上执行此操作,因为它无法检查lastmod(因此,知道它是否确实需要重新绑定)而不先获取资源。< / p>
如果您使用CDN资源,则捆绑程序仅将URL直接打印到页面;它没有做任何修改。即便如此,它只允许你创建一个只包含一个URL的“捆绑”,因为1)捆绑多个CDN资源是没有意义的,因为这会破坏CDN的目的,2)捆绑仅存在于此如果CDN资源不可用,则提供回退的方案。否则,您只需将其硬编码到页面即可,而不必担心设置捆绑包。
答案 1 :(得分:7)
我知道这是一个老话题,但我来到这里寻找捆绑CDN资源的实际方法。从@Chris Pratt的回答中,我知道这是不可能的。
如果您想知道,我正在根据Google's Web Performance Best Practises优化现有项目,当有多个脚本标签时得分较低,而当所有脚本捆绑成一个脚本时,得分较高脚本参考。
我需要一种方法来按顺序捆绑所有CDN脚本资源以及本地资源。我处理了github repo,解决了我的问题。
使用它,您可以构建一个包含一个包列表的包,每个包含对cdn资源的引用,要保存到的本地资源,以及一个布尔值,指示是否要将包缩小。
List<Bundle> jsBundles = new List<Bundle>();
jsBundles.Add(new Bundle("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js", @"~/jquery.min.js", Bundle.BundleType.JavaScript, false));
jsBundles.Add(new Bundle("https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js", @"~/jquery-ui.min.js", Bundle.BundleType.JavaScript, false));
jsBundles.Add(new Bundle(@"~/my-local-script.js", Bundle.BundleType.JavaScript, true));
要放置在页面上,请使用
@jsBundles.Load();
这将处理列表中的所有捆绑包,下载过去24小时内未下载的捆绑包的内容(它每24小时更新一次或Web应用程序重新启动时)。下载的所有内容都将放在本地文件(指定的位置)中。
所有内容将合并到最终结果中,该结果将在脚本标记(或CSS的链接标记)中假脱机到页面中。
加载功能还接受最终脚本/ CSS内容的本地文件URL。如果指定,将给出具有src到该本地文件的相对路径的标记。 E.g。
@jsBundles.Load("~/js/all-my-scripts.js");
上述陈述将返回如下内容:
<script src="~/js/all-my-scripts.js"></script>
如果提供了Load函数的第二个参数,则可以将async属性添加到脚本标记中。
它也适用于css cdn资源。 E.g。
List<Bundle> cssBundles = new List<Bundle>();
cssBundles.Add(new Bundle("https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.css", @"~/jquery.ui.css", Bundle.BundleType.CSS, false));
cssBundles.Add(new Bundle(@"~/css/my-local-style.css", Bundle.BundleType.CSS, true));
@cssBundles.Load("~/css/all-my-styles.css");
这是为了那些喜欢我的人的利益,来到这里寻找实际捆绑CDN资源的方法。
答案 2 :(得分:5)
我找到了一个与CDN无关的解决方案。基本上,授权childWeb
托管在parentWeb
的子目录中,childWeb
应用程序中的以下捆绑配置从parentWeb中选择文件并像往常一样捆绑它们:
bundles.Add(
new ScriptBundle(
"~/bundles/VendorScripts").Include(
"~/../Scripts/jquery.js",
"~/../Scripts/Scripts/jquery-ui.js",
"~/../Scripts/globalize.js"));
重要的是:~/../
,它从根位置向上提升一级。
答案 3 :(得分:2)
要将ScriptBundles与CDN资源一起使用,您需要使用重载的构造函数。不幸的是,您需要为每个文件指定多个ScriptBundle
。
这是一篇很棒的博文,解释了一些事情: http://www.hanselman.com/blog/CDNsFailButYourScriptsDontHaveToFallbackFromCDNToLocalJQuery.aspx
这是一个代码段:
bundles.UseCdn = true;
var bundle = new ScriptBundle("~/bundles/bundleNameHere", "//cdn.host.path/to/file");
// Path to the version of the file on your server (in case the CDN fails)
bundle.Include("~/../Scripts/path/to/file");
// JS expression to run, to test if CDN delivered the file or not
bundle.CdnFallbackExpression = "window.ValueYouExpectToBeTruthy";
bundles.Add(bundle);
答案 4 :(得分:0)
捆绑的目的是减少Web应用程序所在的Web服务器的流量。使用捆绑软件,脚本文件将不会并行加载。当您使用本地文件时,这是必需的。
但是如果是CDN,文件将从CDN服务器加载,因此您不必为CDN制作捆绑包。您只需要捆绑本地文件