web-dev-qa-db-fra.com

Angular Build CLI utilisant base-href et deploy-url pour accéder aux ressources sur CDN

L'arrière-plan

J'utilise Angular CLI pour créer un projet (avec plusieurs applications). Je souhaite publier les applications sur des sous-chemins distincts sur mon domaine, comme example.com/apps/app1/.

Si je règle le --base-href paramètre à /apps/app1/ il résout tous les problèmes concernant le routeur, et il chargera très bien les ressources (js, css, images, etc.).

Si j'utilise le service Location, je peux utiliser

this.location.prepareExternalUrl('/assets/data/data.json')

pour résoudre les actifs chargés dynamiquement (ils résoudront en /apps/app1/assets/data/data.json).

Jusqu'ici tout va bien. Mais je souhaite maintenant diffuser les ressources de l'application via un CDN, tel que cdn.example.com, tout en hébergeant l'application elle-même sur l'url d'origine example.com/apps/app1/. Alors maintenant, je crée l'application en utilisant:

 ng build -prod --app app1 --base-href "/apps/app1/" --deploy-url "http://cdn.example.com/app-assets/apps/app1/"

Cette fois, j'applique à la fois le --base-href et --deploy-url paramètres. Il fonctionne très bien car il utilise la base-href pour aider le routeur à résoudre l'URL et il charge les fichiers js et css à partir du CDN. Il résout également les références d'URL d'image dans les fichiers CSS à l'aide de l'URL CDN.


Le problème

Lors du chargement d'images ou de données à partir du dossier d'actifs dynamiquement (dans un service ou un modèle), je ne trouve pas de bonne moyen de résoudre les URL à l'aide du deploy-url configuration.

Si j'utilise le service Location, il utilise toujours le base-href pour résoudre les URL, donc

this.location.prepareExternalUrl('/assets/data/data.json')

sera toujours résolu en /apps/app1/assets/data/data.json au lieu de http://cdn.example.com/app-assets/apps/app1/assets/data/data.json.

Je m'attendais à ce qu'il utilise le deploy-url valeur si une est définie, d'autant plus que ce serait une solution générale qui fonctionnerait lors de l'hébergement des fichiers sur le même domaine et lors de l'hébergement des fichiers sur un domaine externe.


La question

Existe-t-il un moyen de résoudre les URL des éléments en tenant compte à la fois du base-href et le deploy-url paramètres?

Idéalement, une fonction officielle Angular comme Location.prepareExternalUrl, mais si je peux obtenir les paramètres base-href et deploy-url de Angular d'une certaine manière, je pourrais créer mon propre service pour cela.

Je ne voudrais pas définir les URL dans la configuration de l'environnement car:

  1. Cela nécessiterait des configurations d'environnement spécifiques par application
  2. Cela crée un conflit potentiel avec les valeurs fournies lors de la création de l'application.
26
david.emilsson

Pour accéder à la valeur de --deploy-url Lors de l'exécution de l'application, créez deploy-url.ts Avec:

export const DEPLOY_URL = new InjectionToken<string>('deployUrl');

Et utilisez cet extrait dans votre fichier main.ts:

const deployUrl = (function() {
  const scripts = document.getElementsByTagName('script');
  const index = scripts.length - 1;
  const mainScript = scripts[index];
  return mainScript.src.replace(/main.*?\.js$/, '');
})();

const DEPLOY_URL_PROVIDER = {
  provide: DEPLOY_URL,
  useValue: deployUrl,
};

platformBrowserDynamic([DEPLOY_URL_PROVIDER])
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

L'idée est d'obtenir l'url du fichier Javascript actuellement exécuté, qui est main.js (ou main.hash.js si outputHashing est activé) et de supprimer le nom du fichier. Ensuite, dans vos services, injectez la valeur de --deploy-url Avec @Inject(DEPLOY_URL) deployUrl: string comme paramètre constructeur.

1
Marcin Majkowski

Je suis tombé sur cette même situation exacte, et comme vous l'avez souligné dans The Background, en construisant à la fois le base-href et deploy-url set fonctionne car nous pouvons servir nos fichiers css et js à partir d'un CDN tout en hébergeant l'application sur un autre serveur.

En tant que solution pour les actifs chargés dynamiquement dans nos modèles, nous avons écrit une API qui fournit des variables d'environnement à cet effet qui fournit les URL appropriées nécessaires par déploiement.

0
DevMike