Angular CLI build using base-href and deploy-url to access assets on CDN
To access --deploy-url
value at application runtime, create deploy-url.ts
with:
export const DEPLOY_URL = new InjectionToken<string>('deployUrl');
And use this snippet in your main.ts file:
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));
The idea is to get the url of currently executed Javascript file, which is main.js (or main.hash.js if outputHashing
is enabled) and strip filename from it. Then in your services inject --deploy-url
value with @Inject(DEPLOY_URL) deployUrl: string
as a constructor parameter.
Here is how I solve this "BS"-problem. When your app is for e.g. hosted under www.domain.de/hehe
.
- in
angular.json
add"deployUrl": "./",
- in
src/index.html
inside<head>
add/update<base href="./">
- throughout your app you will use relative paths for assets and whatnot:
<img src="./assets/img/pictureOfMyCrazyWife.png">
- just run
ng build
orng build --prod
conveniently.
with those simple steps you have a general setup. So it will work no matter if its www.domain.de/hehe
, www.domain.de/hehe2
, www.domain.de/
or www.domain.de/lol
I ran into this exact same situation, and as you outlined in The Background, building with both the base-href
and deploy-url
set does work in that we're able to serve up our css and js files from a CDN while hosting the application on another server.
As a solution to dynamically loaded assets in our templates, we wrote an API that delivers environment variables for this purpose which delivers the appropriate URLs needed per deployment.