webpack-dev-server 2.2.0 → 2.4.1

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.
@@ -2,69 +2,7 @@
2
2
 
3
3
  const optionsSchema = require("./optionsSchema.json");
4
4
 
5
- function OptionsValidationError(validationErrors) {
6
- Error.call(this);
7
- Error.captureStackTrace(this, OptionsValidationError);
8
- this.name = "WebpackDevServerOptionsValidationError";
9
- this.message = `${"Invalid configuration object. " +
10
- "webpack-dev-server has been initialised using a configuration object that does not match the API schema.\n"}${
11
- validationErrors.map(function(err) {
12
- return ` - ${indent(OptionsValidationError.formatValidationError(err), " ", false)}`;
13
- }).join("\n")}`;
14
- this.validationErrors = validationErrors;
15
- }
16
- module.exports = OptionsValidationError;
17
-
18
- OptionsValidationError.prototype = Object.create(Error.prototype);
19
- OptionsValidationError.prototype.constructor = OptionsValidationError;
20
-
21
- OptionsValidationError.formatValidationError = function formatValidationError(err) {
22
- const dataPath = `configuration${err.dataPath}`;
23
- switch(err.keyword) {
24
- case "additionalProperties":
25
- return `${dataPath} has an unknown property '${err.params.additionalProperty}'. These properties are valid:\n${
26
- getSchemaPartText(err.parentSchema)}`;
27
- case "oneOf":
28
- case "anyOf":
29
- case "enum":
30
- return `${dataPath} should be one of these:\n${
31
- getSchemaPartText(err.parentSchema)}`;
32
- case "allOf":
33
- return `${dataPath} should be:\n${
34
- getSchemaPartText(err.parentSchema)}`;
35
- case "type":
36
- switch(err.params.type) {
37
- case "object":
38
- return `${dataPath} should be an object.`;
39
- case "array":
40
- return `${dataPath} should be an array.`;
41
- case "string":
42
- return `${dataPath} should be a string.`;
43
- case "boolean":
44
- return `${dataPath} should be a boolean.`;
45
- case "number":
46
- return `${dataPath} should be a number.`;
47
- }
48
- return `${dataPath} should be ${err.params.type}:\n${
49
- getSchemaPartText(err.parentSchema)}`;
50
- case "instanceof":
51
- return `${dataPath} should be an instance of ${getSchemaPartText(err.parentSchema)}.`;
52
- case "required": // eslint-disable-line no-case-declarations
53
- const missingProperty = err.params.missingProperty.replace(/^\./, "");
54
- return `${dataPath} misses the property '${missingProperty}'.\n${
55
- getSchemaPartText(err.parentSchema, ["properties", missingProperty])}`;
56
- case "minLength":
57
- if(err.params.limit === 1)
58
- return `${dataPath} should not be empty.`;
59
- else
60
- return `${dataPath} ${err.message}`;
61
- default:
62
- return `${dataPath} ${err.message} (${JSON.stringify(err, 0, 2)}).\n${
63
- getSchemaPartText(err.parentSchema)}`;
64
- }
65
- }
66
-
67
- function getSchemaPart(path, parents, additionalPath) {
5
+ const getSchemaPart = (path, parents, additionalPath) => {
68
6
  parents = parents || 0;
69
7
  path = path.split("/");
70
8
  path = path.slice(0, path.length - parents);
@@ -79,9 +17,9 @@ function getSchemaPart(path, parents, additionalPath) {
79
17
  schemaPart = inner;
80
18
  }
81
19
  return schemaPart;
82
- }
20
+ };
83
21
 
84
- function getSchemaPartText(schemaPart, additionalPath) {
22
+ const getSchemaPartText = (schemaPart, additionalPath) => {
85
23
  if(additionalPath) {
86
24
  for(let i = 0; i < additionalPath.length; i++) {
87
25
  const inner = schemaPart[additionalPath[i]];
@@ -94,28 +32,56 @@ function getSchemaPartText(schemaPart, additionalPath) {
94
32
  if(schemaPart.description)
95
33
  schemaText += `\n${schemaPart.description}`;
96
34
  return schemaText;
97
- }
35
+ };
98
36
 
99
- function formatSchema(schema, prevSchemas) {
100
- prevSchemas = prevSchemas || [];
37
+ const indent = (str, prefix, firstLine) => {
38
+ if(firstLine) {
39
+ return prefix + str.replace(/\n(?!$)/g, "\n" + prefix);
40
+ } else {
41
+ return str.replace(/\n(?!$)/g, `\n${prefix}`);
42
+ }
43
+ };
44
+
45
+ class OptionsValidationError extends Error {
46
+
47
+ constructor(validationErrors) {
48
+ super();
49
+
50
+ if(Error.hasOwnProperty("captureStackTrace")) {
51
+ Error.captureStackTrace(this, this.constructor);
52
+ }
53
+ this.name = "WebpackDevServerOptionsValidationError";
101
54
 
102
- function formatInnerSchema(innerSchema, addSelf) {
103
- if(!addSelf) return formatSchema(innerSchema, prevSchemas);
104
- if(prevSchemas.indexOf(innerSchema) >= 0) return "(recursive)";
105
- return formatSchema(innerSchema, prevSchemas.concat(schema));
55
+ this.message = "Invalid configuration object. " +
56
+ "webpack-dev-server has been initialised using a configuration object that does not match the API schema.\n" +
57
+ validationErrors.map(err => " - " + indent(OptionsValidationError.formatValidationError(err), " ", false)).join("\n");
58
+ this.validationErrors = validationErrors;
106
59
  }
107
- switch(schema.type) {
108
- case "string":
60
+
61
+ static formatSchema(schema, prevSchemas) {
62
+ prevSchemas = prevSchemas || [];
63
+
64
+ const formatInnerSchema = (innerSchema, addSelf) => {
65
+ if(!addSelf) return OptionsValidationError.formatSchema(innerSchema, prevSchemas);
66
+ if(prevSchemas.indexOf(innerSchema) >= 0) return "(recursive)";
67
+ return OptionsValidationError.formatSchema(innerSchema, prevSchemas.concat(schema));
68
+ };
69
+
70
+ if(schema.type === "string") {
71
+ if(schema.minLength === 1)
72
+ return "non-empty string";
73
+ else if(schema.minLength > 1)
74
+ return `string (min length ${schema.minLength})`;
109
75
  return "string";
110
- case "boolean":
76
+ } else if(schema.type === "boolean") {
111
77
  return "boolean";
112
- case "number":
78
+ } else if(schema.type === "number") {
113
79
  return "number";
114
- case "object":
80
+ } else if(schema.type === "object") {
115
81
  if(schema.properties) {
116
82
  const required = schema.required || [];
117
- return `object { ${Object.keys(schema.properties).map(function(property) {
118
- if(required.indexOf(property) < 0) return `${property}?`;
83
+ return `object { ${Object.keys(schema.properties).map(property => {
84
+ if(required.indexOf(property) < 0) return property + "?";
119
85
  return property;
120
86
  }).concat(schema.additionalProperties ? ["..."] : []).join(", ")} }`;
121
87
  }
@@ -123,31 +89,71 @@ function formatSchema(schema, prevSchemas) {
123
89
  return `object { <key>: ${formatInnerSchema(schema.additionalProperties)} }`;
124
90
  }
125
91
  return "object";
126
- case "array":
92
+ } else if(schema.type === "array") {
127
93
  return `[${formatInnerSchema(schema.items)}]`;
94
+ }
95
+
96
+ switch(schema.instanceof) {
97
+ case "Function":
98
+ return "function";
99
+ case "RegExp":
100
+ return "RegExp";
101
+ }
102
+ if(schema.$ref) return formatInnerSchema(getSchemaPart(schema.$ref), true);
103
+ if(schema.allOf) return schema.allOf.map(formatInnerSchema).join(" & ");
104
+ if(schema.oneOf) return schema.oneOf.map(formatInnerSchema).join(" | ");
105
+ if(schema.anyOf) return schema.anyOf.map(formatInnerSchema).join(" | ");
106
+ if(schema.enum) return schema.enum.map(item => JSON.stringify(item)).join(" | ");
107
+ return JSON.stringify(schema, 0, 2);
128
108
  }
129
- switch(schema.instanceof) {
130
- case "Function":
131
- return "function";
132
- case "RegExp":
133
- return "RegExp";
134
- }
135
- if(schema.$ref) return formatInnerSchema(getSchemaPart(schema.$ref), true);
136
- if(schema.allOf) return schema.allOf.map(formatInnerSchema).join(" & ");
137
- if(schema.oneOf) return schema.oneOf.map(formatInnerSchema).join(" | ");
138
- if(schema.anyOf) return schema.anyOf.map(formatInnerSchema).join(" | ");
139
- if(schema.enum) return schema.enum.map(function(item) {
140
- return JSON.stringify(item);
141
- }).join(" | ");
142
- return JSON.stringify(schema, 0, 2);
143
- }
144
109
 
145
- function indent(str, prefix, firstLine) {
146
- if(firstLine) {
147
- return prefix + str.replace(/\n(?!$)/g, `\n${prefix}`);
148
- } else {
149
- return str.replace(/\n(?!$)/g, `\n${prefix}`);
110
+ static formatValidationError(err) {
111
+ const dataPath = `configuration${err.dataPath}`;
112
+ if(err.keyword === "additionalProperties") {
113
+ return `${dataPath} has an unknown property '${err.params.additionalProperty}'. These properties are valid:\n${getSchemaPartText(err.parentSchema)}`;
114
+ } else if(err.keyword === "oneOf" || err.keyword === "anyOf") {
115
+ if(err.children && err.children.length > 0) {
116
+ return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}\n` +
117
+ `Details:\n${err.children.map(err => " * " + indent(OptionsValidationError.formatValidationError(err), " ", false)).join("\n")}`;
118
+ }
119
+ return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}`;
120
+
121
+ } else if(err.keyword === "enum") {
122
+ if(err.parentSchema && err.parentSchema.enum && err.parentSchema.enum.length === 1) {
123
+ return `${dataPath} should be ${getSchemaPartText(err.parentSchema)}`;
124
+ }
125
+ return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}`;
126
+ } else if(err.keyword === "allOf") {
127
+ return `${dataPath} should be:\n${getSchemaPartText(err.parentSchema)}`;
128
+ } else if(err.keyword === "type") {
129
+ switch(err.params.type) {
130
+ case "object":
131
+ return `${dataPath} should be an object.`;
132
+ case "string":
133
+ return `${dataPath} should be a string.`;
134
+ case "boolean":
135
+ return `${dataPath} should be a boolean.`;
136
+ case "number":
137
+ return `${dataPath} should be a number.`;
138
+ case "array":
139
+ return `${dataPath} should be an array:\n${getSchemaPartText(err.parentSchema)}`;
140
+ }
141
+ return `${dataPath} should be ${err.params.type}:\n${getSchemaPartText(err.parentSchema)}`;
142
+ } else if(err.keyword === "instanceof") {
143
+ return `${dataPath} should be an instance of ${getSchemaPartText(err.parentSchema)}.`;
144
+ } else if(err.keyword === "required") {
145
+ const missingProperty = err.params.missingProperty.replace(/^\./, "");
146
+ return `${dataPath} misses the property '${missingProperty}'.\n${getSchemaPartText(err.parentSchema, ["properties", missingProperty])}`;
147
+ } else if(err.keyword === "minLength" || err.keyword === "minItems") {
148
+ if(err.params.limit === 1)
149
+ return `${dataPath} should not be empty.`;
150
+ else
151
+ return `${dataPath} ${err.message}`;
152
+ } else {
153
+ // eslint-disable-line no-fallthrough
154
+ return `${dataPath} ${err.message} (${JSON.stringify(err, 0, 2)}).\n${getSchemaPartText(err.parentSchema)}`;
155
+ }
150
156
  }
151
157
  }
152
158
 
153
- OptionsValidationError.formatSchema = formatSchema;
159
+ module.exports = OptionsValidationError;
package/lib/Server.js CHANGED
@@ -34,6 +34,7 @@ function Server(compiler, options) {
34
34
  this.hot = options.hot || options.hotOnly;
35
35
  this.headers = options.headers;
36
36
  this.clientLogLevel = options.clientLogLevel;
37
+ this.clientOverlay = options.overlay;
37
38
  this.sockets = [];
38
39
  this.contentBaseWatchers = [];
39
40
 
@@ -317,8 +318,11 @@ function Server(compiler, options) {
317
318
  defaultFeatures.push("contentBaseFiles");
318
319
  if(options.watchContentBase)
319
320
  defaultFeatures.push("watchContentBase");
320
- if(options.historyApiFallback)
321
- defaultFeatures.push("historyApiFallback", "middleware", "contentBaseFiles");
321
+ if(options.historyApiFallback) {
322
+ defaultFeatures.push("historyApiFallback", "middleware");
323
+ if(contentBase !== false)
324
+ defaultFeatures.push("contentBaseFiles");
325
+ }
322
326
  defaultFeatures.push("magicHtml");
323
327
  if(contentBase !== false)
324
328
  defaultFeatures.push("contentBaseIndex");
@@ -400,6 +404,9 @@ Server.prototype.listen = function() {
400
404
  if(this.clientLogLevel)
401
405
  this.sockWrite([conn], "log-level", this.clientLogLevel);
402
406
 
407
+ if(this.clientOverlay)
408
+ this.sockWrite([conn], "overlay", this.clientOverlay);
409
+
403
410
  if(this.hot) this.sockWrite([conn], "hot");
404
411
 
405
412
  if(!this._stats) return;
@@ -486,4 +493,7 @@ Server.prototype.invalidate = function() {
486
493
  if(this.middleware) this.middleware.invalidate();
487
494
  }
488
495
 
496
+ // Export this logic, so that other implementations, like task-runners can use it
497
+ Server.addDevServerEntrypoints = require("./util/addDevServerEntrypoints");
498
+
489
499
  module.exports = Server;
@@ -34,7 +34,14 @@
34
34
  },
35
35
  "port": {
36
36
  "description": "The port the server listens to.",
37
- "type": "number"
37
+ "anyOf": [
38
+ {
39
+ "type": "number"
40
+ },
41
+ {
42
+ "type": "string"
43
+ }
44
+ ]
38
45
  },
39
46
  "socket": {
40
47
  "description": "The Unix socket to listen to (instead of on a host).",
@@ -60,6 +67,25 @@
60
67
  "error"
61
68
  ]
62
69
  },
70
+ "overlay": {
71
+ "description": "Shows an error overlay in browser.",
72
+ "anyOf": [
73
+ {
74
+ "type": "boolean"
75
+ },
76
+ {
77
+ "type": "object",
78
+ "properties": {
79
+ "errors": {
80
+ "type": "boolean"
81
+ },
82
+ "warnings": {
83
+ "type": "boolean"
84
+ }
85
+ }
86
+ }
87
+ ]
88
+ },
63
89
  "key": {
64
90
  "description": "The contents of a SSL key.",
65
91
  "anyOf": [
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ const createDomain = require("./createDomain");
3
+
4
+ module.exports = function addDevServerEntrypoints(webpackOptions, devServerOptions) {
5
+ if(devServerOptions.inline !== false) {
6
+ const domain = createDomain(devServerOptions);
7
+ const devClient = [`${require.resolve("../../client/")}?${domain}`];
8
+
9
+ if(devServerOptions.hotOnly)
10
+ devClient.push("webpack/hot/only-dev-server");
11
+ else if(devServerOptions.hot)
12
+ devClient.push("webpack/hot/dev-server");
13
+
14
+ [].concat(webpackOptions).forEach(function(wpOpt) {
15
+ if(typeof wpOpt.entry === "object" && !Array.isArray(wpOpt.entry)) {
16
+ Object.keys(wpOpt.entry).forEach(function(key) {
17
+ wpOpt.entry[key] = devClient.concat(wpOpt.entry[key]);
18
+ });
19
+ } else {
20
+ wpOpt.entry = devClient.concat(wpOpt.entry);
21
+ }
22
+ });
23
+ }
24
+ };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ const url = require("url");
3
+
4
+ module.exports = function createDomain(options) {
5
+ const protocol = options.https ? "https" : "http";
6
+
7
+ // the formatted domain (url without path) of the webpack server
8
+ return options.public ? `${protocol}://${options.public}` : url.format({
9
+ protocol: protocol,
10
+ hostname: options.host,
11
+ port: options.socket ? 0 : options.port.toString()
12
+ });
13
+ };
package/package.json CHANGED
@@ -1,22 +1,24 @@
1
1
  {
2
2
  "name": "webpack-dev-server",
3
- "version": "2.2.0",
3
+ "version": "2.4.1",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Serves a webpack app. Updates the browser on changes.",
6
6
  "peerDependencies": {
7
7
  "webpack": "^2.2.0"
8
8
  },
9
9
  "dependencies": {
10
+ "ansi-html": "0.0.7",
10
11
  "chokidar": "^1.6.0",
11
12
  "compression": "^1.5.2",
12
13
  "connect-history-api-fallback": "^1.3.0",
13
14
  "express": "^4.13.3",
15
+ "html-entities": "^1.2.0",
14
16
  "http-proxy-middleware": "~0.17.1",
15
17
  "opn": "4.0.2",
16
18
  "portfinder": "^1.0.9",
17
19
  "serve-index": "^1.7.2",
18
20
  "sockjs": "0.3.18",
19
- "sockjs-client": "1.1.1",
21
+ "sockjs-client": "1.1.2",
20
22
  "spdy": "^3.4.1",
21
23
  "strip-ansi": "^3.0.0",
22
24
  "supports-color": "^3.1.1",
@@ -24,9 +26,9 @@
24
26
  "yargs": "^6.0.0"
25
27
  },
26
28
  "devDependencies": {
27
- "css-loader": "~0.25.0",
29
+ "css-loader": "~0.26.1",
28
30
  "eslint": "^3.4.0",
29
- "file-loader": "~0.9.0",
31
+ "file-loader": "~0.10.0",
30
32
  "istanbul": "^0.4.5",
31
33
  "jquery": "^2.2.0",
32
34
  "less": "^2.5.1",
@@ -38,7 +40,7 @@
38
40
  "should": "^11.1.0",
39
41
  "sinon": "^1.17.6",
40
42
  "style-loader": "~0.13.0",
41
- "supertest": "^2.0.0",
43
+ "supertest": "^2.0.1",
42
44
  "url-loader": "~0.5.6",
43
45
  "webpack": "^2.2.0"
44
46
  },
@@ -64,7 +66,7 @@
64
66
  "client-live": "webpack ./client/live.js client/live.bundle.js --color --config client/webpack.config.js -p",
65
67
  "client-index": "webpack ./client/index.js client/index.bundle.js --color --config client/webpack.config.js -p",
66
68
  "client-sockjs": "webpack ./client/sockjs.js client/sockjs.bundle.js --color --config client/webpack.sockjs.config.js -p",
67
- "lint": "eslint bin lib test examples client/{index,live,socket,sockjs,webpack.config}.js",
69
+ "lint": "eslint bin lib test examples client/{index,live,socket,sockjs,overlay,webpack.config}.js",
68
70
  "beautify": "npm run lint -- --fix",
69
71
  "test": "mocha --full-trace --check-leaks",
70
72
  "posttest": "npm run -s lint",