Configure base URL depending on environment

有些话、适合烂在心里 提交于 2020-02-02 13:30:47

问题


Suppose we have Angular 4+ app that needs to be located in different relative root URLs on different environments, i.e.:

  • http://localhost:4200/index.html for development
  • http://prod.server.com/angular-app/index.html for production

Most likely, we'd want to have that option in our environment.x.ts files:

export const environment = {
    production: false,
    appRoot: "/"
};

export const environment = {
    production: true,
    appRoot: "/angular-app/"
};

How can we configure Angular build/runtime infrastructure to automatically adjust the app depending on this option in environment.x.ts files?

UPDATE: Since I'm using the Angular CLI toolchain indirectly via Visual Studio build/publish system (template), it'd be nice to have a solution based completely on Angular CLI + *.json/*.ts/*.js files. This way it would be suitable for any build system where Angular CLI could be used.


回答1:


If you are using the Angular CLI you can do:

ng build --prod --base-href /myUrl/

OR

ng build --prod --bh /myUrl/



回答2:


An alternative to the option described in @DeborahK answer could be to add build configurations to package.json and setup your IDE to specify the desired build configuration depending on environment it's building for.

Here is a snippet from package.json:

{
  ...
  "scripts": {
    ...
    "build": "ng build",
    "build:Debug": "ng build --dev --base-href /",
    "build:Release": "ng build --prod --base-href /angular-app/",
    ...
  },
  ...
}

And here is a snippet of .csproj file to give you an idea of how it could be integrated with Visual Studio (credits to @Andrey_Fomin in this discussion):

  <Target Name="NgBuildAndAddToPublishOutput" AfterTargets="ComputeFilesToPublish">
    <Exec Command="npm run | findstr &quot;build:$(Configuration)&quot;" ConsoleToMSBuild="true" IgnoreExitCode="true" EchoOff="true" WorkingDirectory="$(MSBuildProjectDirectory)">
      <Output TaskParameter="ConsoleOutput" PropertyName="NpmScriptName" />
    </Exec>
    <Exec Condition=" '$(NpmScriptName)'=='build:$(Configuration)' " Command="npm run $(NpmScriptName)" />
    <Exec Condition=" '$(NpmScriptName)'!='build:$(Configuration)' " Command="npm run build" />
  </Target>



回答3:


UPDATED:
Carefully follow these steps and you are good to go :)
----------------------------------------------------------
1. Create 4 files in environment folder: (2 might there by default)
example: 
environment.ts, environment.prod.ts,environment.test1.ts,environment.test2.ts

2. Use this common code for every file with slight change:

    export const environment = {
      production: true, //production is true for environment.prod.ts file
                        //for other test production is false
      apiUrl: ''        //base_url of each environment
    };

3. Maintain a constant file where you will write all base urls.
code sample of constant.ts:

    import { environment } from '../environments/environment';
    let url = environment.apiUrl;
    export const AppConstant = Object.freeze({
        BASE_API_URL: url,
    }

4. import this constant in your service or component class wherever your calling back-end. 

5. In angular-cli.json: 


    "environmentSource": "environments/environment.ts",
          "environments": {
            "dev": "environments/environment.ts",
            "prod": "environments/environment.prod.ts",
            "test1": "environments/environment.test1.ts",
            "test2": "environments/environment.test2.ts"
          }

6.

    ng build --env=prod
    ng build --env=dev / ng build
     ng build --env=test1
     ng build --env=test2

7. if aot is creating problem. you can use :  ng build --env=prod --no-aot

8. TO make things simple: 

you can additonally add new build commands: 
 "scripts": {
    "ng": "ng",
    "start": "ng serve --env=local --no-aot",
    "start:qa": "ng serve --env=dev --no-aot",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "build:prod": "ng build --prod --env=prod --no-aot --output-hashing=all",
    "build:dev": "ng build --prod --env=dev --no-aot --output-hashing=all",
    "build:local": "ng build --env=local"
  }
When you run,command is  ==> npm run start OR npm run start:qa 
OR==> npm run build:local or npm run build:dev, etc.

9. Hashing will solve caching isuue.

Hope it solves your problem. It works for me.



回答4:


In angular 6 we can do it in better way, by using environment.x.ts (x means it might be production/development/configuration etc files).

suppose if its dev mode file name(environment.dev.ts)

export const environment = {
    production: false,
    appRoot: "/" or appRoot: "http://somerestapi"
};

suppose if its in production mode file name(environment.prod.ts)

   export const environment = {
        production: true,
        appRoot: "/" or appRoot: "http://somerestapi"
    };

and same appRoot can be used in all services as in below service.ts file.

import { environment } from '../../environments/environment';

 appRoot = environment.appRoot;

    emplLoginCheckUrl = this.appRoot + "/checkValidUser";

      validateUserDetails(employeeDetails): Observable<any> {
            console.log(this.appRoot );
            return this._httpClinet.post(this.emplLoginCheckUrl, employeeDetails);
        }

after this we have one more job to do, its open your angular.json file

apply below changes to "dev": mode

"dev": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.dev.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": true,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }

and apply below changes to "production": mode

 "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            },

but you have to choose which one is needed to run the application, like if you want to run in dev mode use below command it will automatically apply appRoot(URL) for all aservices where you called.

ng build --configuration=dev (for development mode). ng build --configuration=production (for production mode).



来源:https://stackoverflow.com/questions/45970744/configure-base-url-depending-on-environment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!