Criar um pacote de scripts de vários locais CDN

Vamos supor que nosso aplicativo esteja off-line, ou seja, não podemos usar CDNs de terceiros, portanto, criaremos nossos próprios. Gostaria de hospedar todos os scripts de fornecedores em um aplicativo Web separado (pai) e incluí-los nos pacotes em vários outros aplicativos MVC.

por exemplo

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

Eu gostaria de include no site do aplicativo ASP.NET MVC localizado em: http://localhost/parentWeb/childWeb

ou seja, faça algo assim:

 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")); 

… o que obviamente não é possível no momento. Existe uma boa solução?

Você não pode agrupar resources externos. Se você pensar sobre isso, faz sentido porque você não pode. Isso exigiria que o empacotador realmente baixasse o recurso e o salvasse no sistema de arquivos antes que ele pudesse trabalhar com ele, e, claro, faria tudo de forma assíncrona com algum tipo de retorno se o recurso externo não pudesse ser alcançado. E, então, ele teria que fazer isso em cada carregamento de página, porque ele não pode verificar se há lastmod (e, portanto, saber se ele precisa ser reposto ou não) sem buscar o recurso primeiro.

Se você usar um recurso CDN, o empacotador simplesmente imprime o URL diretamente na página; não faz modificações. Mesmo assim, só permite criar um “conjunto” de apenas uma URL, porque 1) não faria sentido agrupar vários resources de CDN, pois isso prejudicaria o propósito de um CDN e 2) o pacote só existe neste cenário para fornecer um fallback se o recurso CDN não estiver disponível. Caso contrário, você seria servido apenas codificando-o para a página e não se preocupando em configurar um pacote.

Eu encontrei uma solução, que não tem nada a ver com o CDN. Basicamente, se o childWeb estiver hospedado no subdiretório parentWeb , a seguinte configuração do pacote configurável nos childWeb apps selecionará o arquivo do parentWeb e os agrupará como de costume:

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

o bit importante é: ~/../ , que leva você a um nível acima do local da raiz.

Eu sei que este é um tópico antigo, mas eu vim aqui procurando uma maneira real de agrupar resources CDN. A partir da resposta do @Chris Pratt , entendi que não era possível.

Se você estiver se perguntando, estou trabalhando para otimizar um projeto existente de acordo com as práticas recomendadas de desempenho da Web do Google, que fornece uma pontuação baixa quando há várias tags de script e uma mais alta quando todos os scripts são agrupados em uma única referência de script.

Eu precisava de uma maneira de agrupar todos os resources do script CDN e resources locais em ordem. Eu trabalhei neste repository github , que resolveu o meu problema.

Com ele, você constrói um pacote com uma lista de pacotes, cada um contendo uma referência ao recurso cdn, um recurso local para salvar e um booleano indicando se você deseja ou não que o pacote seja reduzido.

 List jsBundles = new List(); 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)); 

Para colocar na página, você usa

 @jsBundles.Load(); 

Isso processará todos os pacotes na lista, fazendo o download de conteúdo para bundles que não foram baixados nas últimas 24 horas (ele é atualizado a cada 24 horas ou quando o aplicativo da Web é reiniciado) . Todo o conteúdo baixado será colocado em arquivos locais (onde especificado) .

Todo o conteúdo será combinado no resultado final, que será colocado na página em uma tag de script (ou tag de link para CSS) .

A function Load também aceita um URL de arquivo local para o conteúdo final de script / css. Se especificado, será fornecido um tag com um src para o caminho relativo desse arquivo local. Por exemplo

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

A declaração acima retornará algo como:

  

Um atributo asynchronous pode ser adicionado à tag de script se o segundo parâmetro da function Load for fornecido.

Ele também funciona em resources cdn css também. Por exemplo

 List cssBundles = new List(); 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"); 

Isso é para o benefício daqueles que, como eu, vieram aqui procurando uma maneira de realmente agregar resources da CDN.

Para usar ScriptBundles com resources de CDN, você precisa usar o construtor sobrecarregado. Infelizmente, você precisa especificar vários ScriptBundle s por arquivo.

Aqui está um ótimo post explicando coisas: http://www.hanselman.com/blog/CDNsFailButYourScriptsDontHaveToFallbackFromCDNToLocalJQuery.aspx

E aqui está um trecho de código:

 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);