Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular - How to dynamically change the content in the index.html file when running the ng-build command

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?

like image 919
gayashanbc Avatar asked May 01 '18 08:05

gayashanbc


People also ask

Can we change index html in Angular?

Customize Webpack Configuration in Your Angular Application Now that we've added it to our project, we can use the index transform option to modify the HTML file output, based on the environment.

What is -- watch in Angular?

You may use the watch option on Angular build for updating the output as and when developers make changes to the code. It is very similar to serve, except that the application runs a different web server from the default dev server.

What is index HTML in Angular?

html file. Angular is a framework which allows us to create "Single Page Applications", and here the index. html is the single page which was provided by the server.


3 Answers

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

like image 179
massic80 Avatar answered Oct 06 '22 18:10

massic80


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
}
like image 4
Wojciech Marciniak Avatar answered Oct 06 '22 20:10

Wojciech Marciniak


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

like image 10
ashfaq.p Avatar answered Oct 06 '22 18:10

ashfaq.p