73 lines
2.3 KiB
JavaScript
73 lines
2.3 KiB
JavaScript
/*
|
|
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
|
|
|
|
@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;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
return {
|
|
sortChunksByDependencies: sortChunksByDependencies
|
|
};
|
|
};
|