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.
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.
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:
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.
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.