How to specify where to inject chunks in html template with vue-cli?
Asked Answered
C

3

6

I am using vue-cli generated project and specified pages in vue.config.js. Vue is automatically injecting the JS chunks at the end of the HTML template file. But in I need to specify a different location to place them in that file.

Standard Webpack syntax does not really help (<%= htmlWebpackPlugin ...). It actually injects the chunks there, but then the chunks are again inserted at the end of the page anyway.

Is there a correct way, how specify exact place in HTML file for building with vue-cli, instead of the default end of the file (or before which does not exist in my template)?

Template (IndexTemplate.cshtml)

...

<scripts-section>
    <% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
    <script src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script><% } %>

</scripts-section>

Generated File (Index.cshtml)

...

<scripts-section>
    <script src="/dist/vue/runtime.js"></script>
    <script src="/dist/vue/sentry.vendor.js"></script>
    <script src="/dist/vue/axios.vendor.js"></script>
    <script src="/dist/vue/vue.vendor.js"></script>
    <script src="/dist/vue/vendors~Search.js"></script>
    <script src="/dist/vue/Search.js"></script>

</scripts-section>

<script type="text/javascript" src="/dist/vue/runtime.js"></script><script type="text/javascript" src="/dist/vue/sentry.vendor.js"></script><script type="text/javascript" src="/dist/vue/axios.vendor.js"></script><script type="text/javascript" src="/dist/vue/vue.vendor.js"></script><script type="text/javascript" src="/dist/vue/vendors~Search.js"></script><script type="text/javascript" src="/dist/vue/Search.js"></script>

As you can see, it gets inserted twice. Having it at the end of the file is not an option here.

vue.config.js

module.exports = {
    publicPath: '/dist/vue/',
    outputDir: './wwwroot/dist/vue/',
    runtimeCompiler: true,
    pages: {
        Search: {
            entry: 'Frontend/vue/Search/main.ts',
            template: 'Views/Mentors/IndexTemplate.cshtml',
            filename: '../../../Views/Mentors/Index.cshtml',
            chunks: ['runtime', 'vue.vendor', 'axios.vendor', 'sentry.vendor', 'Search', 'vendors~Search']
        }
    },
    chainWebpack: config => {
        config.optimization
            .runtimeChunk('single')
            .splitChunks({
                chunks: 'all',
                cacheGroups: {
                    vue: {
                        test: /[\\/]node_modules[\\/](.*vue.*)[\\/]/,
                        name: 'vue.vendor',
                        chunks: 'all',
                    },
                    // ...
                }
            });
    }
}

I expect, that the JS chunks would be injected only in the <scripts-section> element.

Crag answered 26/5, 2019 at 0:14 Comment(0)
O
3

For future reference of others:

In the vue.config.js file, we also have to add the config for html plugin, and set inject to false:

config.plugin("html").tap((args) => {
  args[0].inject = false;
  return args;
});

The complete edited version of the vue.config.js is given below for clarity:

module.exports = {
  publicPath: "/dist/vue/",
  outputDir: "./wwwroot/dist/vue/",
  runtimeCompiler: true,
  pages: {
    Search: {
      entry: "Frontend/vue/Search/main.ts",
      template: "Views/Mentors/IndexTemplate.cshtml",
      filename: "../../../Views/Mentors/Index.cshtml",
      chunks: ["runtime", "vue.vendor", "axios.vendor", "sentry.vendor", "Search", "vendors~Search"],
    },
  },
  chainWebpack: (config) => {
    config.optimization.runtimeChunk("single").splitChunks({
      chunks: "all",
      cacheGroups: {
        vue: {
          test: /[\\/]node_modules[\\/](.*vue.*)[\\/]/,
          name: "vue.vendor",
          chunks: "all",
        },
        // ...
      },
    });
    config.plugin("html").tap((args) => {
      args[0].inject = false;
      return args;
    });
  },
};

For a more detailed example, visit this link.

Oneida answered 29/4, 2021 at 13:22 Comment(0)
D
0

You can delete the thunks at injection time by tapping into the html plugin and remove any chunks you don't want to appear at the bottom:

config.plugin('html').tap((args) => {
  args[0].excludeChunks = ['app', 'runtime', 'chunk-vendors']

  return args
})

Just keep appending to the array for each and every chunk you wish to omit from the bottom from there.

Desmund answered 17/4, 2020 at 23:33 Comment(0)
S
0

Rather than:

<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"</script>
<% } %>

I had success using:

<%= htmlWebpackPlugin.tags.headTags %>

As well as the corresponding 'bodyTags'.

It's, perhaps, not quite the same thing, but it might provide someone else some help.

Ssr answered 4/3, 2022 at 15:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.