Создать комплект скриптов из нескольких мест

Предположим, что наше приложение отключено, то есть мы не можем использовать сторонние CDN, поэтому мы создаем свои собственные. Я хотел бы разместить все сценарии поставщиков в отдельном (родительском) веб-приложении, а затем включить их в пакеты в нескольких других приложениях MVC.

например.

  • http://localhost/parentWeb/Scripts/jquery.js
  • http://localhost/parentWeb/Scripts/jquery-ui.js
  • http://localhost/parentWeb/Scripts/globalize.js

Я хотел бы включить в веб-сайт приложения ASP.NET MVC, расположенный в: 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"));

... что, конечно, в настоящее время невозможно. Хорошее обходное решение?

Ответ 1

Вы не можете связывать внешние ресурсы. Если вы думаете об этом, это имеет смысл, почему вы не можете. Это потребовало бы, чтобы пакетщик фактически загружал ресурс и сохранял его в файловой системе, прежде чем он мог работать с ним, и, конечно же, сделать все это асинхронно с каким-то отступлением, если внешний ресурс не может быть достигнут. И тогда, это должно было бы сделать это при каждой загрузке страницы, потому что он не может проверять lastmod (и, следовательно, знать, нужно ли ему вообще возвращаться или нет), не извлекая сначала ресурс.

Если вы используете ресурс CDN, поставщик просто печатает URL-адрес непосредственно на странице; он не вносит никаких изменений. Даже тогда он позволяет создать "пакет" только одного URL-адреса, потому что 1) было бы бессмысленно связывать несколько ресурсов CDN, поскольку это победит цель CDN и 2) пакет существует только в этом чтобы обеспечить резервную копию, если ресурс CDN недоступен. В противном случае вам будет подан так же просто, просто скопировав его на страницу и не беспокоясь о том, чтобы настроить пакет вообще.

Ответ 2

Я знаю, что это старая тема, но я пришел сюда в поисках реального способа объединения ресурсов CDN. Из ответа @Chris Pratt я понял, что это невозможно.

Если вам интересно, я работаю над оптимизацией существующего проекта в соответствии с рекомендациями Google Web Performance Best Practices, который дает низкую оценку, когда имеется несколько тегов сценария, и более высокую оценку, когда все сценарии объединены в одну ссылку на сценарий.

Мне нужен был способ связать все ресурсы сценария CDN, а также локальные ресурсы по порядку. Я работал над этим репозиторием GitHub, который решил мою проблему.

С его помощью вы создаете пакет со списком пакетов, каждый из которых содержит ссылку на ресурс 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 часа или при перезапуске веб-приложения). Весь загруженный контент будет помещен в локальные файлы (если указано).

Все содержимое будет объединено в конечный результат, который будет помещен на страницу в теге скрипта (или теге ссылки для CSS).

Функция Load также принимает локальный URL-адрес файла для окончательного содержимого script/css. Если указан, вместо него будет указан тег с относительным путем к src для этого локального файла. Например

@jsBundles.Load("~/js/all-my-scripts.js");

Вышеприведенное утверждение вернет что-то вроде:

<script src="~/js/all-my-scripts.js"></script>

Асинхронный атрибут может быть добавлен в тег сценария, если указан второй параметр функции Load.

Это также работает на ресурсах css cdn. Например

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.

Ответ 3

Я нашел решение, которое не имеет никакого отношения к CDN. В принципе, если childWeb размещен в подкаталоге parentWeb, следующая конфигурация пакета в приложениях childWeb выбирает файл из родительскогоWeb и связывает их как обычно:

bundles.Add(
    new ScriptBundle(
        "~/bundles/VendorScripts").Include(
        "~/../Scripts/jquery.js",
        "~/../Scripts/Scripts/jquery-ui.js",
        "~/../Scripts/globalize.js"));

важный бит: ~/../, который выводит вас на один уровень из корневого местоположения.

Ответ 4

Чтобы использовать 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);

Ответ 5

Цель пакета - уменьшить трафик вашего веб-сервера, на котором размещено ваше веб-приложение. при использовании bundle файлы скриптов не будут загружаться параллельно. это необходимо, когда вы используете ваши локальные файлы.

но в случае cdn файлы будут загружаться с сервера cdn, так что вам не нужно создавать пакет для cdn. вам нужен пакет только для локальных файлов