Search code examples
angularangular-cliangular13

Change the location of runtime.js, polyfills.js and so on in index.html


In my index.html file I have multiple javascript files that are included in the body tag

<body>
    <div ng-view class="view"></div>
    <script src="legacy/script1.js"></script>
    <script src="legacy/script2.js"></script>
    <script src="legacy/script3.js"></script>
</body>

When I build my application angular adds the runtime.js, polyfills.js and so on right before the closing of the body tag.

<body>
    <div ng-view class="view"></div>
    <script src="legacy/script1.js"></script>
    <script src="legacy/script2.js"></script>
    <script src="legacy/script3.js"></script>
    <script src="runtime.js" type="module"></script>
    <script src="polyfills.js" type="module"></script>
    <script src="styles.js" defer=""></script>
    <script src="scripts.js" defer=""></script>
    <script src="vendor.js" type="module"></script>
</body>

Is there any way I change where they are placed?

I need the output to be:

<body>
    <div ng-view class="view"></div>
    <script src="legacy/script1.js"></script>
    <script src="legacy/script2.js"></script>
    <script src="runtime.js" type="module"></script>
    <script src="polyfills.js" type="module"></script>
    <script src="styles.js" defer=""></script>
    <script src="scripts.js" defer=""></script>
    <script src="vendor.js" type="module"></script>
    <script src="legacy/script3.js"></script>
</body>

Solution

  • This can be achieved using @angular-builders/custom-webpack by using the following:

    in your angular.json change builder to @angular-builders/custom-webpack:browser and then set "indexTransform": "./index-html-transform.ts"

    In the index-html-transform.ts you can define custom placement logic so I used the following:

    import { TargetOptions } from '@angular-builders/custom-webpack';
    
    export default (_targetOptions: TargetOptions, indexHtml: string) => {
        const start = indexHtml.indexOf('<script src="runtime');
        const end = indexHtml.indexOf('</body>');
        const injectionPositionHtml = '<!-- angular13 -->';
    
        const scripts = indexHtml.slice(start, end);
    
        return indexHtml.replace(scripts, '').replace(injectionPositionHtml, scripts);
    };
    

    now I can place <!-- angular13 --> between script2 and 3 and it works as intended!