title: How to use angular bundles in index.ftl (freemarker template)
body: <p>I am working on multi-module Gradle project having below structure</p>
  <pre class="lang-sh prettyprint-override"><code>    parent-app
       - backend
          - src/main
              - java
              - resources
              - webapp
          - build.gradle
       - angular-ui
          - src
              - app
              - envirnoments
              - index.html
              - index.ftl
              - main.ts
          - angular.json
          - package.json
          - webpack.config.js
          - build.gradle
       - build.gradle
       - settings.gradle
  
  </code></pre>
  <p>I am using <code>index.ftl</code> (freemarker templates) as my view which uses some macros from in-house library (gradle dependencies) to get headers. But for everything else, I have to use angular components/pages.</p>
  <p>I was trying with <code>webpack</code> to dynamically add angular bundles (main.js, polyfill.js etc) in <code>index.ftl</code> file.</p>
  <p>The configuration throws <code>minify error</code> at angular build (<code>ng build --prod</code>) but I see js files are added in index.ftl as scripts.</p>
  <p>Can anyone please help understand the issue and how to resolve it so that my angular bundle are fully loaded in index.ftl file without any errors.</p>
  <p>Below is the error</p>
  <pre><code>Html Webpack Plugin:
  &lt;pre&gt;
    Error: html-webpack-plugin could not minify the generated output.
    In production mode the html minifcation is enabled by default.
    If you are not generating a valid html output please disable it manually.
    You can do so by adding the following setting to your HtmlWebpackPlugin config:
    |
    |    minify: false
    |
    See https://github.com/jantimon/html-webpack-plugin#options for details.
    For parser dedicated bugs please create an issue here:
    https://danielruf.github.io/html-minifier-terser/
    Parse Error: &lt;#macro main&gt; 
        &lt;app-root&gt;&lt;/app-root&gt; 
    &lt;#macro&gt; 
    &lt;#maro pagebody&gt; 
    &lt;#macro&gt;&lt;script src=&quot;angular-ui/runtime.689a94f98876eea3f04c.js&quot;&gt;&lt;/script&gt;&lt;script src=&quot;angular-ui/polyfills.94daefd414b8355106ab.js&quot;&gt;&lt;/script&gt;&lt;script src=&quot;angular-ui/main.95a9937db670e12d53ac.js&quot;&gt;&lt;/script&gt;
    
    - htmlparser.js:244 new HTMLParser
      [angular-webpack]/[html-minifier-terser]/src/htmlparser.js:244:13
    
    - htmlminifier.js:993 minify
      [angular-webpack]/[html-minifier-terser]/src/htmlminifier.js:993:3
    
    - htmlminifier.js:1354 Object.exports.minify
      [angular-webpack]/[html-minifier-terser]/src/htmlminifier.js:1354:16
    
    - index.js:1019 HtmlWebpackPlugin.minifyHtml
      [angular-webpack]/[html-webpack-plugin]/index.js:1019:46
    
    - index.js:435 HtmlWebpackPlugin.postProcessHtml
      [angular-webpack]/[html-webpack-plugin]/index.js:435:40
    
    - index.js:260 
      [angular-webpack]/[html-webpack-plugin]/index.js:260:25
    
    - task_queues:96 processTicksAndRejections
      node:internal/process/task_queues:96:5
    
  &lt;/pre&gt;
  </code></pre>
  <p>webpack.config.js</p>
  <pre class="lang-js prettyprint-override"><code>const HtmlWebpackPlugin = require('html-webpack-plugin');
  const fs = require('fs');
  const path = require('path');
  
  module.exports = {
    output: {
      &quot;publicPath&quot;: &quot;angular-ui/&quot;
    },
  
    plugins: [
      new HtmlWebpackPlugin({
          &quot;template&quot;: &quot;./src/index.ftl&quot;,
          &quot;filename&quot;: &quot;../backend/src/main/webapp/WEB-INF/templates/index.ftl&quot;,
          &quot;inject&quot;: false,
          &quot;hash&quot;: true,
          &quot;xhtml&quot;: true,
      }),
      {
        apply: (compile) =&gt; {
          compile.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) =&gt; {
            fs.unlink(path.join(process.cwd(), &quot;../backend/src/main/webapp/angular-ui/index.html&quot;), (error) =&gt; {
              if (error) throw error;
            });
          });
        }
      }
    ]
  }
  </code></pre>
  <p>index.ftl</p>
  <pre class="lang-html prettyprint-override"><code>&lt;#macro main&gt;
      &lt;app-root&gt;&lt;/app-root&gt;
  &lt;#macro&gt;
  &lt;#maro pagebody&gt;
  &lt;% for (key in htmlWebpackPlugin.files.chunks) { %&gt;
      &lt;% if (htmlWebpackPlugin.files.chunks[key].entry) { %&gt;
          &lt;script src=&quot;&lt;@spring.url '/&lt;%= htmlWebpackPlugin.files.chunks[key].entry %&gt;'/&gt;&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
      &lt;% } %&gt;
  &lt;% } %&gt;
  &lt;#macro&gt;
  &lt;@header&gt;
  </code></pre>
  <p>index.html</p>
  <pre class="lang-html prettyprint-override"><code>&lt;!doctype html&gt;
  &lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;title&gt;AngularUI&lt;/title&gt;
    &lt;base href=&quot;/&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
    &lt;link rel=&quot;icon&quot; type=&quot;image/x-icon&quot; href=&quot;favicon.ico&quot;&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;app-root&gt;&lt;/app-root&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>package.json</p>
  <pre class="lang-json prettyprint-override"><code>{
    &quot;name&quot;: &quot;angular-ui&quot;,
    &quot;version&quot;: &quot;0.0.0&quot;,
    &quot;scripts&quot;: {
      &quot;ng&quot;: &quot;ng&quot;,
      &quot;start&quot;: &quot;ng serve --open&quot;,
      &quot;build&quot;: &quot;ng build --prod&quot;,
      &quot;test&quot;: &quot;ng test&quot;,
      &quot;lint&quot;: &quot;ng lint&quot;,
      &quot;e2e&quot;: &quot;ng e2e&quot;
    },
    &quot;private&quot;: true,
    &quot;dependencies&quot;: {
      &quot;@angular/animations&quot;: &quot;~11.2.14&quot;,
      &quot;@angular/common&quot;: &quot;~11.2.14&quot;,
      &quot;@angular/compiler&quot;: &quot;~11.2.14&quot;,
      &quot;@angular/core&quot;: &quot;~11.2.14&quot;,
      &quot;@angular/forms&quot;: &quot;~11.2.14&quot;,
      &quot;@angular/platform-browser&quot;: &quot;~11.2.14&quot;,
      &quot;@angular/platform-browser-dynamic&quot;: &quot;~11.2.14&quot;,
      &quot;@angular/router&quot;: &quot;~11.2.14&quot;,
      &quot;rxjs&quot;: &quot;~6.6.0&quot;,
      &quot;tslib&quot;: &quot;^2.0.0&quot;,
      &quot;zone.js&quot;: &quot;~0.11.3&quot;
    },
    &quot;devDependencies&quot;: {
      &quot;@angular-builders/custom-webpack&quot;: &quot;^11.1.1&quot;,
      &quot;@angular-devkit/build-angular&quot;: &quot;~0.1102.17&quot;,
      &quot;@angular/cli&quot;: &quot;~11.2.17&quot;,
      &quot;@angular/compiler-cli&quot;: &quot;~11.2.14&quot;,
      &quot;@types/jasmine&quot;: &quot;~3.6.0&quot;,
      &quot;@types/node&quot;: &quot;^12.11.1&quot;,
      &quot;codelyzer&quot;: &quot;^6.0.0&quot;,
      &quot;html-webpack-plugin&quot;: &quot;^4.5.2&quot;,
      &quot;jasmine-core&quot;: &quot;~3.6.0&quot;,
      &quot;jasmine-spec-reporter&quot;: &quot;~5.0.0&quot;,
      &quot;karma&quot;: &quot;~6.1.0&quot;,
      &quot;karma-chrome-launcher&quot;: &quot;~3.1.0&quot;,
      &quot;karma-coverage&quot;: &quot;~2.0.3&quot;,
      &quot;karma-jasmine&quot;: &quot;~4.0.0&quot;,
      &quot;karma-jasmine-html-reporter&quot;: &quot;~1.5.0&quot;,
      &quot;protractor&quot;: &quot;~7.0.0&quot;,
      &quot;ts-node&quot;: &quot;~8.3.0&quot;,
      &quot;tslint&quot;: &quot;~6.1.0&quot;,
      &quot;typescript&quot;: &quot;~4.1.5&quot;
    }
  }
  
  </code></pre>
  <p>angular.json</p>
  <pre class="lang-json prettyprint-override"><code>{
    &quot;$schema&quot;: &quot;./node_modules/@angular/cli/lib/config/schema.json&quot;,
    &quot;version&quot;: 1,
    &quot;newProjectRoot&quot;: &quot;projects&quot;,
    &quot;projects&quot;: {
      &quot;angular-ui&quot;: {
        &quot;projectType&quot;: &quot;application&quot;,
        &quot;schematics&quot;: {
          &quot;@schematics/angular:application&quot;: {
            &quot;strict&quot;: true
          }
        },
        &quot;root&quot;: &quot;&quot;,
        &quot;sourceRoot&quot;: &quot;src&quot;,
        &quot;prefix&quot;: &quot;app&quot;,
        &quot;architect&quot;: {
          &quot;build&quot;: {
            &quot;builder&quot;: &quot;@angular-builders/custom-webpack:browser&quot;,
            &quot;options&quot;: {
              &quot;customWebpackConfig&quot;: {
                &quot;path&quot;: &quot;./webpack.config.js&quot;
              },
              &quot;outputPath&quot;: &quot;../backend/src/main/webapp/angular-ui&quot;,
              &quot;index&quot;: &quot;src/index.html&quot;,
              &quot;main&quot;: &quot;src/main.ts&quot;,
              &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
              &quot;tsConfig&quot;: &quot;tsconfig.app.json&quot;,
              &quot;aot&quot;: true,
              &quot;assets&quot;: [
                &quot;src/favicon.ico&quot;,
                &quot;src/assets&quot;
              ],
              &quot;styles&quot;: [
                &quot;src/styles.css&quot;
              ],
              &quot;scripts&quot;: []
            },
            &quot;configurations&quot;: {
              &quot;production&quot;: {
                &quot;fileReplacements&quot;: [
                  {
                    &quot;replace&quot;: &quot;src/environments/environment.ts&quot;,
                    &quot;with&quot;: &quot;src/environments/environment.prod.ts&quot;
                  }
                ],
                &quot;optimization&quot;: true,
                &quot;outputHashing&quot;: &quot;all&quot;,
                &quot;sourceMap&quot;: false,
                &quot;namedChunks&quot;: false,
                &quot;extractLicenses&quot;: true,
                &quot;vendorChunk&quot;: false,
                &quot;buildOptimizer&quot;: true,
                &quot;budgets&quot;: [
                  {
                    &quot;type&quot;: &quot;initial&quot;,
                    &quot;maximumWarning&quot;: &quot;500kb&quot;,
                    &quot;maximumError&quot;: &quot;1mb&quot;
                  },
                  {
                    &quot;type&quot;: &quot;anyComponentStyle&quot;,
                    &quot;maximumWarning&quot;: &quot;2kb&quot;,
                    &quot;maximumError&quot;: &quot;4kb&quot;
                  }
                ]
              }
            }
          },
          &quot;serve&quot;: {
            &quot;builder&quot;: &quot;@angular-devkit/build-angular:dev-server&quot;,
            &quot;options&quot;: {
              &quot;browserTarget&quot;: &quot;angular-ui:build&quot;
            },
            &quot;configurations&quot;: {
              &quot;production&quot;: {
                &quot;browserTarget&quot;: &quot;angular-ui:build:production&quot;
              }
            }
          },
          &quot;extract-i18n&quot;: {
            &quot;builder&quot;: &quot;@angular-devkit/build-angular:extract-i18n&quot;,
            &quot;options&quot;: {
              &quot;browserTarget&quot;: &quot;angular-ui:build&quot;
            }
          },
          &quot;test&quot;: {
            &quot;builder&quot;: &quot;@angular-devkit/build-angular:karma&quot;,
            &quot;options&quot;: {
              &quot;main&quot;: &quot;src/test.ts&quot;,
              &quot;polyfills&quot;: &quot;src/polyfills.ts&quot;,
              &quot;tsConfig&quot;: &quot;tsconfig.spec.json&quot;,
              &quot;karmaConfig&quot;: &quot;karma.conf.js&quot;,
              &quot;assets&quot;: [
                &quot;src/favicon.ico&quot;,
                &quot;src/assets&quot;
              ],
              &quot;styles&quot;: [
                &quot;src/styles.css&quot;
              ],
              &quot;scripts&quot;: []
            }
          },
          &quot;lint&quot;: {
            &quot;builder&quot;: &quot;@angular-devkit/build-angular:tslint&quot;,
            &quot;options&quot;: {
              &quot;tsConfig&quot;: [
                &quot;tsconfig.app.json&quot;,
                &quot;tsconfig.spec.json&quot;,
                &quot;e2e/tsconfig.json&quot;
              ],
              &quot;exclude&quot;: [
                &quot;**/node_modules/**&quot;
              ]
            }
          },
          &quot;e2e&quot;: {
            &quot;builder&quot;: &quot;@angular-devkit/build-angular:protractor&quot;,
            &quot;options&quot;: {
              &quot;protractorConfig&quot;: &quot;e2e/protractor.conf.js&quot;,
              &quot;devServerTarget&quot;: &quot;angular-ui:serve&quot;
            },
            &quot;configurations&quot;: {
              &quot;production&quot;: {
                &quot;devServerTarget&quot;: &quot;angular-ui:serve:production&quot;
              }
            }
          }
        }
      }
    },
    &quot;defaultProject&quot;: &quot;angular-ui&quot;
  }
  
  </code></pre>