Is there anyway that we can append a script file in the index.html after we build our angular app?

things that i have tried:

{
 "build": {
  "builder": "@angular-devkit/build-angular:browser",
  "options": { ... },
  "configurations": {
   "production": {
    "fileReplacements": [{
     "replace": "src/environments/environment.ts",
     "with": "src/environments/environment.prod.ts"
    }],
    "scripts": ["src/assets/scripts/my-custom-script.js"],
    ...
    }
  }
 }
}

and this:

// main.ts
if (environment.production) {
  enableProdMode();
  const scriptEl = window.document.createElement('script');
  scriptEl.src = 'https://js.intercomcdn.com/vendors-app-modern.28279aba.js';
  window.document.body.appendChild(scriptEl);
}

in both proposed solutions my dist/projectName/index.html file remained unchanged after i ran npm run build command...

2

There are 2 answers

5
Abolfazl Roshanzamir On

You can add the script directly in the index.html

 <script src="./assets/scripts/my-custom-script.js"></script>

UPDATED

In my opinion, you have one option :

Create a folder named dynamic_script in the assets and then put 2 files there

1- Your js file (like ARRS5125-MLL-YourJsfile.js)

2- A JSON file (like info.json), set the name of your file here

{
 "filename":"ARRS5125-MLL-YourJsfile.js"
}

NOTE

Whenever the name of your script is changed, change the filename in the JSON file based on your js name.

Now, You can dynamically load your js file as below

Step 1: Create a service :

@Injectable({ providedIn: "root" })
export class LoadScriptService {
    constructor(private http: HttpClient) { }

    getJsonFileName(): Promise<any> {
        return this.http.get('./assets/dynamic_script/info.json').toPromise();
    }


    loadScript(name: string) {
        return new Promise((resolve, reject) => {
            //load script
            let script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = `/assets/dynamic_script/${name}`;
            if (script.readyState) {  //IE
                script.onreadystatechange = () => {
                    if (script.readyState === "loaded" || script.readyState === "complete") {
                        script.onreadystatechange = null;
                        resolve({ script: name, loaded: true, status: 'Loaded' });
                    }
                };
            } else {  //Others
                script.onload = () => {
                    resolve({ script: name, loaded: true, status: 'Loaded' });
                };
            }
            script.onerror = (error: any) => resolve({ script: name, loaded: false, status: 'Loaded' });
            document.getElementsByTagName('head')[0].appendChild(script);
        });
    }

}

Step 2: In you component

export class AppComponent implements OnInit {
  constructor(private scriptService: LoadScriptService) { }
  ngOnInit(): void {

  }

  private async loadJsonAndScript() {
    const fileInfo = await this.scriptService.getJsonFileName();
    this.scriptService.loadScript(fileInfo.fileName)
  }

  load() {
    this.loadJsonAndScript();
  }
}

NOTE:

After building your project whenever you add the new js file in the dynamic_script then open the info.json and replace the new name manually.

0
Timothy On

On of the possible solution is to use the power of fileReplacements mechanism. Just create index.prod.html and add it into

"fileReplacements": [{
  "replace": "src/environments/environment.ts",
  "with": "src/environments/environment.prod.ts"
},
{
  "replace": "src/index.html",
  "with": "src/index.prod.html"
}]

And add whatever you need in index.prod.html file