|
2 | 2 | MIT License http://www.opensource.org/licenses/mit-license.php |
3 | 3 | Author Tobias Koppers @sokra |
4 | 4 | */ |
5 | | -var path = require("path"); |
| 5 | +"use strict"; |
6 | 6 |
|
7 | | -function AggressiveSplittingPlugin(options) { |
8 | | - this.options = options || {}; |
9 | | - if(typeof this.options.minSize !== "number") this.options.minSize = 30 * 1024; |
10 | | - if(typeof this.options.maxSize !== "number") this.options.maxSize = 50 * 1024; |
11 | | - if(typeof this.options.chunkOverhead !== "number") this.options.chunkOverhead = 0; |
12 | | - if(typeof this.options.entryChunkMultiplicator !== "number") this.options.entryChunkMultiplicator = 1; |
13 | | -} |
14 | | -module.exports = AggressiveSplittingPlugin; |
| 7 | +let path = require("path"); |
15 | 8 |
|
16 | 9 | function makeRelative(context) { |
17 | 10 | return function(module) { |
18 | | - var identifier = module.identifier(); |
19 | | - return identifier.split("|").map(function(str) { |
20 | | - return str.split("!").map(function(str) { |
| 11 | + let identifier = module.identifier(); |
| 12 | + return identifier.split("|").map((str) => { |
| 13 | + return str.split("!").map((str) => { |
21 | 14 | return path.relative(context, str); |
22 | 15 | }).join("!"); |
23 | 16 | }).join("|"); |
@@ -49,150 +42,159 @@ function isNotAEntryModule(entryModule) { |
49 | 42 | } |
50 | 43 |
|
51 | 44 | function copyWithReason(obj) { |
52 | | - var newObj = {}; |
53 | | - Object.keys(obj).forEach(function(key) { |
| 45 | + let newObj = {}; |
| 46 | + Object.keys(obj).forEach((key) => { |
54 | 47 | newObj[key] = obj[key]; |
55 | 48 | }); |
56 | 49 | if(!newObj.reasons || newObj.reasons.indexOf("aggressive-splitted") < 0) |
57 | 50 | newObj.reasons = (newObj.reasons || []).concat("aggressive-splitted"); |
58 | 51 | return newObj; |
59 | 52 | } |
60 | 53 |
|
61 | | -AggressiveSplittingPlugin.prototype.apply = function(compiler) { |
62 | | - var _this = this; |
63 | | - compiler.plugin("compilation", function(compilation) { |
64 | | - compilation.plugin("optimize-chunks-advanced", function(chunks) { |
65 | | - var i, chunk, newChunk; |
66 | | - var savedSplits = compilation.records && compilation.records.aggressiveSplits || []; |
67 | | - var usedSplits = savedSplits; |
68 | | - if(compilation._aggressiveSplittingSplits) |
69 | | - usedSplits = usedSplits.concat(compilation._aggressiveSplittingSplits); |
70 | | - var minSize = _this.options.minSize; |
71 | | - var maxSize = _this.options.maxSize; |
72 | | - // 1. try to restore to recorded splitting |
73 | | - for(var j = 0; j < usedSplits.length; j++) { |
74 | | - var splitData = usedSplits[j]; |
| 54 | +class AggressiveSplittingPlugin { |
| 55 | + constructor(options) { |
| 56 | + this.options = options || {}; |
| 57 | + if(typeof this.options.minSize !== "number") this.options.minSize = 30 * 1024; |
| 58 | + if(typeof this.options.maxSize !== "number") this.options.maxSize = 50 * 1024; |
| 59 | + if(typeof this.options.chunkOverhead !== "number") this.options.chunkOverhead = 0; |
| 60 | + if(typeof this.options.entryChunkMultiplicator !== "number") this.options.entryChunkMultiplicator = 1; |
| 61 | + } |
| 62 | + apply(compiler) { |
| 63 | + compiler.plugin("compilation", (compilation) => { |
| 64 | + compilation.plugin("optimize-chunks-advanced", (chunks) => { |
| 65 | + let i, chunk, newChunk; |
| 66 | + const savedSplits = compilation.records && compilation.records.aggressiveSplits || []; |
| 67 | + let usedSplits = savedSplits; |
| 68 | + if(compilation._aggressiveSplittingSplits) |
| 69 | + usedSplits = usedSplits.concat(compilation._aggressiveSplittingSplits); |
| 70 | + const minSize = this.options.minSize; |
| 71 | + const maxSize = this.options.maxSize; |
| 72 | + // 1. try to restore to recorded splitting |
| 73 | + for(let j = 0; j < usedSplits.length; j++) { |
| 74 | + const splitData = usedSplits[j]; |
| 75 | + for(i = 0; i < chunks.length; i++) { |
| 76 | + chunk = chunks[i]; |
| 77 | + const chunkModuleNames = chunk.modules.map(makeRelative(compiler.context)); |
| 78 | + |
| 79 | + if(chunkModuleNames.length < splitData.modules) |
| 80 | + continue; |
| 81 | + const moduleIndicies = splitData.modules.map(toIndexOf(chunkModuleNames)); |
| 82 | + const hasAllModules = moduleIndicies.every((idx) => { |
| 83 | + return idx >= 0; |
| 84 | + }); |
| 85 | + if(hasAllModules) { |
| 86 | + if(chunkModuleNames.length > splitData.modules.length) { |
| 87 | + const selectedModules = moduleIndicies.map(toChunkModuleIndices(chunk.modules)); |
| 88 | + newChunk = compilation.addChunk(); |
| 89 | + selectedModules.forEach(moveModuleBetween(chunk, newChunk)); |
| 90 | + chunk.split(newChunk); |
| 91 | + chunk.name = null; |
| 92 | + newChunk._fromAggressiveSplitting = true; |
| 93 | + if(j < savedSplits.length) |
| 94 | + newChunk._fromAggressiveSplittingIndex = j; |
| 95 | + if(typeof splitData.id === "number") newChunk.id = splitData.id; |
| 96 | + newChunk.origins = chunk.origins.map(copyWithReason); |
| 97 | + chunk.origins = chunk.origins.map(copyWithReason); |
| 98 | + return true; |
| 99 | + } else { |
| 100 | + if(j < savedSplits.length) |
| 101 | + chunk._fromAggressiveSplittingIndex = j; |
| 102 | + chunk.name = null; |
| 103 | + if(typeof splitData.id === "number") chunk.id = splitData.id; |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + // 2. for any other chunk which isn't splitted yet, split it |
75 | 109 | for(i = 0; i < chunks.length; i++) { |
76 | 110 | chunk = chunks[i]; |
77 | | - var chunkModuleNames = chunk.modules.map(makeRelative(compiler.context)); |
78 | | - |
79 | | - if(chunkModuleNames.length < splitData.modules) |
80 | | - continue; |
81 | | - var moduleIndicies = splitData.modules.map(toIndexOf(chunkModuleNames)); |
82 | | - var hasAllModules = moduleIndicies.every(function(idx) { |
83 | | - return idx >= 0; |
84 | | - }); |
85 | | - if(hasAllModules) { |
86 | | - if(chunkModuleNames.length > splitData.modules.length) { |
87 | | - var selectedModules = moduleIndicies.map(toChunkModuleIndices(chunk.modules)); |
88 | | - newChunk = compilation.addChunk(); |
89 | | - selectedModules.forEach(moveModuleBetween(chunk, newChunk)); |
| 111 | + const size = chunk.size(this.options); |
| 112 | + if(size > maxSize && chunk.modules.length > 1) { |
| 113 | + newChunk = compilation.addChunk(); |
| 114 | + const modules = chunk.modules |
| 115 | + .filter(isNotAEntryModule(chunk.entryModule)) |
| 116 | + .sort((a, b) => { |
| 117 | + a = a.identifier(); |
| 118 | + b = b.identifier(); |
| 119 | + if(a > b) return 1; |
| 120 | + if(a < b) return -1; |
| 121 | + return 0; |
| 122 | + }); |
| 123 | + for(let k = 0; k < modules.length; k++) { |
| 124 | + chunk.moveModule(modules[k], newChunk); |
| 125 | + const newSize = newChunk.size(this.options); |
| 126 | + const chunkSize = chunk.size(this.options); |
| 127 | + // break early if it's fine |
| 128 | + if(chunkSize < maxSize && newSize < maxSize && newSize >= minSize && chunkSize >= minSize) |
| 129 | + break; |
| 130 | + if(newSize > maxSize && k === 0) { |
| 131 | + // break if there is a single module which is bigger than maxSize |
| 132 | + break; |
| 133 | + } |
| 134 | + if(newSize > maxSize || chunkSize < minSize) { |
| 135 | + // move it back |
| 136 | + newChunk.moveModule(modules[k], chunk); |
| 137 | + // check if it's fine now |
| 138 | + if(newSize < maxSize && newSize >= minSize && chunkSize >= minSize) |
| 139 | + break; |
| 140 | + } |
| 141 | + } |
| 142 | + if(newChunk.modules.length > 0) { |
90 | 143 | chunk.split(newChunk); |
91 | 144 | chunk.name = null; |
92 | | - newChunk._fromAggressiveSplitting = true; |
93 | | - if(j < savedSplits.length) |
94 | | - newChunk._fromAggressiveSplittingIndex = j; |
95 | | - if(typeof splitData.id === "number") newChunk.id = splitData.id; |
96 | 145 | newChunk.origins = chunk.origins.map(copyWithReason); |
97 | 146 | chunk.origins = chunk.origins.map(copyWithReason); |
| 147 | + compilation._aggressiveSplittingSplits = (compilation._aggressiveSplittingSplits || []).concat({ |
| 148 | + modules: newChunk.modules.map(makeRelative(compiler.context)) |
| 149 | + }); |
98 | 150 | return true; |
99 | 151 | } else { |
100 | | - if(j < savedSplits.length) |
101 | | - chunk._fromAggressiveSplittingIndex = j; |
102 | | - chunk.name = null; |
103 | | - if(typeof splitData.id === "number") chunk.id = splitData.id; |
| 152 | + chunks.splice(chunks.indexOf(newChunk), 1); |
104 | 153 | } |
105 | 154 | } |
106 | 155 | } |
107 | | - } |
108 | | - // 2. for any other chunk which isn't splitted yet, split it |
109 | | - for(i = 0; i < chunks.length; i++) { |
110 | | - chunk = chunks[i]; |
111 | | - var size = chunk.size(_this.options); |
112 | | - if(size > maxSize && chunk.modules.length > 1) { |
113 | | - newChunk = compilation.addChunk(); |
114 | | - var modules = chunk.modules |
115 | | - .filter(isNotAEntryModule(chunk.entryModule)) |
116 | | - .sort(function(a, b) { |
117 | | - a = a.identifier(); |
118 | | - b = b.identifier(); |
119 | | - if(a > b) return 1; |
120 | | - if(a < b) return -1; |
121 | | - return 0; |
122 | | - }); |
123 | | - for(var k = 0; k < modules.length; k++) { |
124 | | - chunk.moveModule(modules[k], newChunk); |
125 | | - var newSize = newChunk.size(_this.options); |
126 | | - var chunkSize = chunk.size(_this.options); |
127 | | - // break early if it's fine |
128 | | - if(chunkSize < maxSize && newSize < maxSize && newSize >= minSize && chunkSize >= minSize) |
129 | | - break; |
130 | | - if(newSize > maxSize && k === 0) { |
131 | | - // break if there is a single module which is bigger than maxSize |
132 | | - break; |
133 | | - } |
134 | | - if(newSize > maxSize || chunkSize < minSize) { |
135 | | - // move it back |
136 | | - newChunk.moveModule(modules[k], chunk); |
137 | | - // check if it's fine now |
138 | | - if(newSize < maxSize && newSize >= minSize && chunkSize >= minSize) |
139 | | - break; |
140 | | - } |
141 | | - } |
142 | | - if(newChunk.modules.length > 0) { |
143 | | - chunk.split(newChunk); |
144 | | - chunk.name = null; |
145 | | - newChunk.origins = chunk.origins.map(copyWithReason); |
146 | | - chunk.origins = chunk.origins.map(copyWithReason); |
147 | | - compilation._aggressiveSplittingSplits = (compilation._aggressiveSplittingSplits || []).concat({ |
148 | | - modules: newChunk.modules.map(makeRelative(compiler.context)) |
| 156 | + }); |
| 157 | + compilation.plugin("record-hash", (records) => { |
| 158 | + // 3. save to made splittings to records |
| 159 | + const minSize = this.options.minSize; |
| 160 | + if(!records.aggressiveSplits) records.aggressiveSplits = []; |
| 161 | + compilation.chunks.forEach((chunk) => { |
| 162 | + if(chunk.hasEntryModule()) return; |
| 163 | + const size = chunk.size(this.options); |
| 164 | + const incorrectSize = size < minSize; |
| 165 | + const modules = chunk.modules.map(makeRelative(compiler.context)); |
| 166 | + if(typeof chunk._fromAggressiveSplittingIndex === "undefined") { |
| 167 | + if(incorrectSize) return; |
| 168 | + chunk.recorded = true; |
| 169 | + records.aggressiveSplits.push({ |
| 170 | + modules: modules, |
| 171 | + hash: chunk.hash, |
| 172 | + id: chunk.id |
149 | 173 | }); |
150 | | - return true; |
151 | 174 | } else { |
152 | | - chunks.splice(chunks.indexOf(newChunk), 1); |
153 | | - } |
154 | | - } |
155 | | - } |
156 | | - }); |
157 | | - compilation.plugin("record-hash", function(records) { |
158 | | - // 3. save to made splittings to records |
159 | | - var minSize = _this.options.minSize; |
160 | | - if(!records.aggressiveSplits) records.aggressiveSplits = []; |
161 | | - compilation.chunks.forEach(function(chunk) { |
162 | | - if(chunk.hasEntryModule()) return; |
163 | | - var size = chunk.size(_this.options); |
164 | | - var incorrectSize = size < minSize; |
165 | | - var modules = chunk.modules.map(makeRelative(compiler.context)); |
166 | | - if(typeof chunk._fromAggressiveSplittingIndex === "undefined") { |
167 | | - if(incorrectSize) return; |
168 | | - chunk.recorded = true; |
169 | | - records.aggressiveSplits.push({ |
170 | | - modules: modules, |
171 | | - hash: chunk.hash, |
172 | | - id: chunk.id |
173 | | - }); |
174 | | - } else { |
175 | | - var splitData = records.aggressiveSplits[chunk._fromAggressiveSplittingIndex]; |
176 | | - if(splitData.hash !== chunk.hash || incorrectSize) { |
177 | | - if(chunk._fromAggressiveSplitting) { |
178 | | - chunk._aggressiveSplittingInvalid = true; |
179 | | - splitData.invalid = true; |
180 | | - } else { |
181 | | - splitData.hash = chunk.hash; |
| 175 | + let splitData = records.aggressiveSplits[chunk._fromAggressiveSplittingIndex]; |
| 176 | + if(splitData.hash !== chunk.hash || incorrectSize) { |
| 177 | + if(chunk._fromAggressiveSplitting) { |
| 178 | + chunk._aggressiveSplittingInvalid = true; |
| 179 | + splitData.invalid = true; |
| 180 | + } else { |
| 181 | + splitData.hash = chunk.hash; |
| 182 | + } |
182 | 183 | } |
183 | 184 | } |
184 | | - } |
185 | | - }); |
186 | | - records.aggressiveSplits = records.aggressiveSplits.filter(function(splitData) { |
187 | | - return !splitData.invalid; |
| 185 | + }); |
| 186 | + records.aggressiveSplits = records.aggressiveSplits.filter((splitData) => { |
| 187 | + return !splitData.invalid; |
| 188 | + }); |
188 | 189 | }); |
189 | | - }); |
190 | | - compilation.plugin("need-additional-seal", function(callback) { |
191 | | - var invalid = this.chunks.some(function(chunk) { |
192 | | - return chunk._aggressiveSplittingInvalid; |
| 190 | + compilation.plugin("need-additional-seal", (callback) => { |
| 191 | + const invalid = compilation.chunks.some((chunk) => { |
| 192 | + return chunk._aggressiveSplittingInvalid; |
| 193 | + }); |
| 194 | + if(invalid) |
| 195 | + return true; |
193 | 196 | }); |
194 | | - if(invalid) |
195 | | - return true; |
196 | 197 | }); |
197 | | - }); |
198 | | -}; |
| 198 | + } |
| 199 | +} |
| 200 | +module.exports = AggressiveSplittingPlugin; |
0 commit comments