diff --git a/index.js b/index.js index e758843..df2fbef 100644 --- a/index.js +++ b/index.js @@ -281,17 +281,11 @@ HtmlWebpackPlugin.prototype.addFileToAssets = function (filename, compilation) { HtmlWebpackPlugin.prototype.sortChunks = function (chunks, sortMode) { // Sort mode auto by default: if (typeof sortMode === 'undefined' || sortMode === 'auto') { - return chunks.sort(function orderEntryLast (a, b) { - if (a.entry !== b.entry) { - return b.entry ? 1 : -1; - } else { - return b.id - a.id; - } - }); + return chunkSorter.auto(chunks); } // Sort mode 'dependency': if (sortMode === 'dependency') { - var sortResult = chunkSorter().sortChunksByDependencies(chunks); + var sortResult = chunkSorter.dependency(chunks); if (!sortResult) { throw new Error('Chunk sorting based on dependencies failed. Please consider custom sort mode.'); @@ -301,7 +295,7 @@ HtmlWebpackPlugin.prototype.sortChunks = function (chunks, sortMode) { } // Disabled sorting: if (sortMode === 'none') { - return chunks; + return chunkSorter.none(chunks); } // Custom function if (typeof sortMode === 'function') { diff --git a/lib/chunksorter.js b/lib/chunksorter.js index 220f0f5..0ef52d2 100644 --- a/lib/chunksorter.js +++ b/lib/chunksorter.js @@ -1,72 +1,96 @@ -/* -This module sorts chunks based on their dependencies with each other. -The parent relation between chunks as generated by Webpack for each chunk -is used to define a directed (and hopefully acyclic) graph, which is then -topologically sorted in order to retrieve the correct order in which -chunks need to be embedded into HTML. A directed edge in this graph is -describing a "is parent of" relationship from a chunk to another (distinct) -chunk. Thus topological sorting orders chunks from bottom-layer chunks to -highest level chunks that use the lower-level chunks. -*/ 'use strict'; var toposort = require('toposort'); -module.exports = function () { - /* - Sorts dependencies between chunks by their "parents" attribute. - @param chunks an array of chunks as generated by the html-webpack-plugin. - It is assumed that each entry contains at least the properties "id" - (containing the chunk id) and "parents" (array containing the ids of the - parent chunks). Must not be null/undefined or empty +/* + Sorts dependencies between chunks by their "parents" attribute. - @return A topologically sorted version of the input chunks, or null if - no such order could be calculated (e.g. because the chunks and their - parent relations did not define an directed acyclic graph). - */ - function sortChunksByDependencies (chunks) { - if (!chunks) { - return null; - } + This function sorts chunks based on their dependencies with each other. + The parent relation between chunks as generated by Webpack for each chunk + is used to define a directed (and hopefully acyclic) graph, which is then + topologically sorted in order to retrieve the correct order in which + chunks need to be embedded into HTML. A directed edge in this graph is + describing a "is parent of" relationship from a chunk to another (distinct) + chunk. Thus topological sorting orders chunks from bottom-layer chunks to + highest level chunks that use the lower-level chunks. - // We build a map (chunk-id -> chunk) for faster access during graph building. - var nodeMap = []; + @param {Array} chunks an array of chunks as generated by the html-webpack-plugin. + It is assumed that each entry contains at least the properties "id" + (containing the chunk id) and "parents" (array containing the ids of the + parent chunks). Must not be null/undefined or empty - chunks.forEach(function (chunk) { - nodeMap[chunk.id] = chunk; - }); - - // Next, we add an edge for each parent relationship into the graph - var edges = []; - - chunks.forEach(function (chunk) { - if (chunk.parents) { - // Add an edge for each parent (parent -> child) - chunk.parents.forEach(function (parentId) { - var parentChunk = nodeMap[parentId]; - - if (!parentChunk) { - return null; // We haven't found the referenced chunk in our map! - } - - edges.push([parentChunk, chunk]); - }); - } - }); - - // We now perform a topological sorting on the input chunks and built edges - var sortedVertices = null; - - try { - sortedVertices = toposort.array(chunks, edges); - } catch (err) { - return null; // Error during sort - } - - return sortedVertices; + @return {Array} A topologically sorted version of the input chunks, or null if + no such order could be calculated (e.g. because the chunks and their + parent relations did not define an directed acyclic graph). +*/ +module.exports.dependency = function (chunks) { + if (!chunks) { + return null; } - return { - sortChunksByDependencies: sortChunksByDependencies - }; + // We build a map (chunk-id -> chunk) for faster access during graph building. + var nodeMap = []; + + chunks.forEach(function (chunk) { + nodeMap[chunk.id] = chunk; + }); + + // Next, we add an edge for each parent relationship into the graph + var edges = []; + + chunks.forEach(function (chunk) { + if (chunk.parents) { + // Add an edge for each parent (parent -> child) + chunk.parents.forEach(function (parentId) { + var parentChunk = nodeMap[parentId]; + + if (!parentChunk) { + return null; // We haven't found the referenced chunk in our map! + } + + edges.push([parentChunk, chunk]); + }); + } + }); + + // We now perform a topological sorting on the input chunks and built edges + var sortedVertices = null; + + try { + sortedVertices = toposort.array(chunks, edges); + } catch (err) { + return null; // Error during sort + } + + return sortedVertices; }; + +/** + * Sorts the chunks based on the chunk id. + * + * @param {Array} chunks the list of chunks to sort + * @return {Array} The sorted list of chunks + */ +module.exports.id = function (chunks) { + return chunks.sort(function orderEntryLast (a, b) { + if (a.entry !== b.entry) { + return b.entry ? 1 : -1; + } else { + return b.id - a.id; + } + }); +}; + +/** + * Performs identity mapping (no-sort). + * @param {Array} chunks the chunks to sort + * @return {Array} The sorted chunks + */ +module.exports.none = function (chunks) { + return chunks; +}; + +/** + * Defines the default sorter. + */ +module.exports.auto = module.exports.id;