webpack 3.5.3 → 3.6.0

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.
@@ -30,6 +30,7 @@ class OptionsDefaulter {
30
30
  }
31
31
 
32
32
  process(options) {
33
+ // TODO: change this for webpack 4: options = Object.assign({}, options);
33
34
  for(let name in this.defaults) {
34
35
  switch(this.config[name]) {
35
36
  case undefined:
@@ -55,6 +56,7 @@ class OptionsDefaulter {
55
56
  throw new Error("OptionsDefaulter cannot process " + this.config[name]);
56
57
  }
57
58
  }
59
+ // TODO: change this for webpack 4: return options;
58
60
  }
59
61
 
60
62
  set(name, config, def) {
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" &&
@@ -96,7 +96,8 @@ class SourceMapDevToolPlugin {
96
96
  return module || source;
97
97
  });
98
98
 
99
- for(const module of modules) {
99
+ for(let idx = 0; idx < modules.length; idx++) {
100
+ const module = modules[idx];
100
101
  if(!moduleToSourceNameMapping.get(module)) {
101
102
  moduleToSourceNameMapping.set(module, ModuleFilenameHelpers.createFilename(module, moduleFilenameTemplate, requestShortener));
102
103
  }
@@ -121,7 +122,8 @@ class SourceMapDevToolPlugin {
121
122
  });
122
123
 
123
124
  // find modules with conflicting source names
124
- for(const module of allModules) {
125
+ for(let idx = 0; idx < allModules.length; idx++) {
126
+ const module = allModules[idx];
125
127
  let sourceName = moduleToSourceNameMapping.get(module);
126
128
  let hasName = conflictDetectionSet.has(sourceName);
127
129
  if(!hasName) {
package/lib/Template.js CHANGED
@@ -10,6 +10,12 @@ const ConcatSource = require("webpack-sources").ConcatSource;
10
10
  const START_LOWERCASE_ALPHABET_CODE = "a".charCodeAt(0);
11
11
  const START_UPPERCASE_ALPHABET_CODE = "A".charCodeAt(0);
12
12
  const DELTA_A_TO_Z = "z".charCodeAt(0) - START_LOWERCASE_ALPHABET_CODE + 1;
13
+ const FUNCTION_CONTENT_REGEX = /^function\s?\(\)\s?\{\n?|\n?\}$/g;
14
+ const INDENT_MULTILINE_REGEX = /^\t/mg;
15
+ const IDENTIFIER_NAME_REPLACE_REGEX = /^[^a-zA-Z$_]/;
16
+ const IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX = /[^a-zA-Z0-9$_]/g;
17
+ const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!§$()=\-^°]+/g;
18
+ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
13
19
 
14
20
  module.exports = class Template extends Tapable {
15
21
  constructor(outputOptions) {
@@ -18,17 +24,17 @@ module.exports = class Template extends Tapable {
18
24
  }
19
25
 
20
26
  static getFunctionContent(fn) {
21
- return fn.toString().replace(/^function\s?\(\)\s?\{\n?|\n?\}$/g, "").replace(/^\t/mg, "");
27
+ return fn.toString().replace(FUNCTION_CONTENT_REGEX, "").replace(INDENT_MULTILINE_REGEX, "");
22
28
  }
23
29
 
24
30
  static toIdentifier(str) {
25
31
  if(typeof str !== "string") return "";
26
- return str.replace(/^[^a-zA-Z$_]/, "_").replace(/[^a-zA-Z0-9$_]/g, "_");
32
+ return str.replace(IDENTIFIER_NAME_REPLACE_REGEX, "_").replace(IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX, "_");
27
33
  }
28
34
 
29
35
  static toPath(str) {
30
36
  if(typeof str !== "string") return "";
31
- return str.replace(/[^a-zA-Z0-9_!§$()=\-^°]+/g, "-").replace(/^-|-$/, "");
37
+ return str.replace(PATH_NAME_NORMALIZE_REPLACE_REGEX, "-").replace(MATCH_PADDED_HYPHENS_REPLACE_REGEX, "");
32
38
  }
33
39
 
34
40
  // map number to a single character a-z, A-Z or <_ + number> if number is too big
@@ -144,23 +150,27 @@ module.exports = class Template extends Tapable {
144
150
  } else {
145
151
  // Render an object
146
152
  source.add("{\n");
147
- allModules.sort(function(a, b) {
148
- var aId = a.id + "";
149
- var bId = b.id + "";
150
- if(aId < bId) return -1;
151
- if(aId > bId) return 1;
152
- return 0;
153
- }).forEach(function(module, idx) {
154
- if(idx !== 0) source.add(",\n");
155
- source.add("\n/***/ " + JSON.stringify(module.id) + ":\n");
156
- source.add(module.source);
157
- });
153
+ allModules
154
+ .sort(stringifyIdSortPredicate)
155
+ .forEach(function(module, idx) {
156
+ if(idx !== 0) source.add(",\n");
157
+ source.add(`\n/***/ ${JSON.stringify(module.id)}:\n`);
158
+ source.add(module.source);
159
+ });
158
160
  source.add("\n\n" + prefix + "}");
159
161
  }
160
162
  return source;
161
163
  }
162
164
  };
163
165
 
166
+ function stringifyIdSortPredicate(a, b) {
167
+ var aId = a.id + "";
168
+ var bId = b.id + "";
169
+ if(aId < bId) return -1;
170
+ if(aId > bId) return 1;
171
+ return 0;
172
+ }
173
+
164
174
  function moduleIdIsNumber(module) {
165
175
  return typeof module.id === "number";
166
176
  }
@@ -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
 
@@ -16,6 +16,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
16
16
  this.set("context", process.cwd());
17
17
  this.set("target", "web");
18
18
 
19
+ this.set("module", "call", value => Object.assign({}, value));
19
20
  this.set("module.unknownContextRequest", ".");
20
21
  this.set("module.unknownContextRegExp", false);
21
22
  this.set("module.unknownContextRecursive", true);
@@ -29,7 +30,6 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
29
30
  this.set("module.wrappedContextCritical", false);
30
31
  this.set("module.strictExportPresence", false);
31
32
  this.set("module.strictThisContextOnImports", false);
32
-
33
33
  this.set("module.unsafeCache", true);
34
34
 
35
35
  this.set("output", "call", (value, options) => {
@@ -40,7 +40,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
40
40
  } else if(typeof value !== "object") {
41
41
  return {};
42
42
  } else {
43
- return value;
43
+ return Object.assign({}, value);
44
44
  }
45
45
  });
46
46
  this.set("output.filename", "[name].js");
@@ -68,7 +68,13 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
68
68
  this.set("output.devtoolLineToLine", false);
69
69
  this.set("output.strictModuleExceptionHandling", false);
70
70
 
71
- this.set("node", {});
71
+ this.set("node", "call", value => {
72
+ if(typeof value === "boolean") {
73
+ return value;
74
+ } else {
75
+ return Object.assign({}, value);
76
+ }
77
+ });
72
78
  this.set("node.console", false);
73
79
  this.set("node.process", true);
74
80
  this.set("node.global", true);
@@ -77,11 +83,18 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
77
83
  this.set("node.__filename", "mock");
78
84
  this.set("node.__dirname", "mock");
79
85
 
86
+ this.set("performance", "call", value => {
87
+ if(typeof value === "boolean") {
88
+ return value;
89
+ } else {
90
+ return Object.assign({}, value);
91
+ }
92
+ });
80
93
  this.set("performance.maxAssetSize", 250000);
81
94
  this.set("performance.maxEntrypointSize", 250000);
82
95
  this.set("performance.hints", false);
83
96
 
84
- this.set("resolve", {});
97
+ this.set("resolve", "call", value => Object.assign({}, value));
85
98
  this.set("resolve.unsafeCache", true);
86
99
  this.set("resolve.modules", ["node_modules"]);
87
100
  this.set("resolve.extensions", [".js", ".json"]);
@@ -101,7 +114,8 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
101
114
  this.set("resolve.cacheWithContext", "make", (options) => {
102
115
  return Array.isArray(options.resolve.plugins) && options.resolve.plugins.length > 0;
103
116
  });
104
- this.set("resolveLoader", {});
117
+
118
+ this.set("resolveLoader", "call", value => Object.assign({}, value));
105
119
  this.set("resolveLoader.unsafeCache", true);
106
120
  this.set("resolveLoader.mainFields", ["loader", "main"]);
107
121
  this.set("resolveLoader.extensions", [".js", ".json"]);
@@ -26,11 +26,12 @@ class HarmonyExportImportedSpecifierDependency extends NullDependency {
26
26
  const active = HarmonyModulesHelpers.isActive(this.originModule, this);
27
27
  const importedModule = this.importDependency.module;
28
28
 
29
- if(!importedModule || !used || !active) return null;
30
- if(!this.originModule.usedExports) return null;
29
+ if(!importedModule || !used || !active || !this.originModule.usedExports) return null;
30
+
31
+ const hasUsedExports = Array.isArray(this.originModule.usedExports);
31
32
 
32
33
  if(name) {
33
- const nameIsNotInUsedExports = Array.isArray(this.originModule.usedExports) && this.originModule.usedExports.indexOf(name) < 0;
34
+ const nameIsNotInUsedExports = hasUsedExports && this.originModule.usedExports.indexOf(name) < 0;
34
35
  if(nameIsNotInUsedExports) return null;
35
36
 
36
37
  // export { name as name }
@@ -48,33 +49,31 @@ class HarmonyExportImportedSpecifierDependency extends NullDependency {
48
49
  };
49
50
  }
50
51
 
52
+ const hasProvidedExports = Array.isArray(importedModule.providedExports);
53
+
51
54
  // export *
52
- if(Array.isArray(this.originModule.usedExports)) {
55
+ if(hasUsedExports) {
53
56
  // reexport * with known used exports
54
- var activeExports = HarmonyModulesHelpers.getActiveExports(this.originModule, this);
55
- if(Array.isArray(importedModule.providedExports)) {
56
- return {
57
- module: importedModule,
58
- importedNames: this.originModule.usedExports.filter((id) => {
59
- const notInActiveExports = activeExports.indexOf(id) < 0;
60
- const notDefault = id !== "default";
61
- const inProvidedExports = importedModule.providedExports.indexOf(id) >= 0;
62
- return notInActiveExports && notDefault && inProvidedExports;
63
- }),
64
- };
65
- }
57
+ const activeExports = HarmonyModulesHelpers.getActiveExports(this.originModule, this);
58
+ const importedNames = this.originModule.usedExports.filter(id => {
59
+ const notInActiveExports = activeExports.indexOf(id) < 0;
60
+ const notDefault = id !== "default";
61
+
62
+ if(hasProvidedExports) {
63
+ const inProvidedExports = importedModule.providedExports.indexOf(id) >= 0;
64
+ return notInActiveExports && notDefault && inProvidedExports;
65
+ } else {
66
+ return notInActiveExports && notDefault;
67
+ }
68
+ });
66
69
 
67
70
  return {
68
71
  module: importedModule,
69
- importedNames: this.originModule.usedExports.filter(id => {
70
- const notInActiveExports = activeExports.indexOf(id) < 0;
71
- const notDefault = id !== "default";
72
- return notInActiveExports && notDefault;
73
- }),
72
+ importedNames
74
73
  };
75
74
  }
76
75
 
77
- if(Array.isArray(importedModule.providedExports)) {
76
+ if(hasProvidedExports) {
78
77
  return {
79
78
  module: importedModule,
80
79
  importedNames: importedModule.providedExports.filter(id => id !== "default"),
@@ -56,6 +56,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
56
56
  if(this.strictThisContextOnImports) {
57
57
  // only in case when we strictly follow the spec we need a special case here
58
58
  parser.plugin("call imported var.*", (expr) => {
59
+ if(expr.callee.type !== "MemberExpression") return;
60
+ if(expr.callee.object.type !== "Identifier") return;
59
61
  const name = expr.callee.object.name;
60
62
  const settings = parser.state.harmonySpecifier[`$${name}`];
61
63
  if(settings[2] !== null)
@@ -75,6 +77,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
75
77
  const args = expr.arguments;
76
78
  const fullExpr = expr;
77
79
  expr = expr.callee;
80
+ if(expr.type !== "Identifier") return;
78
81
  const name = expr.name;
79
82
  const settings = parser.state.harmonySpecifier[`$${name}`];
80
83
  const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], settings[2], name, expr.range, this.strictExportPresence);
@@ -34,8 +34,8 @@ class HarmonyModulesHelpers {
34
34
  const desc = depInQuestion.describeHarmonyExport();
35
35
  if(!desc.exportedName) return true;
36
36
  let before = true;
37
- for(const moduleDependency of module.dependencies) {
38
- const dep = moduleDependency;
37
+ for(let idx = 0; idx < module.dependencies.length; idx++) {
38
+ const dep = module.dependencies[idx];
39
39
  if(dep === depInQuestion) {
40
40
  before = false;
41
41
  continue;
@@ -172,7 +172,7 @@ class ConcatenatedModule extends Module {
172
172
  this.built = modules.some(m => m.built);
173
173
  this.cacheable = modules.every(m => m.cacheable);
174
174
  const modulesSet = new Set(modules);
175
- this.reasons = rootModule.reasons.filter(reason => !modulesSet.has(reason.module));
175
+ this.reasons = rootModule.reasons.filter(reason => !(reason.dependency instanceof HarmonyImportDependency) || !modulesSet.has(reason.module));
176
176
  this.meta = rootModule.meta;
177
177
  this.moduleArgument = rootModule.moduleArgument;
178
178
  this.exportsArgument = rootModule.exportsArgument;
@@ -193,7 +193,7 @@ class ConcatenatedModule extends Module {
193
193
  const m = info.module;
194
194
 
195
195
  // populate dependencies
196
- m.dependencies.filter(dep => !modulesSet.has(dep.module))
196
+ m.dependencies.filter(dep => !(dep instanceof HarmonyImportDependency) || !modulesSet.has(dep.module))
197
197
  .forEach(d => this.dependencies.push(d));
198
198
  // populate dep warning
199
199
  m.dependenciesWarnings.forEach(depWarning => this.dependenciesWarnings.push(depWarning));
@@ -213,6 +213,12 @@ class ConcatenatedModule extends Module {
213
213
  }
214
214
  }
215
215
 
216
+ get modules() {
217
+ return this._orderedConcatenationList
218
+ .filter(info => info.type === "concatenated")
219
+ .map(info => info.module);
220
+ }
221
+
216
222
  identifier() {
217
223
  return this._orderedConcatenationList.map(info => {
218
224
  switch(info.type) {
@@ -346,7 +352,6 @@ class ConcatenatedModule extends Module {
346
352
  internalNames: new Map(),
347
353
  exportMap: exportMap,
348
354
  reexportMap: reexportMap,
349
- needCompatibilityFlag: false,
350
355
  hasNamespaceObject: false,
351
356
  namespaceObjectSource: null
352
357
  };
@@ -445,7 +450,7 @@ class ConcatenatedModule extends Module {
445
450
  const allUsedNames = new Set([
446
451
  "__WEBPACK_MODULE_DEFAULT_EXPORT__", // avoid using this internal name
447
452
 
448
- "abstract", "arguments", "await", "boolean", "break", "byte", "case", "catch", "char", "class",
453
+ "abstract", "arguments", "async", "await", "boolean", "break", "byte", "case", "catch", "char", "class",
449
454
  "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "eval",
450
455
  "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if",
451
456
  "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new",
@@ -570,7 +575,8 @@ class ConcatenatedModule extends Module {
570
575
  const result = new ConcatSource();
571
576
 
572
577
  // add harmony compatibility flag (must be first because of possible circular dependencies)
573
- if(moduleToInfoMap.get(this.rootModule).needCompatibilityFlag) {
578
+ const usedExports = this.rootModule.usedExports;
579
+ if(usedExports === true) {
574
580
  result.add(`Object.defineProperty(${this.exportsArgument || "exports"}, "__esModule", { value: true });\n`);
575
581
  }
576
582
 
@@ -801,9 +807,7 @@ class HarmonyCompatibilityDependencyConcatenatedTemplate {
801
807
  }
802
808
 
803
809
  apply(dep, source, outputOptions, requestShortener, dependencyTemplates) {
804
- if(dep.originModule === this.rootModule) {
805
- this.modulesMap.get(this.rootModule).needCompatibilityFlag = true;
806
- }
810
+ // do nothing
807
811
  }
808
812
  }
809
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/lib/webpack.js CHANGED
@@ -22,6 +22,7 @@ function webpack(options, callback) {
22
22
  if(Array.isArray(options)) {
23
23
  compiler = new MultiCompiler(options.map(options => webpack(options)));
24
24
  } else if(typeof options === "object") {
25
+ // TODO webpack 4: process returns options
25
26
  new WebpackOptionsDefaulter().process(options);
26
27
 
27
28
  compiler = new Compiler();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "3.5.3",
3
+ "version": "3.6.0",
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": {
@@ -106,7 +106,7 @@
106
106
  "nsp": "nsp check --output summary",
107
107
  "benchmark": "mocha --max-old-space-size=4096 --harmony test/*.benchmark.js -R spec",
108
108
  "cover": "node --max-old-space-size=4096 --harmony ./node_modules/istanbul/lib/cli.js cover -x '**/*.runtime.js' node_modules/mocha/bin/_mocha -- test/*.test.js",
109
- "cover:min": "node --max-old-space-size=4096 --harmony ./node_modules/.bin/istanbul cover -x '**/*.runtime.js' --report lcovonly node_modules/mocha/bin/_mocha -- test/*.test.js",
109
+ "cover:min": "node --max-old-space-size=4096 --harmony ./node_modules/istanbul/lib/cli.js cover -x '**/*.runtime.js' --report lcovonly node_modules/mocha/bin/_mocha -- test/*.test.js",
110
110
  "publish-patch": "npm run lint && npm run beautify-lint && mocha && npm version patch && git push && git push --tags && npm publish"
111
111
  }
112
112
  }
@@ -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": [