mirror of https://github.com/webpack/webpack.git
Merge pull request #8468 from webpack/feature/chunk-root-modules
add algorithm to extract graph roots
This commit is contained in:
commit
a20f621263
|
|
@ -1267,6 +1267,10 @@ export interface StatsOptions {
|
||||||
* add the origins of chunks and chunk merging info
|
* add the origins of chunks and chunk merging info
|
||||||
*/
|
*/
|
||||||
chunkOrigins?: boolean;
|
chunkOrigins?: boolean;
|
||||||
|
/**
|
||||||
|
* add root modules information to chunk information
|
||||||
|
*/
|
||||||
|
chunkRootModules?: boolean;
|
||||||
/**
|
/**
|
||||||
* add chunk information
|
* add chunk information
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ const {
|
||||||
compareSelect,
|
compareSelect,
|
||||||
compareIds
|
compareIds
|
||||||
} = require("./util/comparators");
|
} = require("./util/comparators");
|
||||||
|
const findGraphRoots = require("./util/findGraphRoots");
|
||||||
|
|
||||||
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
|
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
|
||||||
/** @typedef {import("./Chunk")} Chunk */
|
/** @typedef {import("./Chunk")} Chunk */
|
||||||
|
|
@ -155,6 +156,8 @@ class ChunkGraph {
|
||||||
this._blockChunkGroups = new WeakMap();
|
this._blockChunkGroups = new WeakMap();
|
||||||
/** @private @type {ModuleGraph} */
|
/** @private @type {ModuleGraph} */
|
||||||
this.moduleGraph = moduleGraph;
|
this.moduleGraph = moduleGraph;
|
||||||
|
|
||||||
|
this._getGraphRoots = this._getGraphRoots.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -185,6 +188,25 @@ class ChunkGraph {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SortableSet<Module>} set the sortable Set to get the roots of
|
||||||
|
* @returns {Module[]} the graph roots
|
||||||
|
*/
|
||||||
|
_getGraphRoots(set) {
|
||||||
|
const { moduleGraph } = this;
|
||||||
|
return Array.from(
|
||||||
|
findGraphRoots(set, module => {
|
||||||
|
return moduleGraph
|
||||||
|
.getOutgoingConnections(module)
|
||||||
|
.reduce((arr, connection) => {
|
||||||
|
const module = connection.module;
|
||||||
|
if (module) arr.push(module);
|
||||||
|
return arr;
|
||||||
|
}, []);
|
||||||
|
})
|
||||||
|
).sort(compareModulesByIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Chunk} chunk the new chunk
|
* @param {Chunk} chunk the new chunk
|
||||||
* @param {Module} module the module
|
* @param {Module} module the module
|
||||||
|
|
@ -534,6 +556,15 @@ class ChunkGraph {
|
||||||
return cgc.modules.getFromUnorderedCache(getModulesSizes);
|
return cgc.modules.getFromUnorderedCache(getModulesSizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Chunk} chunk the chunk
|
||||||
|
* @returns {Module[]} root modules of the chunks (ordered by identifer)
|
||||||
|
*/
|
||||||
|
getChunkRootModules(chunk) {
|
||||||
|
const cgc = this._getChunkGraphChunk(chunk);
|
||||||
|
return cgc.modules.getFromUnorderedCache(this._getGraphRoots);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Chunk} chunk the chunk
|
* @param {Chunk} chunk the chunk
|
||||||
* @param {ChunkSizeOptions} options options object
|
* @param {ChunkSizeOptions} options options object
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ class ModuleGraph {
|
||||||
* @param {Module} module the module
|
* @param {Module} module the module
|
||||||
* @returns {ModuleGraphConnection[]} list of outgoing connections
|
* @returns {ModuleGraphConnection[]} list of outgoing connections
|
||||||
*/
|
*/
|
||||||
getOutgoingConnection(module) {
|
getOutgoingConnections(module) {
|
||||||
const connections = this._getModuleGraphModule(module).outgoingConnections;
|
const connections = this._getModuleGraphModule(module).outgoingConnections;
|
||||||
return Array.from(connections);
|
return Array.from(connections);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
93
lib/Stats.js
93
lib/Stats.js
|
|
@ -170,7 +170,14 @@ class Stats {
|
||||||
!forToString
|
!forToString
|
||||||
);
|
);
|
||||||
const showChunks = optionOrLocalFallback(options.chunks, !forToString);
|
const showChunks = optionOrLocalFallback(options.chunks, !forToString);
|
||||||
const showChunkModules = optionOrLocalFallback(options.chunkModules, true);
|
const showChunkModules = optionOrLocalFallback(
|
||||||
|
options.chunkModules,
|
||||||
|
!forToString
|
||||||
|
);
|
||||||
|
const showChunkRootModules = optionOrLocalFallback(
|
||||||
|
options.chunkRootModules,
|
||||||
|
forToString ? !showChunkModules : true
|
||||||
|
);
|
||||||
const showChunkOrigins = optionOrLocalFallback(
|
const showChunkOrigins = optionOrLocalFallback(
|
||||||
options.chunkOrigins,
|
options.chunkOrigins,
|
||||||
!forToString
|
!forToString
|
||||||
|
|
@ -178,7 +185,7 @@ class Stats {
|
||||||
const showModules = optionOrLocalFallback(options.modules, true);
|
const showModules = optionOrLocalFallback(options.modules, true);
|
||||||
const showNestedModules = optionOrLocalFallback(
|
const showNestedModules = optionOrLocalFallback(
|
||||||
options.nestedModules,
|
options.nestedModules,
|
||||||
true
|
!forToString
|
||||||
);
|
);
|
||||||
const showOrphanModules = optionOrLocalFallback(
|
const showOrphanModules = optionOrLocalFallback(
|
||||||
options.orphanModules,
|
options.orphanModules,
|
||||||
|
|
@ -793,6 +800,25 @@ class Stats {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (showChunkRootModules) {
|
||||||
|
const rootModules = chunkGraph.getChunkRootModules(chunk);
|
||||||
|
obj.rootModules = rootModules
|
||||||
|
.slice()
|
||||||
|
.sort(sortRealModules)
|
||||||
|
.filter(createModuleFilter("root-of-chunk"))
|
||||||
|
.map(m => fnModule(m));
|
||||||
|
obj.filteredRootModules = rootModules.length - obj.rootModules.length;
|
||||||
|
obj.nonRootModules =
|
||||||
|
chunkGraph.getNumberOfChunkModules(chunk) - rootModules.length;
|
||||||
|
if (sortModules) {
|
||||||
|
obj.rootModules.sort(
|
||||||
|
concatComparators(
|
||||||
|
sortByField(sortModules),
|
||||||
|
keepOriginalOrder(obj.rootModules)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (showChunkOrigins) {
|
if (showChunkOrigins) {
|
||||||
const originsKeySet = new Set();
|
const originsKeySet = new Set();
|
||||||
obj.origins = Array.from(chunk.groupsIterable, g => g.origins)
|
obj.origins = Array.from(chunk.groupsIterable, g => g.origins)
|
||||||
|
|
@ -1059,7 +1085,7 @@ class Stats {
|
||||||
color: getAssetColor(asset, colors.normal)
|
color: getAssetColor(asset, colors.normal)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: asset.chunks.join(", "),
|
value: asset.chunks.map(c => `{${c}}`).join(", "),
|
||||||
color: colors.bold
|
color: colors.bold
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1134,21 +1160,6 @@ class Stats {
|
||||||
processChunkGroups(outputChunkGroups, "Chunk Group");
|
processChunkGroups(outputChunkGroups, "Chunk Group");
|
||||||
}
|
}
|
||||||
|
|
||||||
const modulesByIdentifier = {};
|
|
||||||
if (obj.modules) {
|
|
||||||
for (const module of obj.modules) {
|
|
||||||
modulesByIdentifier[`$${module.identifier}`] = module;
|
|
||||||
}
|
|
||||||
} else if (obj.chunks) {
|
|
||||||
for (const chunk of obj.chunks) {
|
|
||||||
if (chunk.modules) {
|
|
||||||
for (const module of chunk.modules) {
|
|
||||||
modulesByIdentifier[`$${module.identifier}`] = module;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const processSizes = sizes => {
|
const processSizes = sizes => {
|
||||||
const keys = Object.keys(sizes);
|
const keys = Object.keys(sizes);
|
||||||
if (keys.length > 1) {
|
if (keys.length > 1) {
|
||||||
|
|
@ -1341,11 +1352,16 @@ class Stats {
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
if (module.modules) {
|
if (module.modules) {
|
||||||
processModulesList(module, prefix + "| ");
|
processModulesList(module, prefix + "| ", "nested module");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const processModulesList = (obj, prefix) => {
|
const processModulesList = (
|
||||||
|
obj,
|
||||||
|
prefix,
|
||||||
|
itemType = "module",
|
||||||
|
dependentItemType = "dependent module"
|
||||||
|
) => {
|
||||||
if (obj.modules) {
|
if (obj.modules) {
|
||||||
let maxModuleId = 0;
|
let maxModuleId = 0;
|
||||||
for (const module of obj.modules) {
|
for (const module of obj.modules) {
|
||||||
|
|
@ -1397,7 +1413,19 @@ class Stats {
|
||||||
if (obj.modules.length > 0) colors.normal(" + ");
|
if (obj.modules.length > 0) colors.normal(" + ");
|
||||||
colors.normal(obj.filteredModules);
|
colors.normal(obj.filteredModules);
|
||||||
if (obj.modules.length > 0) colors.normal(" hidden");
|
if (obj.modules.length > 0) colors.normal(" hidden");
|
||||||
colors.normal(obj.filteredModules !== 1 ? " modules" : " module");
|
colors.normal(` ${itemType}${obj.filteredModules !== 1 ? "s" : ""}`);
|
||||||
|
newline();
|
||||||
|
}
|
||||||
|
if (obj.dependentModules > 0) {
|
||||||
|
const additional = obj.modules.length > 0 || obj.filteredModules > 0;
|
||||||
|
colors.normal(prefix);
|
||||||
|
colors.normal(" ");
|
||||||
|
if (additional) colors.normal(" + ");
|
||||||
|
colors.normal(obj.dependentModules);
|
||||||
|
if (additional) colors.normal(" hidden");
|
||||||
|
colors.normal(
|
||||||
|
` ${dependentItemType}${obj.dependentModules !== 1 ? "s" : ""}`
|
||||||
|
);
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1473,9 +1501,8 @@ class Stats {
|
||||||
colors.normal("[");
|
colors.normal("[");
|
||||||
colors.normal(origin.moduleId);
|
colors.normal(origin.moduleId);
|
||||||
colors.normal("] ");
|
colors.normal("] ");
|
||||||
const module = modulesByIdentifier[`$${origin.module}`];
|
if (origin.moduleName) {
|
||||||
if (module) {
|
colors.bold(origin.moduleName);
|
||||||
colors.bold(module.name);
|
|
||||||
colors.normal(" ");
|
colors.normal(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1485,7 +1512,21 @@ class Stats {
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
processModulesList(chunk, " ");
|
const hasRootModules =
|
||||||
|
chunk.rootModules ||
|
||||||
|
chunk.filteredRootModules ||
|
||||||
|
chunk.nonRootModules;
|
||||||
|
processModulesList(
|
||||||
|
{
|
||||||
|
modules: chunk.rootModules,
|
||||||
|
filteredModules: chunk.filteredRootModules,
|
||||||
|
dependentModules: chunk.nonRootModules
|
||||||
|
},
|
||||||
|
" ",
|
||||||
|
"root module",
|
||||||
|
"dependent module"
|
||||||
|
);
|
||||||
|
processModulesList(chunk, hasRootModules ? " | " : " ", "chunk module");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1552,6 +1593,7 @@ class Stats {
|
||||||
modules: false,
|
modules: false,
|
||||||
chunks: true,
|
chunks: true,
|
||||||
chunkModules: true,
|
chunkModules: true,
|
||||||
|
chunkRootModules: false,
|
||||||
chunkOrigins: true,
|
chunkOrigins: true,
|
||||||
depth: true,
|
depth: true,
|
||||||
env: true,
|
env: true,
|
||||||
|
|
@ -1572,6 +1614,7 @@ class Stats {
|
||||||
chunkGroups: true,
|
chunkGroups: true,
|
||||||
chunks: true,
|
chunks: true,
|
||||||
chunkModules: false,
|
chunkModules: false,
|
||||||
|
chunkRootModules: false,
|
||||||
chunkOrigins: true,
|
chunkOrigins: true,
|
||||||
depth: true,
|
depth: true,
|
||||||
usedExports: true,
|
usedExports: true,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Tobias Koppers @sokra
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const NO_MARKER = 0;
|
||||||
|
const IN_PROGRESS_MARKER = 1;
|
||||||
|
const DONE_MARKER = 2;
|
||||||
|
const DONE_MAYBE_ROOT_CYCLE_MARKER = 3;
|
||||||
|
const DONE_AND_ROOT_MARKER = 4;
|
||||||
|
|
||||||
|
class Node {
|
||||||
|
constructor(item) {
|
||||||
|
this.item = item;
|
||||||
|
this.dependencies = new Set();
|
||||||
|
this.marker = NO_MARKER;
|
||||||
|
this.cycle = undefined;
|
||||||
|
this.incoming = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Cycle {
|
||||||
|
constructor() {
|
||||||
|
this.nodes = new Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} StackEntry
|
||||||
|
* @property {Node} node
|
||||||
|
* @property {Node[]} openEdges
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @param {Iterable<T>} items list of items
|
||||||
|
* @param {function(T): Iterable<T>} getDependencies function to get dependencies of an item (items that are not in list are ignored)
|
||||||
|
* @returns {Iterable<T>} graph roots of the items
|
||||||
|
*/
|
||||||
|
module.exports = (items, getDependencies) => {
|
||||||
|
const itemToNode = new Map();
|
||||||
|
for (const item of items) {
|
||||||
|
const node = new Node(item);
|
||||||
|
itemToNode.set(item, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// early exit when there is only a single item
|
||||||
|
if (itemToNode.size <= 1) return items;
|
||||||
|
|
||||||
|
// grab all the dependencies
|
||||||
|
for (const node of itemToNode.values()) {
|
||||||
|
for (const dep of getDependencies(node.item)) {
|
||||||
|
const depNode = itemToNode.get(dep);
|
||||||
|
if (depNode !== undefined) {
|
||||||
|
node.dependencies.add(depNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set of current root modules
|
||||||
|
// items will be removed if a new reference to it has been found
|
||||||
|
/** @type {Set<Node>} */
|
||||||
|
const roots = new Set();
|
||||||
|
|
||||||
|
// Set of current cycles without references to it
|
||||||
|
// cycles will be removed if a new reference to it has been found
|
||||||
|
// that is not part of the cycle
|
||||||
|
/** @type {Set<Cycle>} */
|
||||||
|
const rootCycles = new Set();
|
||||||
|
|
||||||
|
// For all non-marked nodes
|
||||||
|
for (const selectedNode of itemToNode.values()) {
|
||||||
|
if (selectedNode.marker === NO_MARKER) {
|
||||||
|
// deep-walk all referenced modules
|
||||||
|
// in a non-recursive way
|
||||||
|
|
||||||
|
// start by entering the selected node
|
||||||
|
selectedNode.marker = IN_PROGRESS_MARKER;
|
||||||
|
|
||||||
|
// keep a stack to avoid recursive walk
|
||||||
|
/** @type {StackEntry[]} */
|
||||||
|
const stack = [
|
||||||
|
{
|
||||||
|
node: selectedNode,
|
||||||
|
openEdges: Array.from(selectedNode.dependencies)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// process the top item until stack is empty
|
||||||
|
while (stack.length > 0) {
|
||||||
|
const topOfStack = stack[stack.length - 1];
|
||||||
|
|
||||||
|
// Are there still edges unprocessed in the current node?
|
||||||
|
if (topOfStack.openEdges.length > 0) {
|
||||||
|
// Process one dependency
|
||||||
|
const dependency = topOfStack.openEdges.pop();
|
||||||
|
switch (dependency.marker) {
|
||||||
|
case NO_MARKER:
|
||||||
|
// dependency has not be visited yet
|
||||||
|
// mark it as in-progress and recurse
|
||||||
|
stack.push({
|
||||||
|
node: dependency,
|
||||||
|
openEdges: Array.from(dependency.dependencies)
|
||||||
|
});
|
||||||
|
dependency.marker = IN_PROGRESS_MARKER;
|
||||||
|
break;
|
||||||
|
case IN_PROGRESS_MARKER: {
|
||||||
|
// It's a in-progress cycle
|
||||||
|
let cycle = dependency.cycle;
|
||||||
|
if (!cycle) {
|
||||||
|
cycle = new Cycle();
|
||||||
|
cycle.nodes.add(dependency);
|
||||||
|
dependency.cycle = cycle;
|
||||||
|
}
|
||||||
|
// set cycle property for each node in the cycle
|
||||||
|
// if nodes are already part of a cycle
|
||||||
|
// we merge the cycles to a shared cycle
|
||||||
|
for (
|
||||||
|
let i = stack.length - 1;
|
||||||
|
stack[i].node !== dependency;
|
||||||
|
i--
|
||||||
|
) {
|
||||||
|
const node = stack[i].node;
|
||||||
|
if (node.cycle) {
|
||||||
|
if (node.cycle !== cycle) {
|
||||||
|
// merge cycles
|
||||||
|
for (const cycleNode of node.cycle.nodes) {
|
||||||
|
cycleNode.cycle = cycle;
|
||||||
|
cycle.nodes.add(cycleNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node.cycle = cycle;
|
||||||
|
cycle.nodes.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// don't recurse into dependencies
|
||||||
|
// these are already on the stack
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DONE_AND_ROOT_MARKER:
|
||||||
|
// This node has be visited yet and is currently a root node
|
||||||
|
// But as this is a new reference to the node
|
||||||
|
// it's not really a root
|
||||||
|
// so we have to convert it to a normal node
|
||||||
|
dependency.marker = DONE_MARKER;
|
||||||
|
roots.delete(dependency);
|
||||||
|
break;
|
||||||
|
case DONE_MAYBE_ROOT_CYCLE_MARKER:
|
||||||
|
// This node has be visited yet and
|
||||||
|
// is maybe currently part of a completed root cycle
|
||||||
|
// we found a new reference to the cycle
|
||||||
|
// so it's not really a root cycle
|
||||||
|
// remove the cycle from the root cycles
|
||||||
|
// and convert it to a normal node
|
||||||
|
rootCycles.delete(dependency.cycle);
|
||||||
|
dependency.marker = DONE_MARKER;
|
||||||
|
break;
|
||||||
|
// DONE_MARKER: nothing to do, don't recurse into dependencies
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// All dependencies of the current node has been visited
|
||||||
|
// we leave the node
|
||||||
|
stack.pop();
|
||||||
|
topOfStack.node.marker = DONE_MARKER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const cycle = selectedNode.cycle;
|
||||||
|
if (cycle) {
|
||||||
|
for (const node of cycle.nodes) {
|
||||||
|
node.marker = DONE_MAYBE_ROOT_CYCLE_MARKER;
|
||||||
|
}
|
||||||
|
rootCycles.add(cycle);
|
||||||
|
} else {
|
||||||
|
selectedNode.marker = DONE_AND_ROOT_MARKER;
|
||||||
|
roots.add(selectedNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract roots from root cycles
|
||||||
|
// We take the nodes with most incoming edges
|
||||||
|
// inside of the cycle
|
||||||
|
for (const cycle of rootCycles) {
|
||||||
|
let max = 0;
|
||||||
|
const cycleRoots = new Set();
|
||||||
|
const nodes = cycle.nodes;
|
||||||
|
for (const node of nodes) {
|
||||||
|
for (const dep of node.dependencies) {
|
||||||
|
if (nodes.has(dep)) {
|
||||||
|
dep.incoming++;
|
||||||
|
if (dep.incoming < max) continue;
|
||||||
|
if (dep.incoming > max) {
|
||||||
|
cycleRoots.clear();
|
||||||
|
max = dep.incoming;
|
||||||
|
}
|
||||||
|
cycleRoots.add(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const cycleRoot of cycleRoots) {
|
||||||
|
roots.add(cycleRoot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When roots were found, return them
|
||||||
|
if (roots.size > 0) {
|
||||||
|
return Array.from(roots, r => r.item);
|
||||||
|
} else {
|
||||||
|
throw new Error("Implementation of findGraphRoots is broken");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1745,6 +1745,10 @@
|
||||||
"description": "add the origins of chunks and chunk merging info",
|
"description": "add the origins of chunks and chunk merging info",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"chunkRootModules": {
|
||||||
|
"description": "add root modules information to chunk information",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"chunks": {
|
"chunks": {
|
||||||
"description": "add chunk information",
|
"description": "add chunk information",
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
||||||
|
import "./b";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./c";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./index";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./a";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./b";
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
import "./c";
|
||||||
|
import "./index";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./index";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./a";
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
import "./index";
|
||||||
|
import "./b";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./c";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./index";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./a";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./b";
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
import "./c";
|
||||||
|
import "./index";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./index";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./a";
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import(/* webpackChunkName: "tree" */ "./tree");
|
||||||
|
|
||||||
|
import(/* webpackChunkName: "trees" */ "./trees/1");
|
||||||
|
import(/* webpackChunkName: "trees" */ "./trees/2");
|
||||||
|
import(/* webpackChunkName: "trees" */ "./trees/3");
|
||||||
|
|
||||||
|
import(/* webpackChunkName: "cycle" */ "./cycle");
|
||||||
|
|
||||||
|
import(/* webpackChunkName: "cycle2" */ "./cycle2");
|
||||||
|
|
||||||
|
import(/* webpackChunkName: "cycles" */ "./cycles/1");
|
||||||
|
import(/* webpackChunkName: "cycles" */ "./cycles/2");
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./b";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./c";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./a";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./a";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./a";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./b";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./b";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import "./c";
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
module.exports = {
|
||||||
|
mode: "development",
|
||||||
|
entry: "./index.js",
|
||||||
|
optimization: {
|
||||||
|
moduleIds: "natural",
|
||||||
|
chunkIds: "natural",
|
||||||
|
splitChunks: false
|
||||||
|
},
|
||||||
|
stats: {
|
||||||
|
all: false,
|
||||||
|
chunks: true,
|
||||||
|
chunkRootModules: true
|
||||||
|
}
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue