webpack 3.5.1 → 3.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,6 +22,7 @@ const Dependency = require("./Dependency");
22
22
  const ChunkRenderError = require("./ChunkRenderError");
23
23
  const CachedSource = require("webpack-sources").CachedSource;
24
24
  const Stats = require("./Stats");
25
+ const Semaphore = require("./util/Semaphore");
25
26
 
26
27
  function byId(a, b) {
27
28
  if(a.id < b.id) return -1;
@@ -62,6 +63,8 @@ class Compilation extends Tapable {
62
63
  this.hotUpdateChunkTemplate = new HotUpdateChunkTemplate(this.outputOptions);
63
64
  this.moduleTemplate = new ModuleTemplate(this.outputOptions);
64
65
 
66
+ this.semaphore = new Semaphore(options.parallelism || 100);
67
+
65
68
  this.entries = [];
66
69
  this.preparedChunks = [];
67
70
  this.entrypoints = {};
@@ -229,120 +232,128 @@ class Compilation extends Tapable {
229
232
  callback();
230
233
  };
231
234
 
232
- const factory = item[0];
233
- factory.create({
234
- contextInfo: {
235
- issuer: module.nameForCondition && module.nameForCondition(),
236
- compiler: _this.compiler.name
237
- },
238
- context: module.context,
239
- dependencies: dependencies
240
- }, function factoryCallback(err, dependentModule) {
241
- let afterFactory;
242
-
243
- function isOptional() {
244
- return dependencies.filter(d => !d.optional).length === 0;
245
- }
235
+ _this.semaphore.acquire(() => {
236
+ const factory = item[0];
237
+ factory.create({
238
+ contextInfo: {
239
+ issuer: module.nameForCondition && module.nameForCondition(),
240
+ compiler: _this.compiler.name
241
+ },
242
+ context: module.context,
243
+ dependencies: dependencies
244
+ }, function factoryCallback(err, dependentModule) {
245
+ let afterFactory;
246
+
247
+ function isOptional() {
248
+ return dependencies.filter(d => !d.optional).length === 0;
249
+ }
246
250
 
247
- function errorOrWarningAndCallback(err) {
248
- if(isOptional()) {
249
- return warningAndCallback(err);
250
- } else {
251
- return errorAndCallback(err);
251
+ function errorOrWarningAndCallback(err) {
252
+ if(isOptional()) {
253
+ return warningAndCallback(err);
254
+ } else {
255
+ return errorAndCallback(err);
256
+ }
252
257
  }
253
- }
254
258
 
255
- function iterationDependencies(depend) {
256
- for(let index = 0; index < depend.length; index++) {
257
- const dep = depend[index];
258
- dep.module = dependentModule;
259
- dependentModule.addReason(module, dep);
259
+ function iterationDependencies(depend) {
260
+ for(let index = 0; index < depend.length; index++) {
261
+ const dep = depend[index];
262
+ dep.module = dependentModule;
263
+ dependentModule.addReason(module, dep);
264
+ }
260
265
  }
261
- }
262
266
 
263
- if(err) {
264
- return errorOrWarningAndCallback(new ModuleNotFoundError(module, err, dependencies));
265
- }
266
- if(!dependentModule) {
267
- return process.nextTick(callback);
268
- }
269
- if(_this.profile) {
270
- if(!dependentModule.profile) {
271
- dependentModule.profile = {};
267
+ if(err) {
268
+ _this.semaphore.release();
269
+ return errorOrWarningAndCallback(new ModuleNotFoundError(module, err, dependencies));
270
+ }
271
+ if(!dependentModule) {
272
+ _this.semaphore.release();
273
+ return process.nextTick(callback);
274
+ }
275
+ if(_this.profile) {
276
+ if(!dependentModule.profile) {
277
+ dependentModule.profile = {};
278
+ }
279
+ afterFactory = Date.now();
280
+ dependentModule.profile.factory = afterFactory - start;
272
281
  }
273
- afterFactory = Date.now();
274
- dependentModule.profile.factory = afterFactory - start;
275
- }
276
282
 
277
- dependentModule.issuer = module;
278
- const newModule = _this.addModule(dependentModule, cacheGroup);
283
+ dependentModule.issuer = module;
284
+ const newModule = _this.addModule(dependentModule, cacheGroup);
279
285
 
280
- if(!newModule) { // from cache
281
- dependentModule = _this.getModule(dependentModule);
286
+ if(!newModule) { // from cache
287
+ dependentModule = _this.getModule(dependentModule);
282
288
 
283
- if(dependentModule.optional) {
284
- dependentModule.optional = isOptional();
285
- }
289
+ if(dependentModule.optional) {
290
+ dependentModule.optional = isOptional();
291
+ }
286
292
 
287
- iterationDependencies(dependencies);
293
+ iterationDependencies(dependencies);
288
294
 
289
- if(_this.profile) {
290
- if(!module.profile) {
291
- module.profile = {};
292
- }
293
- const time = Date.now() - start;
294
- if(!module.profile.dependencies || time > module.profile.dependencies) {
295
- module.profile.dependencies = time;
295
+ if(_this.profile) {
296
+ if(!module.profile) {
297
+ module.profile = {};
298
+ }
299
+ const time = Date.now() - start;
300
+ if(!module.profile.dependencies || time > module.profile.dependencies) {
301
+ module.profile.dependencies = time;
302
+ }
296
303
  }
304
+
305
+ _this.semaphore.release();
306
+ return process.nextTick(callback);
297
307
  }
298
308
 
299
- return process.nextTick(callback);
300
- }
309
+ if(newModule instanceof Module) {
310
+ if(_this.profile) {
311
+ newModule.profile = dependentModule.profile;
312
+ }
301
313
 
302
- if(newModule instanceof Module) {
303
- if(_this.profile) {
304
- newModule.profile = dependentModule.profile;
305
- }
314
+ newModule.optional = isOptional();
315
+ newModule.issuer = dependentModule.issuer;
316
+ dependentModule = newModule;
306
317
 
307
- newModule.optional = isOptional();
308
- newModule.issuer = dependentModule.issuer;
309
- dependentModule = newModule;
318
+ iterationDependencies(dependencies);
310
319
 
311
- iterationDependencies(dependencies);
320
+ if(_this.profile) {
321
+ const afterBuilding = Date.now();
322
+ module.profile.building = afterBuilding - afterFactory;
323
+ }
312
324
 
313
- if(_this.profile) {
314
- const afterBuilding = Date.now();
315
- module.profile.building = afterBuilding - afterFactory;
325
+ _this.semaphore.release();
326
+ if(recursive) {
327
+ return process.nextTick(_this.processModuleDependencies.bind(_this, dependentModule, callback));
328
+ } else {
329
+ return process.nextTick(callback);
330
+ }
316
331
  }
317
332
 
318
- if(recursive) {
319
- return process.nextTick(_this.processModuleDependencies.bind(_this, dependentModule, callback));
320
- } else {
321
- return process.nextTick(callback);
322
- }
323
- }
333
+ dependentModule.optional = isOptional();
324
334
 
325
- dependentModule.optional = isOptional();
335
+ iterationDependencies(dependencies);
326
336
 
327
- iterationDependencies(dependencies);
337
+ _this.buildModule(dependentModule, isOptional(), module, dependencies, err => {
338
+ if(err) {
339
+ _this.semaphore.release();
340
+ return errorOrWarningAndCallback(err);
341
+ }
328
342
 
329
- _this.buildModule(dependentModule, isOptional(), module, dependencies, err => {
330
- if(err) {
331
- return errorOrWarningAndCallback(err);
332
- }
343
+ if(_this.profile) {
344
+ const afterBuilding = Date.now();
345
+ dependentModule.profile.building = afterBuilding - afterFactory;
346
+ }
333
347
 
334
- if(_this.profile) {
335
- const afterBuilding = Date.now();
336
- dependentModule.profile.building = afterBuilding - afterFactory;
337
- }
348
+ _this.semaphore.release();
349
+ if(recursive) {
350
+ _this.processModuleDependencies(dependentModule, callback);
351
+ } else {
352
+ return callback();
353
+ }
354
+ });
338
355
 
339
- if(recursive) {
340
- _this.processModuleDependencies(dependentModule, callback);
341
- } else {
342
- return callback();
343
- }
344
356
  });
345
-
346
357
  });
347
358
  }, function finalCallbackAddModuleDependencies(err) {
348
359
  // In V8, the Error objects keep a reference to the functions on the stack. These warnings &
@@ -362,13 +373,13 @@ class Compilation extends Tapable {
362
373
  _addModuleChain(context, dependency, onModule, callback) {
363
374
  const start = this.profile && Date.now();
364
375
 
365
- const errorAndCallback = this.bail ? function errorAndCallback(err) {
376
+ const errorAndCallback = this.bail ? (err) => {
366
377
  callback(err);
367
- } : function errorAndCallback(err) {
378
+ } : (err) => {
368
379
  err.dependencies = [dependency];
369
380
  this.errors.push(err);
370
381
  callback();
371
- }.bind(this);
382
+ };
372
383
 
373
384
  if(typeof dependency !== "object" || dependency === null || !dependency.constructor) {
374
385
  throw new Error("Parameter 'dependency' must be a Dependency");
@@ -379,79 +390,85 @@ class Compilation extends Tapable {
379
390
  throw new Error(`No dependency factory available for this dependency type: ${dependency.constructor.name}`);
380
391
  }
381
392
 
382
- moduleFactory.create({
383
- contextInfo: {
384
- issuer: "",
385
- compiler: this.compiler.name
386
- },
387
- context: context,
388
- dependencies: [dependency]
389
- }, (err, module) => {
390
- if(err) {
391
- return errorAndCallback(new EntryModuleNotFoundError(err));
392
- }
393
-
394
- let afterFactory;
395
-
396
- if(this.profile) {
397
- if(!module.profile) {
398
- module.profile = {};
393
+ this.semaphore.acquire(() => {
394
+ moduleFactory.create({
395
+ contextInfo: {
396
+ issuer: "",
397
+ compiler: this.compiler.name
398
+ },
399
+ context: context,
400
+ dependencies: [dependency]
401
+ }, (err, module) => {
402
+ if(err) {
403
+ this.semaphore.release();
404
+ return errorAndCallback(new EntryModuleNotFoundError(err));
399
405
  }
400
- afterFactory = Date.now();
401
- module.profile.factory = afterFactory - start;
402
- }
403
-
404
- const result = this.addModule(module);
405
- if(!result) {
406
- module = this.getModule(module);
407
406
 
408
- onModule(module);
407
+ let afterFactory;
409
408
 
410
409
  if(this.profile) {
411
- const afterBuilding = Date.now();
412
- module.profile.building = afterBuilding - afterFactory;
410
+ if(!module.profile) {
411
+ module.profile = {};
412
+ }
413
+ afterFactory = Date.now();
414
+ module.profile.factory = afterFactory - start;
413
415
  }
414
416
 
415
- return callback(null, module);
416
- }
417
+ const result = this.addModule(module);
418
+ if(!result) {
419
+ module = this.getModule(module);
417
420
 
418
- if(result instanceof Module) {
419
- if(this.profile) {
420
- result.profile = module.profile;
421
- }
421
+ onModule(module);
422
422
 
423
- module = result;
423
+ if(this.profile) {
424
+ const afterBuilding = Date.now();
425
+ module.profile.building = afterBuilding - afterFactory;
426
+ }
424
427
 
425
- onModule(module);
428
+ this.semaphore.release();
429
+ return callback(null, module);
430
+ }
426
431
 
427
- moduleReady.call(this);
428
- return;
429
- }
432
+ if(result instanceof Module) {
433
+ if(this.profile) {
434
+ result.profile = module.profile;
435
+ }
430
436
 
431
- onModule(module);
437
+ module = result;
432
438
 
433
- this.buildModule(module, false, null, null, (err) => {
434
- if(err) {
435
- return errorAndCallback(err);
436
- }
439
+ onModule(module);
437
440
 
438
- if(this.profile) {
439
- const afterBuilding = Date.now();
440
- module.profile.building = afterBuilding - afterFactory;
441
+ moduleReady.call(this);
442
+ return;
441
443
  }
442
444
 
443
- moduleReady.call(this);
444
- });
445
+ onModule(module);
445
446
 
446
- function moduleReady() {
447
- this.processModuleDependencies(module, err => {
447
+ this.buildModule(module, false, null, null, (err) => {
448
448
  if(err) {
449
- return callback(err);
449
+ this.semaphore.release();
450
+ return errorAndCallback(err);
450
451
  }
451
452
 
452
- return callback(null, module);
453
+ if(this.profile) {
454
+ const afterBuilding = Date.now();
455
+ module.profile.building = afterBuilding - afterFactory;
456
+ }
457
+
458
+ moduleReady.call(this);
453
459
  });
454
- }
460
+
461
+ function moduleReady() {
462
+ this.semaphore.release();
463
+ this.processModuleDependencies(module, err => {
464
+ if(err) {
465
+ return callback(err);
466
+ }
467
+
468
+ return callback(null, module);
469
+ });
470
+ }
471
+ });
455
472
  });
456
473
  }
457
474
 
@@ -1103,6 +1120,17 @@ class Compilation extends Tapable {
1103
1120
  for(let indexChunk = 0; indexChunk < chunks.length; indexChunk++) {
1104
1121
  chunks[indexChunk].sortItems();
1105
1122
  }
1123
+
1124
+ const byMessage = (a, b) => {
1125
+ const ma = `${a.message}`;
1126
+ const mb = `${b.message}`;
1127
+ if(ma < mb) return -1;
1128
+ if(mb < ma) return 1;
1129
+ return 0;
1130
+ };
1131
+
1132
+ this.errors.sort(byMessage);
1133
+ this.warnings.sort(byMessage);
1106
1134
  }
1107
1135
 
1108
1136
  summarizeDependencies() {
@@ -1171,6 +1199,12 @@ class Compilation extends Tapable {
1171
1199
  this.children.forEach(function(child) {
1172
1200
  hash.update(child.hash);
1173
1201
  });
1202
+ this.warnings.forEach(function(warning) {
1203
+ hash.update(`${warning.message}`);
1204
+ });
1205
+ this.errors.forEach(function(error) {
1206
+ hash.update(`${error.message}`);
1207
+ });
1174
1208
  // clone needed as sort below is inplace mutation
1175
1209
  const chunks = this.chunks.slice();
1176
1210
  /**
package/lib/Compiler.js CHANGED
@@ -201,7 +201,7 @@ class Compiler extends Tapable {
201
201
  });
202
202
  });
203
203
  },
204
- apply: function() {
204
+ apply: () => {
205
205
  const args = arguments;
206
206
  if(!deprecationReported) {
207
207
  console.warn("webpack: Using compiler.parser is deprecated.\n" +
@@ -214,7 +214,7 @@ class Compiler extends Tapable {
214
214
  parser.apply.apply(parser, args);
215
215
  });
216
216
  });
217
- }.bind(this)
217
+ }
218
218
  };
219
219
 
220
220
  this.options = {};
@@ -313,13 +313,7 @@ class Compiler extends Tapable {
313
313
  emitAssets(compilation, callback) {
314
314
  let outputPath;
315
315
 
316
- this.applyPluginsAsync("emit", compilation, err => {
317
- if(err) return callback(err);
318
- outputPath = compilation.getPath(this.outputPath);
319
- this.outputFileSystem.mkdirp(outputPath, emitFiles.bind(this));
320
- });
321
-
322
- function emitFiles(err) {
316
+ const emitFiles = (err) => {
323
317
  if(err) return callback(err);
324
318
 
325
319
  require("async").forEach(Object.keys(compilation.assets), (file, callback) => {
@@ -330,12 +324,7 @@ class Compiler extends Tapable {
330
324
  targetFile = targetFile.substr(0, queryStringIdx);
331
325
  }
332
326
 
333
- if(targetFile.match(/\/|\\/)) {
334
- const dir = path.dirname(targetFile);
335
- this.outputFileSystem.mkdirp(this.outputFileSystem.join(outputPath, dir), writeOut.bind(this));
336
- } else writeOut.call(this);
337
-
338
- function writeOut(err) {
327
+ const writeOut = (err) => {
339
328
  if(err) return callback(err);
340
329
  const targetPath = this.outputFileSystem.join(outputPath, targetFile);
341
330
  const source = compilation.assets[file];
@@ -352,14 +341,25 @@ class Compiler extends Tapable {
352
341
  source.existsAt = targetPath;
353
342
  source.emitted = true;
354
343
  this.outputFileSystem.writeFile(targetPath, content, callback);
355
- }
344
+ };
345
+
346
+ if(targetFile.match(/\/|\\/)) {
347
+ const dir = path.dirname(targetFile);
348
+ this.outputFileSystem.mkdirp(this.outputFileSystem.join(outputPath, dir), writeOut);
349
+ } else writeOut();
356
350
 
357
351
  }, err => {
358
352
  if(err) return callback(err);
359
353
 
360
354
  afterEmit.call(this);
361
355
  });
362
- }
356
+ };
357
+
358
+ this.applyPluginsAsync("emit", compilation, err => {
359
+ if(err) return callback(err);
360
+ outputPath = compilation.getPath(this.outputPath);
361
+ this.outputFileSystem.mkdirp(outputPath, emitFiles);
362
+ });
363
363
 
364
364
  function afterEmit() {
365
365
  this.applyPluginsAsyncSeries1("after-emit", compilation, err => {
@@ -103,16 +103,16 @@ module.exports = class ContextModuleFactory extends Tapable {
103
103
  if(!regExp || !resource)
104
104
  return callback(null, []);
105
105
  (function addDirectory(directory, callback) {
106
- fs.readdir(directory, function(err, files) {
106
+ fs.readdir(directory, (err, files) => {
107
107
  if(err) return callback(err);
108
108
  if(!files || files.length === 0) return callback(null, []);
109
109
  asyncLib.map(files.filter(function(p) {
110
110
  return p.indexOf(".") !== 0;
111
- }), function(seqment, callback) {
111
+ }), (seqment, callback) => {
112
112
 
113
113
  const subResource = path.join(directory, seqment);
114
114
 
115
- fs.stat(subResource, function(err, stat) {
115
+ fs.stat(subResource, (err, stat) => {
116
116
  if(err) return callback(err);
117
117
 
118
118
  if(stat.isDirectory()) {
@@ -141,9 +141,9 @@ module.exports = class ContextModuleFactory extends Tapable {
141
141
 
142
142
  } else callback();
143
143
 
144
- }.bind(this));
144
+ });
145
145
 
146
- }.bind(this), (err, result) => {
146
+ }, (err, result) => {
147
147
  if(err) return callback(err);
148
148
 
149
149
  if(!result) return callback(null, []);
@@ -154,7 +154,7 @@ module.exports = class ContextModuleFactory extends Tapable {
154
154
  return a.concat(i);
155
155
  }, []));
156
156
  });
157
- }.bind(this));
157
+ });
158
158
  }.call(this, resource, callback));
159
159
  }
160
160
  };
@@ -1,27 +1,27 @@
1
1
  /*
2
2
  MIT License http://www.opensource.org/licenses/mit-license.php
3
3
  Author Tobias Koppers @sokra
4
- */
4
+ */
5
5
  "use strict";
6
6
 
7
7
  const SingleEntryPlugin = require("./SingleEntryPlugin");
8
8
  const MultiEntryPlugin = require("./MultiEntryPlugin");
9
9
  const DynamicEntryPlugin = require("./DynamicEntryPlugin");
10
10
 
11
+ function itemToPlugin(context, item, name) {
12
+ if(Array.isArray(item)) {
13
+ return new MultiEntryPlugin(context, item, name);
14
+ }
15
+ return new SingleEntryPlugin(context, item, name);
16
+ }
17
+
11
18
  module.exports = class EntryOptionPlugin {
12
19
  apply(compiler) {
13
20
  compiler.plugin("entry-option", (context, entry) => {
14
- function itemToPlugin(item, name) {
15
- if(Array.isArray(item)) {
16
- return new MultiEntryPlugin(context, item, name);
17
- } else {
18
- return new SingleEntryPlugin(context, item, name);
19
- }
20
- }
21
21
  if(typeof entry === "string" || Array.isArray(entry)) {
22
- compiler.apply(itemToPlugin(entry, "main"));
22
+ compiler.apply(itemToPlugin(context, entry, "main"));
23
23
  } else if(typeof entry === "object") {
24
- Object.keys(entry).forEach(name => compiler.apply(itemToPlugin(entry[name], name)));
24
+ Object.keys(entry).forEach(name => compiler.apply(itemToPlugin(context, entry[name], name)));
25
25
  } else if(typeof entry === "function") {
26
26
  compiler.apply(new DynamicEntryPlugin(context, entry));
27
27
  }
@@ -462,6 +462,9 @@ module.exports = function() {
462
462
  // remove module from cache
463
463
  delete installedModules[moduleId];
464
464
 
465
+ // when disposing there is no need to call dispose handler
466
+ delete outdatedDependencies[moduleId];
467
+
465
468
  // remove "parents" references from all children
466
469
  for(j = 0; j < module.children.length; j++) {
467
470
  var child = installedModules[module.children[j]];
@@ -507,30 +510,34 @@ module.exports = function() {
507
510
  for(moduleId in outdatedDependencies) {
508
511
  if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) {
509
512
  module = installedModules[moduleId];
510
- moduleOutdatedDependencies = outdatedDependencies[moduleId];
511
- var callbacks = [];
512
- for(i = 0; i < moduleOutdatedDependencies.length; i++) {
513
- dependency = moduleOutdatedDependencies[i];
514
- cb = module.hot._acceptedDependencies[dependency];
515
- if(callbacks.indexOf(cb) >= 0) continue;
516
- callbacks.push(cb);
517
- }
518
- for(i = 0; i < callbacks.length; i++) {
519
- cb = callbacks[i];
520
- try {
521
- cb(moduleOutdatedDependencies);
522
- } catch(err) {
523
- if(options.onErrored) {
524
- options.onErrored({
525
- type: "accept-errored",
526
- moduleId: moduleId,
527
- dependencyId: moduleOutdatedDependencies[i],
528
- error: err
529
- });
513
+ if(module) {
514
+ moduleOutdatedDependencies = outdatedDependencies[moduleId];
515
+ var callbacks = [];
516
+ for(i = 0; i < moduleOutdatedDependencies.length; i++) {
517
+ dependency = moduleOutdatedDependencies[i];
518
+ cb = module.hot._acceptedDependencies[dependency];
519
+ if(cb) {
520
+ if(callbacks.indexOf(cb) >= 0) continue;
521
+ callbacks.push(cb);
530
522
  }
531
- if(!options.ignoreErrored) {
532
- if(!error)
533
- error = err;
523
+ }
524
+ for(i = 0; i < callbacks.length; i++) {
525
+ cb = callbacks[i];
526
+ try {
527
+ cb(moduleOutdatedDependencies);
528
+ } catch(err) {
529
+ if(options.onErrored) {
530
+ options.onErrored({
531
+ type: "accept-errored",
532
+ moduleId: moduleId,
533
+ dependencyId: moduleOutdatedDependencies[i],
534
+ error: err
535
+ });
536
+ }
537
+ if(!options.ignoreErrored) {
538
+ if(!error)
539
+ error = err;
540
+ }
534
541
  }
535
542
  }
536
543
  }
package/lib/Module.js CHANGED
@@ -73,6 +73,7 @@ class Module extends DependenciesBlock {
73
73
 
74
74
  setChunks(chunks) {
75
75
  this._chunks = new SortableSet(chunks, sortById);
76
+ this._chunksDebugIdent = undefined;
76
77
  }
77
78
 
78
79
  addChunk(chunk) {
package/lib/Parser.js CHANGED
@@ -634,14 +634,14 @@ class Parser extends Tapable {
634
634
  statement.params.forEach(param => {
635
635
  this.walkPattern(param);
636
636
  });
637
- this.inScope(statement.params, function() {
637
+ this.inScope(statement.params, () => {
638
638
  if(statement.body.type === "BlockStatement") {
639
639
  this.prewalkStatement(statement.body);
640
640
  this.walkStatement(statement.body);
641
641
  } else {
642
642
  this.walkExpression(statement.body);
643
643
  }
644
- }.bind(this));
644
+ });
645
645
  }
646
646
 
647
647
  prewalkImportDeclaration(statement) {
@@ -784,10 +784,10 @@ class Parser extends Tapable {
784
784
  }
785
785
 
786
786
  walkCatchClause(catchClause) {
787
- this.inScope([catchClause.param], function() {
787
+ this.inScope([catchClause.param], () => {
788
788
  this.prewalkStatement(catchClause.body);
789
789
  this.walkStatement(catchClause.body);
790
- }.bind(this));
790
+ });
791
791
  }
792
792
 
793
793
  prewalkVariableDeclarators(declarators) {
@@ -916,28 +916,28 @@ class Parser extends Tapable {
916
916
  expression.params.forEach(param => {
917
917
  this.walkPattern(param);
918
918
  });
919
- this.inScope(expression.params, function() {
919
+ this.inScope(expression.params, () => {
920
920
  if(expression.body.type === "BlockStatement") {
921
921
  this.prewalkStatement(expression.body);
922
922
  this.walkStatement(expression.body);
923
923
  } else {
924
924
  this.walkExpression(expression.body);
925
925
  }
926
- }.bind(this));
926
+ });
927
927
  }
928
928
 
929
929
  walkArrowFunctionExpression(expression) {
930
930
  expression.params.forEach(param => {
931
931
  this.walkPattern(param);
932
932
  });
933
- this.inScope(expression.params, function() {
933
+ this.inScope(expression.params, () => {
934
934
  if(expression.body.type === "BlockStatement") {
935
935
  this.prewalkStatement(expression.body);
936
936
  this.walkStatement(expression.body);
937
937
  } else {
938
938
  this.walkExpression(expression.body);
939
939
  }
940
- }.bind(this));
940
+ });
941
941
  }
942
942
 
943
943
  walkSequenceExpression(expression) {
@@ -1059,7 +1059,7 @@ class Parser extends Tapable {
1059
1059
  const args = options.map(renameArgOrThis, this);
1060
1060
  this.inScope(params.filter(function(identifier, idx) {
1061
1061
  return !args[idx];
1062
- }), function() {
1062
+ }), () => {
1063
1063
  if(renameThis) {
1064
1064
  this.scope.renames.$this = renameThis;
1065
1065
  }
@@ -1074,7 +1074,7 @@ class Parser extends Tapable {
1074
1074
  this.walkStatement(functionExpression.body);
1075
1075
  } else
1076
1076
  this.walkExpression(functionExpression.body);
1077
- }.bind(this));
1077
+ });
1078
1078
  }
1079
1079
  if(expression.callee.type === "MemberExpression" &&
1080
1080
  expression.callee.object.type === "FunctionExpression" &&
@@ -41,7 +41,7 @@ class UmdMainTemplatePlugin {
41
41
 
42
42
  apply(compilation) {
43
43
  const mainTemplate = compilation.mainTemplate;
44
- compilation.templatesPlugin("render-with-entry", function(source, chunk, hash) {
44
+ compilation.templatesPlugin("render-with-entry", (source, chunk, hash) => {
45
45
  let externals = chunk.getModules().filter(m => m.external);
46
46
  const optionalExternals = [];
47
47
  let requiredExternals = [];
@@ -172,19 +172,19 @@ class UmdMainTemplatePlugin {
172
172
  " }\n"
173
173
  ) +
174
174
  "})(this, function(" + externalsArguments(externals) + ") {\nreturn ", "webpack/universalModuleDefinition"), source, ";\n})");
175
- }.bind(this));
176
- mainTemplate.plugin("global-hash-paths", function(paths) {
175
+ });
176
+ mainTemplate.plugin("global-hash-paths", (paths) => {
177
177
  if(this.names.root) paths = paths.concat(this.names.root);
178
178
  if(this.names.amd) paths = paths.concat(this.names.amd);
179
179
  if(this.names.commonjs) paths = paths.concat(this.names.commonjs);
180
180
  return paths;
181
- }.bind(this));
182
- mainTemplate.plugin("hash", function(hash) {
181
+ });
182
+ mainTemplate.plugin("hash", (hash) => {
183
183
  hash.update("umd");
184
184
  hash.update(`${this.names.root}`);
185
185
  hash.update(`${this.names.amd}`);
186
186
  hash.update(`${this.names.commonjs}`);
187
- }.bind(this));
187
+ });
188
188
  }
189
189
  }
190
190
 
@@ -32,17 +32,16 @@ function ensureNsObjSource(info, moduleToInfoMap, requestShortener) {
32
32
  }
33
33
  }
34
34
 
35
- function getExternalImport(importedModule, importedVar, exportName, asCall) {
36
- const isHarmonyModule = importedModule && (!importedModule.meta || importedModule.meta.harmonyModule);
37
- if(exportName === true) return importedVar;
35
+ function getExternalImport(importedModule, info, exportName, asCall) {
36
+ if(exportName === true) return info.name;
38
37
  const used = importedModule.isUsed(exportName);
39
38
  if(!used) return "/* unused reexport */undefined";
40
- if(!isHarmonyModule && exportName === "default") {
41
- return asCall ? `${importedVar}_default()` : `${importedVar}_default.a`;
39
+ if(info.interop && exportName === "default") {
40
+ return asCall ? `${info.interopName}()` : `${info.interopName}.a`;
42
41
  }
43
42
  // TODO use Template.toNormalComment when merging with pure-module
44
43
  const comment = used !== exportName ? ` /* ${exportName} */` : "";
45
- const reference = `${importedVar}[${JSON.stringify(used)}${comment}]`;
44
+ const reference = `${info.name}[${JSON.stringify(used)}${comment}]`;
46
45
  if(asCall)
47
46
  return `Object(${reference})`;
48
47
  return reference;
@@ -67,12 +66,6 @@ function getFinalName(info, exportName, moduleToInfoMap, requestShortener, asCal
67
66
  if(refInfo) {
68
67
  // module is in the concatenation
69
68
  return getFinalName(refInfo, reexport.exportName, moduleToInfoMap, requestShortener, asCall);
70
- } else {
71
- const dep = reexport.dependency;
72
- const importedModule = reexport.module;
73
- const exportName = reexport.exportName;
74
- const importedVar = dep.importedVar;
75
- return getExternalImport(importedModule, importedVar, exportName, asCall);
76
69
  }
77
70
  }
78
71
  const problem = `Cannot get final name for export "${exportName}" in "${info.module.readableIdentifier(requestShortener)}"` +
@@ -84,7 +77,7 @@ function getFinalName(info, exportName, moduleToInfoMap, requestShortener, asCal
84
77
  case "external":
85
78
  {
86
79
  const importedModule = info.module;
87
- return getExternalImport(importedModule, info.name, exportName, asCall);
80
+ return getExternalImport(importedModule, info, exportName, asCall);
88
81
  }
89
82
  }
90
83
  }
@@ -220,8 +213,19 @@ class ConcatenatedModule extends Module {
220
213
  }
221
214
  }
222
215
 
216
+ get modules() {
217
+ return this._orderedConcatenationList
218
+ .filter(info => info.type === "concatenated")
219
+ .map(info => info.module);
220
+ }
221
+
223
222
  identifier() {
224
- return this._orderedConcatenationList.map(info => info.module.identifier()).join(" ");
223
+ return this._orderedConcatenationList.map(info => {
224
+ switch(info.type) {
225
+ case "concatenated":
226
+ return info.module.identifier();
227
+ }
228
+ }).filter(Boolean).join(" ");
225
229
  }
226
230
 
227
231
  readableIdentifier(requestShortener) {
@@ -348,7 +352,6 @@ class ConcatenatedModule extends Module {
348
352
  internalNames: new Map(),
349
353
  exportMap: exportMap,
350
354
  reexportMap: reexportMap,
351
- needCompatibilityFlag: false,
352
355
  hasNamespaceObject: false,
353
356
  namespaceObjectSource: null
354
357
  };
@@ -358,7 +361,9 @@ class ConcatenatedModule extends Module {
358
361
  type: "external",
359
362
  module: info.module,
360
363
  index: idx,
361
- name: undefined
364
+ name: undefined,
365
+ interopName: undefined,
366
+ interop: undefined
362
367
  };
363
368
  default:
364
369
  throw new Error(`Unsupported concatenation entry type ${info.type}`);
@@ -453,6 +458,8 @@ class ConcatenatedModule extends Module {
453
458
  "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof",
454
459
  "var", "void", "volatile", "while", "with", "yield",
455
460
 
461
+ "module", "__dirname", "__filename", "exports",
462
+
456
463
  "Array", "Date", "eval", "function", "hasOwnProperty", "Infinity", "isFinite", "isNaN",
457
464
  "isPrototypeOf", "length", "Math", "NaN", "name", "Number", "Object", "prototype", "String",
458
465
  "toString", "undefined", "valueOf",
@@ -526,9 +533,15 @@ class ConcatenatedModule extends Module {
526
533
  }
527
534
  case "external":
528
535
  {
536
+ info.interop = info.module.meta && !info.module.meta.harmonyModule;
529
537
  const externalName = this.findNewName("", allUsedNames, null, info.module.readableIdentifier(requestShortener));
530
538
  allUsedNames.add(externalName);
531
539
  info.name = externalName;
540
+ if(info.interop) {
541
+ const externalNameInterop = this.findNewName("default", allUsedNames, null, info.module.readableIdentifier(requestShortener));
542
+ allUsedNames.add(externalNameInterop);
543
+ info.interopName = externalNameInterop;
544
+ }
532
545
  break;
533
546
  }
534
547
  }
@@ -562,7 +575,8 @@ class ConcatenatedModule extends Module {
562
575
  const result = new ConcatSource();
563
576
 
564
577
  // add harmony compatibility flag (must be first because of possible circular dependencies)
565
- if(moduleToInfoMap.get(this.rootModule).needCompatibilityFlag) {
578
+ const usedExports = this.rootModule.usedExports;
579
+ if(usedExports === true) {
566
580
  result.add(`Object.defineProperty(${this.exportsArgument || "exports"}, "__esModule", { value: true });\n`);
567
581
  }
568
582
 
@@ -583,8 +597,8 @@ class ConcatenatedModule extends Module {
583
597
  case "external":
584
598
  result.add(`\n// EXTERNAL MODULE: ${info.module.readableIdentifier(requestShortener)}\n`);
585
599
  result.add(`var ${info.name} = __webpack_require__(${JSON.stringify(info.module.id)});\n`);
586
- if(info.module.meta && !info.module.meta.harmonyModule) {
587
- result.add(`var ${info.name}_default = /*#__PURE__*/__webpack_require__.n(${info.name});\n`);
600
+ if(info.interop) {
601
+ result.add(`var ${info.interopName} = /*#__PURE__*/__webpack_require__.n(${info.name});\n`);
588
602
  }
589
603
  break;
590
604
  default:
@@ -793,9 +807,7 @@ class HarmonyCompatibilityDependencyConcatenatedTemplate {
793
807
  }
794
808
 
795
809
  apply(dep, source, outputOptions, requestShortener, dependencyTemplates) {
796
- if(dep.originModule === this.rootModule) {
797
- this.modulesMap.get(this.rootModule).needCompatibilityFlag = true;
798
- }
810
+ // do nothing
799
811
  }
800
812
  }
801
813
 
@@ -22,6 +22,7 @@ class EnsureChunkConditionsPlugin {
22
22
  chunk.parents.forEach((parent) => {
23
23
  if(!usedChunks.has(parent)) {
24
24
  parent.addModule(module);
25
+ module.addChunk(parent);
25
26
  newChunks.push(parent);
26
27
  }
27
28
  });
@@ -5,6 +5,8 @@
5
5
  "use strict";
6
6
 
7
7
  const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
8
+ const ModuleHotAcceptDependency = require("../dependencies/ModuleHotAcceptDependency");
9
+ const ModuleHotDeclineDependency = require("../dependencies/ModuleHotDeclineDependency");
8
10
  const ConcatenatedModule = require("./ConcatenatedModule");
9
11
  const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
10
12
  const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
@@ -67,6 +69,12 @@ class ModuleConcatenationPlugin {
67
69
  continue;
68
70
  }
69
71
 
72
+ // Hot Module Replacement need it's own module to work correctly
73
+ if(module.dependencies.some(dep => dep instanceof ModuleHotAcceptDependency || dep instanceof ModuleHotDeclineDependency)) {
74
+ setBailoutReason(module, "Module uses Hot Module Replacement");
75
+ continue;
76
+ }
77
+
70
78
  relevantModules.push(module);
71
79
 
72
80
  // Module must not be the entry points
@@ -155,6 +163,7 @@ class ModuleConcatenationPlugin {
155
163
  }
156
164
  chunks.forEach(chunk => {
157
165
  chunk.addModule(newModule);
166
+ newModule.addChunk(chunk);
158
167
  if(chunk.entryModule === concatConfiguration.rootModule)
159
168
  chunk.entryModule = newModule;
160
169
  });
@@ -0,0 +1,32 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ "use strict";
6
+
7
+ class Semaphore {
8
+ constructor(available) {
9
+ this.available = available;
10
+ this.waiters = [];
11
+ }
12
+
13
+ acquire(callback) {
14
+ if(this.available > 0) {
15
+ this.available--;
16
+ callback();
17
+ } else {
18
+ this.waiters.push(callback);
19
+ }
20
+ }
21
+
22
+ release() {
23
+ if(this.waiters.length > 0) {
24
+ const callback = this.waiters.pop();
25
+ process.nextTick(callback);
26
+ } else {
27
+ this.available++;
28
+ }
29
+ }
30
+ }
31
+
32
+ module.exports = Semaphore;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "3.5.1",
3
+ "version": "3.5.5",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
6
6
  "dependencies": {
@@ -101,6 +101,7 @@
101
101
  "pretest": "npm run lint-files",
102
102
  "lint-files": "npm run lint && npm run beautify-lint",
103
103
  "lint": "eslint lib bin hot buildin \"test/**/webpack.config.js\" \"test/binCases/**/test.js\" \"examples/**/webpack.config.js\"",
104
+ "fix": "npm run lint -- --fix",
104
105
  "beautify-lint": "beautify-lint \"lib/**/*.js\" \"hot/**/*.js\" \"bin/**/*.js\" \"benchmark/*.js\" \"test/*.js\"",
105
106
  "nsp": "nsp check --output summary",
106
107
  "benchmark": "mocha --max-old-space-size=4096 --harmony test/*.benchmark.js -R spec",
@@ -900,6 +900,11 @@
900
900
  "output": {
901
901
  "$ref": "#/definitions/output"
902
902
  },
903
+ "parallelism": {
904
+ "description": "The number of parallel processed modules in the compilation.",
905
+ "minimum": 1,
906
+ "type": "number"
907
+ },
903
908
  "performance": {
904
909
  "description": "Configuration for web performance recommendations.",
905
910
  "anyOf": [