1

I am using HtmlWebpackPlugin to inject javascript into my template file:

<html>
    ...
    <body>
        ...
        <?php echo $this->inlineScript(); ?>
        <script type="text/javascript" src="/dist/vendor.js?a4212b4b10c2d4d2d73e"></script>
    </body>
</html>

However, I need the generated bundle to be injected before the PHP code <?php echo $this->inlineScript(); ?>, to let inline scripts work properly (they require JQuery, which will be loaded inside vendor.js).

Result should be:

<html>
    ...
    <body>
        ...
        <script type="text/javascript" src="/dist/vendor.js?a4212b4b10c2d4d2d73e"></script>
        <?php echo $this->inlineScript(); ?>
    </body>
</html>

Is there a way to achieve this? Maybe it is possible to use a placeholder like <%= htmlWebpackPlugin.options.??? %> or something similar? If it does not work with HtmlWebpackPlugin, is there another webpack plugin I can use?

koseduhemak
  • 523
  • 2
  • 4
  • 19

3 Answers3

11

Ok I figured it out. Put the following code where you want to include your js files:

<% for(var i=0; i < htmlWebpackPlugin.files.js.length; i++) {%>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.files.js[i] %>"></script>
<% } %>

and set inject in HtmlWebpackPlugin options to false.

Keep in mind that you need to inject other stuff (css, meta tags, etc.) by hand, too. F.e. CSS:

<% for(var i=0; i < htmlWebpackPlugin.files.css.length; i++) {%>
    <link type="text/css" rel="stylesheet" href="<%= htmlWebpackPlugin.files.css[i] %>">
<% } %>
koseduhemak
  • 523
  • 2
  • 4
  • 19
  • 1
    You can also use `htmlWebpackPlugin.tags.headTags` and `htmlWebpackPlugin.tags.bodyTags`, see [example](https://github.com/jantimon/html-webpack-plugin/tree/main/examples/custom-insertion-position#custom-insertion-example) – Joe Van Leeuwen Oct 13 '21 at 19:53
0

To fix this problem I did the following:

(1) install the HtmlWebpackPlugin (https://www.npmjs.com/package/html-webpack-plugin)

npm i html-webpack-plugin

(2) update my webpack config

module.exports = {
// ...
plugins: [
    // ...
    new HtmlWebpackPlugin({
        template: 'template.html',
        filename: 'file.html',
        inject: false,
        minify: false,
        templateParameters: (compilation, assets) => {
            const css = assets.css.map((filePath) => `<link rel="stylesheet" href="${filePath}" />`).join("\n");
            const js = assets.js.map((filePath) => `<script src="${filePath}"></script>`).join("\n");
            return { css, js };
        },
    }),
  
    }),
    // ...
],};

(3) add these tags within my template. This will tell webpack where to place the CSS and JS files.

 <!-- Webpack CSS -->
<%= css %>

<!-- Webpack JS -->
<%= js %>
Sim
  • 91
  • 1
  • 2
-1

Not sure if I am too late, but you can use script-ext-html-webpack-plugin. This can set the script as defer which can defer the execution until the DOM is parsed. Additionally you can inject this script in head of html to start fetching it in parallel but executing at the end :

plugins: [
  new HtmlWebpackPlugin({ template: 'template.ejs', inject: 'head'}),
  new ScriptExtHtmlWebpackPlugin({ defaultAttribute: 'defer' }),
]
Easwar
  • 5,132
  • 1
  • 11
  • 21