13

I want to change the URL of a script tag when I'm running the ng build command with the --prod option and without the --prod option. Following is an example.

ng build --prod

<!DOCTYPE html>
<html>
<head>
    <title>Home Page</title>
</head>
<body>
    <script src="https://my-site.net/prod.js"></script>
</body>
</html>

ng build

<!DOCTYPE html>
<html>
<head>
    <title>Home Page</title>
</head>
<body>
    <script src="https://my-site.net/dev.js"></script>
</body>
</html>

How can I achieve this?

1

5 Answers 5

13

In angular.json you can configure the index file to be used (I'm using Angular 8):

"projects": {
    "projectName": {
        "architect": {
            "build": {
                "options": {
                    "index": "src/index.html", // this is the default location (also for ng serve)
                    "configurations": {
                        "production": {
                            "index": "index-prod.html" // this is the prod version (you can also link it to /prod/index.html or whatever: it will be placed in the dist root folder with the provided name)
                        },
                        "development": {
                            "index": "index-whatever.html" // this is the version for ng build --configuration=development`
                        }
                    }
                }
            }/*, UPDATED: THIS DOESN'T WORK
            "serve": {
                "index": "dev/index.html" // file to be used in ng serve
            }*/
        }
    }
}

AFAIK none of those "index"s is mandatory, except the first

Sidenote: this is what I just tried with some tries, builds and ng serves. I didn't find it in any documentation.

Check it out and let me know.

===========

UPDATE 19 Oct '19: I noticed that the configuration reported above still uses src/index.html also for serve on "@angular/cli": "^8.3.6", "@angular/compiler-cli": "^8.2.8". Looks like there is no override for serve itself. My question is: should serve always inherit base index configuration?

Trying to dig a bit more I found this: https://github.com/angular/angular-cli/issues/14599

There is an example of how it should work with the new CLI, but attempting to replace the

"development": {
    index": "index-whatever.html"
}

with a

"development": {
    index": {
        "input": "index-whatever.html"
    }
}

and building, it gives me a Schema validation failed with the following errors: Data path ".index" should be string.

===========

UPDATE 10 Apr '20:

I just noticed that in October's update I missed a quote in the latest code snippet. I don't remember whether it was copied directly from my code - hence the reported error could be related to that - or it was a mistype when I attempted to rewrite the code. I'll check again whenever I'll have time

Sign up to request clarification or add additional context in comments.

6 Comments

This answer is correct but could largely be simplified. Could you modify it and just give the final solution described in this github issue? See this answer as an example.
Hi, thanks for your advice, but as I wrote the solution in the issue doesn't work on my side.
Although I am currently on 8.1.1 cli (end thus your first version worked), I have seen a solution here for later versions (not sure which one): github.com/angular/angular-cli/issues/…. The scheme thing seems to be fixed by this PR: github.com/angular/angular-cli/pull/15582 but I am also not sure in which version this is released.
@massic80 ok sorry, I didn't realize that current solution does not work with previous angular versions or other settings.
You're welcome :) Actually, mine WASN'T a previous version, but validator didn't allow angular to compile it. Is it working on your side? Interesting...
|
12

For current versions of Angular from v6.1.0-beta.2 on, you can use the fileReplacements value in the angular.json file configurations as detailed in this answer: https://stackoverflow.com/a/57274333/228429 by @massic80.

More info here: https://github.com/angular/angular-cli/issues/4451#issuecomment-395651237

For older versions before v6.1.0-beta.2, Angular CLI does not provide any such feature. But you can use environment variables to inject proper scripts dynamically on run time.

Eg:

main.ts

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

if (env.production) {
   const script = document.createElement('script');
   script.src = https://my-site.net/prod.js
   document.head.appendChild(script);
} else {
   const script = document.createElement('script');
   script.src = https://my-site.net/dev.js
   document.head.appendChild(script);
}

Read more here: https://github.com/angular/angular-cli/issues/4451#issuecomment-285329985

3 Comments

fileReplacement didnt replace index file, why?
fileReplacements of index.html doesn't work for me either on angular8 (I think there's now an "index":"src/index.prod.html" attribute, but that ones doesn't work either for me)
Using the dynamic approach in main.ts can be useful for things like changing a google analytics id per environment with configuration transformations as part of a deployment process, instead of during build.
6

If you want to stick with standard src/index.html while serving locally by want to have specialised index.html files per production / test configuration (as it was in my case, where different Google Analytics code chunks have been to be applied) do it simply:

  1. Create separate directories each holding a dedicated version of index.html. Eg.:

src/prod/index.html src/test/index.html

  1. Let angular.json know about them, per configuration:
"configurations": {
    "production": {
        "fileReplacements": [
            {
                "replace": "src/environments/environment.ts",
                "with": "src/environments/environment.prod.ts"
            }
        ],
        "index": "src/index/prod/index.html",
        // other stuff
    },
    "test": { 
        "fileReplacements": [
            {
                "replace": "src/environments/environment.ts",
                "with": "src/environments/environment.test.ts"
            }
        ],
        "index": "src/index/test/index.html",
        // other stuff
    }
    // other stuff
}

Comments

3

this aint pretty but it works, i just have 2 index files and i copy over the main one before the build

"build:en": "copy src\\index.en.html src\\index.html && ng build --configuration=production-en",
"build:fr": "copy src\\index.fr.html src\\index.html && ng build --configuration=production-fr",

1 Comment

take care that this method is not cross-OS
2

With Angular 8 and 9 you can add custom webpack builder: https://github.com/just-jeb/angular-builders/tree/master/packages/custom-webpack

npm install @angular-builders/custom-webpack

and follow instructions from this page: https://github.com/just-jeb/angular-builders/blob/master/packages/custom-webpack/README.md

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.