html-webpack-plugin: Wrong chunks order also with chunksSortMode: 'none'

I want to create two html pages based on ejs templates, injecting chunks into the body tag.

Pages are created and everything seems to be ok, but the order of chunks is wrong.

If I use chunksSortMode:‘auto’ for both files -> the first is ok (polyfills->vendor->app), but the second one no (admin->polyfills->vendor)

If I use chunksSortMode:‘none’ for both files -> both of them are wrong. The first one is (vendor->app->polyfills), the second one (vendor->admin->polyfills)

For the first file (with app) I can use ‘auto’, but for the second one, I’m obliged to create a crazy-custom-order function [p…-v…-a… (not alphabetical order)] (that i don’t want to post here, because it’s something the no one should see 😦 ).

new HtmlWebpackPlugin({
      title: TITLE,
      inject: true,
      chunksSortMode: 'auto', //ok only with auto
      chunks: ['polyfills', 'vendor', 'app'],
      template: TEMPLATE_PATH,
      filename: TEMPLATE_HTML
    }),
    new HtmlWebpackPlugin({
      title: TITLE_ADMIN,
      inject: true,
      chunksSortMode: 'none' //wrong with every value -> I'm using a crazy order function (very bad)
      chunks: ['polyfills', 'vendor', 'admin'],
      template: TEMPLATE_ADMIN_PATH,
      filename: TEMPLATE_ADMIN_HTML
    }),

The expected behaviour should be this:

  • chunksSortMode: ‘none’, chunks: [‘polyfills’, ‘vendor’, ‘admin’]
<body> ....polyfills... ....vendor... ....admin... </body> - chunksSortMode: 'none', chunks: ['polyfills', 'vendor', 'app'] <body> ....polyfills... ....vendor... ....app... </body>

Every other behaviour with chunksSortMode: ‘none’ it is weird.

PS: I created my chunks in this way (probably, the cause of this issue is here…I really don’t know):

entry: {
    polyfills: './src/polyfills.ts',
    vendor: './src/vendor.ts',
    app: './src/main.ts',
    admin: './src/admin.ts'
  },
........
new CommonsChunkPlugin({
      name: ['admin', 'app', 'vendor', 'polyfills'],
      minChunks: Infinity
    }),

I used: Nodejs 7.0.0, macOS Sierra, Webpack 2.1.0 beta 25, HtmlWebpackPlugin: 2.24.1

Thank u, Ks89

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 13
  • Comments: 40 (10 by maintainers)

Most upvoted comments

I did something like this to customize my chunk ordering. Basically, it will order the chunk the way you put the chunks in the array.

chunksSortMode: function (chunk1, chunk2) {
  var orders = ['manifest', 'style', 'vendor', 'app'];
  var order1 = orders.indexOf(chunk1.names[0]);
  var order2 = orders.indexOf(chunk2.names[0]);
  if (order1 > order2) {
    return 1;
  } else if (order1 < order2) {
    return -1;
  } else {
    return 0;
  }
}

Would it make sense to add a new options (e.g. called manual) that would keep the order exactly as defined in chunks array?

In case you rather to set the order manually instead of creating a function and as per html-webpack-plugin 2.30.1 version. Setting chunksSortMode to ‘manual’ loads the chunks in the same order than in the chunks option.

// The following code will include vendor and app chunks in that particular order.
chunks: ['vendor', 'app'],
chunksSortMode: 'manual',

I used chunksSortMode with custom function and it worked for me as a trick (alphabetical order)

chunks: ['vendor', 'polyfills', 'admin'],
chunksSortMode: function(a, b) {
   return (a.names[0] < b.names[0])? 1 : -1;
}

Thanks to @jamesjieye

      chunksSortMode: function (chunk1, chunk2) {
        var orders = ['vendor', 'app'];
        var order1 = orders.indexOf(chunk1.names[0]);
        var order2 = orders.indexOf(chunk2.names[0]);

        return order1 - order2;
      }

ugly but works. i spent awhile trying to figure out raw-loader only worked once in awhile.

Tks @jamesjieye && @anthonyettinger, these are my settings for define resource sorting:

new HtmlWebpackPlugin({
    title: 'App Name',
    minify: {
        collapseWhitespace: true,
        keepClosingSlash: true,
        removeComments: true
    },
    chunksSortMode: (c1, c2) => {
        // Corrige bug da ordenação de assets.
        let orders = ['common', 'vendor', 'app'];
        let o1 = orders.indexOf(c1.names[0]);
        let o2 = orders.indexOf(c2.names[0]);
        return o1 - o2;
    },
    filename: '../index.html',
    favicon: './src/assets/images/favicon.ico',
    template: './src/assets/index.ejs'
})

Released 2.30.0

yes! a sensible default ordering should be the array order.

An option to define the chunk order manually would be really great! +1

One more way to do this:

const entryMap = [
    ["polyfills", path.join(root, "src", "polyfills.ts")],
    ["vendor", path.join(root, "src", "vendor.ts")],
    ["app", path.join(root, "src", "index.ts")],
];
const entry = Object.assign({}, 
    ...entryMap.map(([key, value]) => ({[key]: value})));
const chunkSorter = (a, b) => {
    const order = Object.assign({}, 
        ...entryMap.map(([key, value], index) => ({[key]: index})));
    return order[a.names[0]] - order[b.names[0]];
}

module.exports = {
    entry,
    ...
    plugins: [
        new HtmlWebpackPlugin({
            filename: "index.html",
            template: path.join(root, "src", "index.ejs"),
            chunksSortMode: chunkSorter,
        }),
    ]
    ...
}

Only real difference here is that the order is defined in the same place as the sorter, so you can’t forget to update both locations when you add a new chunk…

@jamesjieye’s custom function above works very nicely. If we step back and look at the root issue, I’m thinking the better solution is to design webpack such that the entry property can accept either an object or an array. The fact that we have to cobble together something to control order seems kind of silly to me.

Finally, I created a skeleton project, as promised: https://github.com/Ks89/Angular2-webpack2-skeleton

Branches:

  • master (custom function based on @jamesjieye solution) -> working
  • chunckSortMode-auto -> broken (I’m sorry for the typo in the branch name 😃 )
  • chunksSortMode-dependency -> broken
  • chunksSortMode-none -> broken

run npm run buildDev and check ./dist/admin.html to see if the order is ok or not.

This can only be a simple choice if it is positive or reverse. Read the source to find in the function and then called the sort function, not too friendly, has been feedback

I am also facing the same issue, and described the problem in details here.