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?
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
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 serve
s. 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
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
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",
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:
- Create separate directories each holding a dedicated version of
index.html
.
Eg.:
src/prod/index.html
src/test/index.html
- 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
}