Chris Pickford
Chris Pickford

Reputation: 8991

Read VSTS release variable at runtime (TypeScript/Webpack SPA)

I'm struggling to find a solution to what must be a fairly common problem passing a Visual Studio Team Services (VSTS) release variable into a Single Page Application (SPA) website. There are quite a few moving parts which I'll attempt to explain below.

I have created a release variable ServiceLocations.ApiBaseUri in VSTS that is unique for each environment (dev/test/stage/prod) and my end goal is for the value of this variable to be used by a typescript class (~/src/services/ApiService.ts).

Could anyone please offer any suggestions on a practical approach?

Upvotes: 0

Views: 775

Answers (4)

TechWatching
TechWatching

Reputation: 1549

As your SPA is hosted in a ASP.NET Core wrapper I guess you could also retrieve your app setting ApiBaseUri in your Layout.cshtml file and create a global js variable with this value.

Let me know if you find some disavantages with this solution.

Upvotes: 0

Chris Pickford
Chris Pickford

Reputation: 8991

The VSTS release process provides the ability to substitute variables into a JSON file as part of the IIS Site Deploy task.

JSON variable substitution input field

We are leveraging this to write the value of ServiceLocations.ApiBaseUri into a file (~/clientconfig/settings.json) which has the following initial contents allowing for local development:

{
  "ServiceLocations": {
    "ApiBaseUri": "https://localhost:44390"
  }
}

In the ASP.NET Core Startup.cs file, we are statically hosting this file so it is available by the SPA:

app.UseStaticFiles(new StaticFileOptions
{
  FileProvider = new PhysicalFileProvider(
    Path.Combine(
      Directory.GetCurrentDirectory(), "clientconfig")),
  RequestPath = "/clientconfig"
});

Then in the SPA's ApiService.ts we are using fetch to create a HTTP request for the settings file:

fetch("/clientconfig/settings.json", {
  method: "GET",
  credentials: "omit"
}).then(response => {
  return response.json();
}).then(settings => {
  this._apiBaseUri = settings.ServiceLocations.ApiBaseUri;
})

Upvotes: 2

Liviu Costea
Liviu Costea

Reputation: 3784

When you create or edit the build in VSTS, besides the Tasks tab you also have a Variables tab. There you can setup your environment variables, including the base api url - that's what we do when we build a react app on VSTS (screenshot from a real build we have) enter image description here

Then in code you use it like this: export const baseUrl = process.env.REACT_APP_BASE_API_URL; This is Javascript, but should be something similar for Typescript.

The only downside is that you will have to have separate build definitions per environments.

Upvotes: 2

Lorenzo Montanari
Lorenzo Montanari

Reputation: 968

You could build the project using the --environment="ENV_NAME" where ENV_NAME" is the name of the environment you are targetting.
(Note that it has to be registered in the .angular-cli.json config file under the node environments)

You can then define different values for the same variable in the various environment file. When building, Angular will use the values from the specified env file using the --environment flag.

To use the variable you will need to import it from the environment file doing

import { /*Your vars and/or functions */ } from "../../environments/environment";

INDEPENDENTLY from the environment you are targetting.

Upvotes: 1

Related Questions