Reputation: 425
I need to know the build time information(ng build --this_information
or from angular.json
), such as deploy_url
or base_href
at runtime.
For base_href
, I can read the href
attribute of <base>
tag instead, but there is no any alternative for deploy_url
.
Can someone give me an "Angular way" to read build configurations at runtime?
Upvotes: 2
Views: 2407
Reputation: 1397
I ran into this issue too where I needed the deployUrl
to pass into my environment.ts
(and environment.prod.ts
) file during build time. My use case is slightly different where the deployUrl
is dynamic at
build time. My use case:
https://{cdn}/my-app/{version}/{buildNumber}/...
https://app.example.com/
index.html
file from the CDN url – gives me great control over which version & build number gets deployed.Since my CDN url changes with each build, I cannot use the accepted answer of copying the static configurations from angular.json
. So my solution takes a few steps but works great for me:
Need to set up a custom webpack.config.js
build configuration. You can follow Net Basal's article on how to do that.
Get my build script setup in package.json
:
"build:prod": "ng build --prod",
In my build scripts on the server (Jenkins in my case), I make sure to pass the dynamic deployUrl
to the npm script.
npm ci && npm run build:prod -- --deployUrl=$CDN_URL && npm test
$CDN_URL
I dynamically generate during the build process (it matches the CDN pattern I listed above)Add a static string in my environment.ts
file that webpack will later replace:
declare var __CDN_URL__: string;
export const environment = {
production: true,
deployUrl: __CDN_URL__
};
Use my webpack.config.js
to add the __CDN_URL__
variable to webpack's global scope. Making it available in environment.ts
const yargs = require('yargs/yargs')
const webpack = require('webpack');
/* parse out the `deployUrl` option passed into our `npm run build:prod` from step #2 */
const argv = { ...yargs(process.argv).argv };
/* this config gets merged with Angular's webpack config */
module.exports = {
plugins: [
new webpack.DefinePlugin({
__CDN_URL__: JSON.stringify(argv.deployUrl || '') // this will add this variable
})
]
};
process.argv
options, but you could use anything (or even do it yourself).Now you will have access to your dynamic deployUrl
via your environment config. This worked great for my use case.
I use this for all our assets, but most notable is loading my translation .json
files. Example:
// app.module.ts
import { NgModule } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { AppComponent } from './app.component';
import { environment } from '../environments/environment';
@NgModule({
declarations: [
AppComponent
],
imports: [
// other imports
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
}),
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function HttpLoaderFactory (http: HttpClient) {
// this ensures I load my translation files from my cdn url
return new TranslateHttpLoader(http, `${environment.deployUrl}i18n/`, '.json');
}
Hope this helps someone. Cheers!
Upvotes: 2
Reputation: 671
If your build configuration is stored in angular.json, you can copy the bits relevant to you into a json-file in your "src/assets/" folder with the help of a nodeJS script:
let fs = require("fs");
let angularJson = require("../angular.json");
let buildConfig = {
baseHref: angularJson.projects.<projectname>.architect.build.options.baseHref,
deployUrl: angularJson.projects.<projectname>.architect.build.options.deployUrl,
};
fs.writeFile(
"./src/assets/buildConfig.json",
JSON.stringify(buildConfig),
{flag: ""},
err => {
if (err) {
console.log(err);
}
}
);
// example output=> '{"baseHref": "/app", "deployUrl": "https://example.com"}'
In this case this script is stored in /scripts, you may need to update your relative paths if you store it in a different folder. Also remember to include the correct projectname. You can include this script before your regular build step by updating the build script in your package.json like this:
"build": "node ./scripts/extractBuildConfig.js && ng build"
Although if you only want to get the actual location where a web application is actually deployed, it's probably a lot easier to get the value of document.location
(or one of its properties), document.baseURI
, document.domain
and document.getElementsByTagName("base")[0].attributes["href"]
.
All that said, if you set up the base href in your Angular project correctly, all relative paths in your files should automatically point to the correct locations, so I'm not sure what you'd even need this for.
Upvotes: -1