Socket
Socket
Sign inDemoInstall

webpack-dev-server

Package Overview
Dependencies
305
Maintainers
5
Versions
217
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.0-beta.1 to 4.0.0-beta.2

client/index.js

171

bin/cli-flags.js

@@ -8,2 +8,7 @@ 'use strict';

type: String,
configs: [
{
type: 'string',
},
],
description: 'The hostname/ip address the server will bind to.',

@@ -14,2 +19,7 @@ },

type: Number,
configs: [
{
type: 'number',
},
],
description: 'The port server will listen to.',

@@ -20,2 +30,10 @@ },

type: [String, Boolean],
configs: [
{
type: 'string',
},
{
type: 'boolean',
},
],
description: 'A directory to serve static content from.',

@@ -28,2 +46,7 @@ multiple: true,

type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Enables live reloading on changing files.',

@@ -36,2 +59,7 @@ negatedDescription: 'Disables live reloading on changing files.',

type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Use HTTPS protocol.',

@@ -44,2 +72,7 @@ negatedDescription: 'Do not use HTTPS protocol.',

type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Use HTTP/2, must be used with HTTPS.',

@@ -52,3 +85,11 @@ negatedDescription: 'Do not use HTTP/2.',

type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Broadcasts the server via ZeroConf networking on start.',
negatedDescription:
'Do not broadcast the server via ZeroConf networking on start.',
negative: true,
},

@@ -58,3 +99,11 @@ {

type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Print compilation progress in percentage in the browser.',
negatedDescription:
'Do not print compilation progress in percentage in the browser.',
negative: true,
processor(opts) {

@@ -67,4 +116,28 @@ opts.client = opts.client || {};

{
name: 'client-overlay',
type: Boolean,
configs: [
{
type: 'boolean',
},
],
description:
'Show a full-screen overlay in the browser when there are compiler errors or warnings.',
negatedDescription:
'Do not show a full-screen overlay in the browser when there are compiler errors or warnings.',
negative: true,
processor(opts) {
opts.client = opts.client || {};
opts.client.overlay = opts.clientOverlay;
delete opts.clientOverlay;
},
},
{
name: 'setup-exit-signals',
type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Close and exit the process on SIGINT and SIGTERM.',

@@ -75,23 +148,54 @@ negatedDescription:

},
// TODO remove in the next major release in favor `--open-target`
{
name: 'stdin',
type: Boolean,
description: 'Close when stdin ends.',
},
{
name: 'open',
type: [String, Boolean],
description:
'Open the default browser, or optionally specify a browser name.',
type: [Boolean, String],
multiple: true,
configs: [
{
type: 'boolean',
},
{
type: 'string',
},
],
description: 'Open the default browser.',
negatedDescription: 'Do not open the default browser.',
negative: true,
},
{
name: 'use-local-ip',
type: Boolean,
description: 'Open default browser with local IP.',
name: 'open-app',
type: String,
configs: [
{
type: 'string',
},
],
description: 'Open specified browser.',
processor(opts) {
opts.open = opts.open || {};
opts.open.app = opts.openApp.split(' ');
delete opts.openApp;
},
},
{
name: 'open-page',
name: 'open-target',
type: String,
description: 'Open default browser with the specified page.',
configs: [
{
type: 'boolean',
},
{
type: 'string',
},
],
description: 'Open specified route in browser.',
processor(opts) {
opts.open = opts.open || {};
opts.open.target = opts.openTarget;
delete opts.openTarget;
},
negatedDescription: 'Do not open specified route in browser.',
multiple: true,
negative: true,
},

@@ -101,2 +205,7 @@ {

type: String,
configs: [
{
type: 'string',
},
],
description:

@@ -113,2 +222,7 @@ 'Log level in the browser (none, error, warn, info, log, verbose).',

type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Fallback to /index.html for Single Page Applications.',

@@ -122,2 +236,7 @@ negatedDescription:

type: Boolean,
configs: [
{
type: 'boolean',
},
],
description: 'Enable gzip compression.',

@@ -130,2 +249,7 @@ negatedDescription: 'Disable gzip compression.',

type: String,
configs: [
{
type: 'string',
},
],
description: 'The public hostname/ip address of the server.',

@@ -135,3 +259,11 @@ },

name: 'firewall',
type: [String, Boolean],
type: [Boolean, String],
configs: [
{
type: 'boolean',
},
{
type: 'string',
},
],
description:

@@ -143,3 +275,14 @@ 'Enable firewall or set hosts that are allowed to access the dev server.',

},
{
name: 'watch-files',
type: String,
configs: [
{
type: 'string',
},
],
description: 'Watch static files for file changes.',
multiple: true,
},
],
};

@@ -5,2 +5,64 @@ # Changelog

## [4.0.0-beta.2](https://github.com/webpack/webpack-dev-server/compare/v4.0.0-beta.1...v4.0.0-beta.2) (2021-04-06)
### ⚠ BREAKING CHANGES
* the `openPage` option and the `--open-page` CLI option were removed in favor `{ open: ['/my-page', '/my-other-page/'] }` for Node.js API and `--open-target [URL]` (without `[URL]` dev server will open a browser using the `host` option value) and `--open-app <browser>` for CLI
* the `useLocalIp` option was removed in favor `{ host: 'local-ip' }`, alternative you can provide values: `local-ipv4` for IPv4 and `local-ipv6` for IPv6
* `stdin` option was removed in favor `--watch-options-stdin`
* `injectClient` and `injectHot` was removed in favor `client.needClientEntry` and `client.needHotEntry`
### Features
* added the `watchFiles` option, now you can reload server on file changes, for example `{ watchFiles: ['src/**/*.php', 'public/**/*'] }` ([#3136](https://github.com/webpack/webpack-dev-server/issues/3136)) ([d73213a](https://github.com/webpack/webpack-dev-server/commit/d73213ab04b9cae38364a0c68dfc3bdfd8df227f))
* added more CLI options, please run `webpack server --help` ([#3148](https://github.com/webpack/webpack-dev-server/issues/3148)) ([03a2b27](https://github.com/webpack/webpack-dev-server/commit/03a2b27011098b6b98b3d20c4c46a949c4f05355))
* enable overlay by default ([#3108](https://github.com/webpack/webpack-dev-server/issues/3108)) ([5e05e48](https://github.com/webpack/webpack-dev-server/commit/5e05e48a56232038c1341f2c0deae3d35a1add47))
* you can specify multiple targets and browsers for the `open` option, i.e. `{ open: { target: ['/my-page', '/my-other-page'], app: ['google-chrome', '--incognito'] } }` ([e3c2683](https://github.com/webpack/webpack-dev-server/commit/e3c26835fae88a478baad477d537bd0ff1424db9))
### Bug Fixes
* `/webpack-dev-server` url shows list of files ([#3101](https://github.com/webpack/webpack-dev-server/issues/3101)) ([b3374c3](https://github.com/webpack/webpack-dev-server/commit/b3374c3ec2e07e4ba41e4ef40beaff5b9da2eccc))
* dev server client compatibility with `IE11`/`IE10`/`IE9` ([#3129](https://github.com/webpack/webpack-dev-server/issues/3129)) ([1e3e656](https://github.com/webpack/webpack-dev-server/commit/1e3e656b5871456a483401f829a4dd4e67d48863))
* For `IE11`/`IE10` you need polyfill `fetch()` and `Promise`, example:
```js
module.exports = {
entry: {
entry: [
'whatwg-fetch',
'core-js/features/promise',
'./entry.js'
],
},
};
```
* For `IE9` you need polyfill `fetch()` and `Promise` and use `sockjs` for communications (because `WebSocket` is not supported), example:
```js
module.exports = {
entry: {
entry: [
'whatwg-fetch',
'core-js/features/promise',
'./entry.js'
],
},
devServer: {
transportMode: 'sockjs',
},
};
```
IE8 is not supported
* hostname resolving ([#3128](https://github.com/webpack/webpack-dev-server/issues/3128)) ([cd39491](https://github.com/webpack/webpack-dev-server/commit/cd39491ea395c985f2014dfc03379db5c894f711))
* improve CLI options ([#3151](https://github.com/webpack/webpack-dev-server/issues/3151)) ([09fa827](https://github.com/webpack/webpack-dev-server/commit/09fa827c0abbce271fa70f3553b004ff64d16b32))
* output description on invalid options ([#3154](https://github.com/webpack/webpack-dev-server/issues/3154)) ([2e02978](https://github.com/webpack/webpack-dev-server/commit/2e02978f921ebdbda020f746f35c86048de9b2ee))
* prefer to open the `host` option ([#3115](https://github.com/webpack/webpack-dev-server/issues/3115)) ([7e525eb](https://github.com/webpack/webpack-dev-server/commit/7e525ebe35201996d047d14af05709b0b082ae7a))
* reduce number of `dependencies`
## [4.0.0-beta.1](https://github.com/webpack/webpack-dev-server/compare/v4.0.0-beta.0...v4.0.0-beta.1) (2021-03-23)

@@ -7,0 +69,0 @@

8

client/clients/SockJSClient.js
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -17,3 +15,3 @@

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

@@ -26,5 +24,5 @@ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

var SockJS = require('sockjs-client/dist/sockjs');
var SockJS = require('../modules/sockjs-client');
var _require = require('../default/utils/log'),
var _require = require('../utils/log'),
log = _require.log;

@@ -31,0 +29,0 @@

'use strict';
/* global WebSocket */
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -18,3 +15,3 @@

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

@@ -27,3 +24,3 @@ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

var _require = require('../default/utils/log'),
var _require = require('../utils/log'),
log = _require.log;

@@ -30,0 +27,0 @@

@@ -13,3 +13,4 @@ {

"staticOptions": {
"type": "object"
"type": "object",
"additionalProperties": true
},

@@ -38,3 +39,4 @@ "publicPath": {

{
"type": "object"
"type": "object",
"additionalProperties": true
}

@@ -58,2 +60,79 @@ ]

"minLength": 1
},
"OpenBoolean": {
"type": "boolean"
},
"OpenString": {
"type": "string",
"minLength": 1
},
"OpenObject": {
"type": "object",
"additionalProperties": false,
"properties": {
"target": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"minLength": 1
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
]
},
"app": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1
}
]
}
}
},
"WatchFilesString": {
"type": "string",
"minLength": 1
},
"WatchFilesObject": {
"type": "object",
"properties": {
"paths": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
]
},
"options": {
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": false
}

@@ -63,3 +142,4 @@ },

"bonjour": {
"type": "boolean"
"type": "boolean",
"description": "Broadcasts the server via ZeroConf networking on start. https://webpack.js.org/configuration/dev-server/#devserverbonjour"
},

@@ -111,11 +191,34 @@ "client": {

]
},
"needClientEntry": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"needHotEntry": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
}
},
"description": "Specifies client properties. https://webpack.js.org/configuration/dev-server/#devserverclient",
"additionalProperties": false
},
"compress": {
"type": "boolean"
"type": "boolean",
"description": "Enable gzip compression for everything served. https://webpack.js.org/configuration/dev-server/#devservercompress"
},
"dev": {
"type": "object"
"type": "object",
"description": "The bundled files will be available in the browser under this path. https://webpack.js.org/configuration/dev-server/#devserverdev-"
},

@@ -134,6 +237,8 @@ "firewall": {

}
]
],
"description": "Defines routes which are enabled by default, on by default and allows localhost. https://webpack.js.org/configuration/dev-server/#devserverfirewall"
},
"headers": {
"type": "object"
"type": "object",
"description": "Adds headers to all responses. https://webpack.js.org/configuration/dev-server/#devserverheaders"
},

@@ -148,3 +253,4 @@ "historyApiFallback": {

}
]
],
"description": "When using the HTML5 History API, the index.html page will likely have to be served in place of any 404 responses. https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback"
},

@@ -159,3 +265,4 @@ "host": {

}
]
],
"description": "Specify a host to use. If you want your server to be accessible externally. https://webpack.js.org/configuration/dev-server/#devserverhost"
},

@@ -170,6 +277,8 @@ "hot": {

}
]
],
"description": "Enable webpack's Hot Module Replacement feature. https://webpack.js.org/configuration/dev-server/#devserverhot"
},
"http2": {
"type": "boolean"
"type": "boolean",
"description": "Serve over HTTP/2 using spdy. https://webpack.js.org/configuration/dev-server/#devserverhttp2"
},

@@ -233,35 +342,20 @@ "https": {

}
]
],
"description": "By default, dev-server will be served over HTTP. It can optionally be served over HTTP/2 with HTTPS. https://webpack.js.org/configuration/dev-server/#devserverhttps"
},
"injectClient": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"injectHot": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"liveReload": {
"type": "boolean"
"type": "boolean",
"description": "By default, the dev-server will reload/refresh the page when file changes are detected. https://webpack.js.org/configuration/dev-server/#devserverlivereload"
},
"onAfterSetupMiddleware": {
"instanceof": "Function"
"instanceof": "Function",
"description": "Provides the ability to execute custom middleware after all other middleware internally within the server. https://webpack.js.org/configuration/dev-server/#devserverafter"
},
"onBeforeSetupMiddleware": {
"instanceof": "Function"
"instanceof": "Function",
"description": "Provides the ability to execute custom middleware prior to all other middleware internally within the server. https://webpack.js.org/configuration/dev-server/#devserverbefore"
},
"onListening": {
"instanceof": "Function"
"instanceof": "Function",
"description": "Provides an option to execute a custom function when webpack-dev-server starts listening for connections on a port. https://webpack.js.org/configuration/dev-server/#onlistening"
},

@@ -271,16 +365,9 @@ "open": {

{
"type": "string"
"$ref": "#/definitions/OpenBoolean"
},
{
"type": "boolean"
"$ref": "#/definitions/OpenString"
},
{
"type": "object"
}
]
},
"openPage": {
"anyOf": [
{
"type": "string"
"$ref": "#/definitions/OpenObject"
},

@@ -290,7 +377,15 @@ {

"items": {
"type": "string"
"anyOf": [
{
"$ref": "#/definitions/OpenString"
},
{
"$ref": "#/definitions/OpenObject"
}
]
},
"minItems": 1
}
]
],
"description": "Tells dev-server to open the browser after server had been started. Set it to true to open your default browser. https://webpack.js.org/configuration/dev-server/#devserveropen"
},

@@ -308,3 +403,4 @@ "port": {

}
]
],
"description": "Specify a port number to listen for requests on. https://webpack.js.org/configuration/dev-server/#devserverport"
},

@@ -330,9 +426,12 @@ "proxy": {

}
]
],
"description": "Proxying some URLs can be useful when you have a separate API backend development server and you want to send API requests on the same domain. https://webpack.js.org/configuration/dev-server/#devserverproxy"
},
"public": {
"type": "string"
"type": "string",
"description": "When using dev server and you're proxying dev-server, the client script does not always know where to connect to. It will try to guess the URL of the server based on window.location, but if that fails you'll need to use this. https://webpack.js.org/configuration/dev-server/#devserverpublic"
},
"setupExitSignals": {
"type": "boolean"
"type": "boolean",
"description": "It takes a boolean and if true (default on CLI), the server will close and exit the process on SIGINT and SIGTERM. https://webpack.js.org/configuration/dev-server/#devserversetupexitsignals"
},

@@ -364,7 +463,5 @@ "static": {

}
]
],
"description": "It is possible to configure advanced options for serving static files from directory. See the Express documentation for the possible options. https://webpack.js.org/configuration/dev-server/#devserverstatic"
},
"stdin": {
"type": "boolean"
},
"transportMode": {

@@ -394,40 +491,31 @@ "anyOf": [

}
]
],
"description": "This option allows us either to choose the current devServer transport mode for client/server individually or to provide custom client/server implementation. https://webpack.js.org/configuration/dev-server/#devservertransportmode"
},
"useLocalIp": {
"type": "boolean"
"watchFiles": {
"anyOf": [
{
"$ref": "#/definitions/WatchFilesString"
},
{
"$ref": "#/definitions/WatchFilesObject"
},
{
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/WatchFilesString"
},
{
"$ref": "#/definitions/WatchFilesObject"
}
]
}
}
],
"description": "List of files to watch for file changes and serve. https://webpack.js.org/configuration/dev-server/#devserverwatchfiles"
}
},
"errorMessage": {
"properties": {
"bonjour": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverbonjour)",
"client": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devserverclient)",
"compress": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devservercompress)",
"dev": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devserverdev-)",
"firewall": "should be {Boolean|Array} (https://webpack.js.org/configuration/dev-server/#devserverfirewall)",
"headers": "should be {Object} (https://webpack.js.org/configuration/dev-server/#devserverheaders)",
"historyApiFallback": "should be {Boolean|Object} (https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback)",
"host": "should be {String|Null} (https://webpack.js.org/configuration/dev-server/#devserverhost)",
"hot": "should be {Boolean|String} (https://webpack.js.org/configuration/dev-server/#devserverhot)",
"http2": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverhttp2)",
"https": "should be {Object|Boolean} (https://webpack.js.org/configuration/dev-server/#devserverhttps)",
"injectClient": "should be {Boolean|Function} (https://webpack.js.org/configuration/dev-server/#devserverinjectclient)",
"injectHot": "should be {Boolean|Function} (https://webpack.js.org/configuration/dev-server/#devserverinjecthot)",
"liveReload": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverlivereload)",
"onAfterSetupMiddleware": "should be {Function} (https://webpack.js.org/configuration/dev-server/#devserverafter)",
"onBeforeSetupMiddleware": "should be {Function} (https://webpack.js.org/configuration/dev-server/#devserverbefore)",
"onListening": "should be {Function} (https://webpack.js.org/configuration/dev-server/#onlistening)",
"open": "should be {String|Boolean|Object} (https://webpack.js.org/configuration/dev-server/#devserveropen)",
"openPage": "should be {String|Array} (https://webpack.js.org/configuration/dev-server/#devserveropenpage)",
"port": "should be {Number|String|Null} (https://webpack.js.org/configuration/dev-server/#devserverport)",
"proxy": "should be {Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverproxy)",
"public": "should be {String} (https://webpack.js.org/configuration/dev-server/#devserverpublic)",
"setupExitSignals": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserversetupexitsignals)",
"static": "should be {Boolean|String|Object|Array} (https://webpack.js.org/configuration/dev-server/#devserverstatic)",
"stdin": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserverstdin)",
"transportMode": "should be {String|Object} (https://webpack.js.org/configuration/dev-server/#devservertransportmode)",
"useLocalIp": "should be {Boolean} (https://webpack.js.org/configuration/dev-server/#devserveruselocalip)"
}
},
"additionalProperties": false
}

@@ -70,2 +70,7 @@ 'use strict';

this.setupDevMiddleware();
// Should be after `webpack-dev-middleware`, otherwise other middlewares might rewrite response
routes(this);
this.setupWatchFiles();
this.setupFeatures();

@@ -75,3 +80,2 @@ this.setupHttps();

routes(this);
killable(this.server);

@@ -351,2 +355,23 @@ setupExitSignals(this);

setupWatchFiles() {
if (this.options.watchFiles) {
const { watchFiles } = this.options;
if (typeof watchFiles === 'string') {
this.watchFiles(watchFiles, {});
} else if (Array.isArray(watchFiles)) {
watchFiles.forEach((file) => {
if (typeof file === 'string') {
this.watchFiles(file, {});
} else {
this.watchFiles(file.paths, file.options || {});
}
});
} else {
// { paths: [...], options: {} }
this.watchFiles(watchFiles.paths, watchFiles.options || {});
}
}
}
setupMiddleware() {

@@ -524,4 +549,4 @@ this.app.use(this.middleware);

this.server.on('error', (err) => {
throw err;
this.server.on('error', (error) => {
throw error;
});

@@ -593,88 +618,89 @@ }

const useColor = getColorsOption(getCompilerConfigArray(this.compiler));
const protocol = this.options.https ? 'https' : 'http';
const { address: hostname, port } = this.server.address();
const { address, port } = this.server.address();
const prettyPrintUrl = (newHostname) =>
url.format({ protocol, hostname: newHostname, port, pathname: '/' });
let localhostForTerminal;
let networkUrlForTerminalIPv4;
let networkUrlForTerminalIPv6;
let server;
let localhost;
let loopbackIPv4;
let loopbackIPv6;
let networkUrlIPv4;
let networkUrlIPv6;
const parsedIP = ipaddr.parse(hostname);
const isUnspecified = parsedIP.range() === 'unspecified';
if (this.hostname) {
if (this.hostname === 'localhost') {
localhost = prettyPrintUrl('localhost');
} else {
let isIP;
if (isUnspecified) {
localhostForTerminal = prettyPrintUrl('localhost');
try {
isIP = ipaddr.parse(this.hostname);
} catch (error) {
// Ignore
}
if (!isIP) {
server = prettyPrintUrl(this.hostname);
}
}
}
const parsedIP = ipaddr.parse(address);
if (parsedIP.range() === 'unspecified') {
localhost = prettyPrintUrl('localhost');
const networkIPv4 = internalIp.v4.sync();
if (networkIPv4) {
networkUrlForTerminalIPv4 = prettyPrintUrl(networkIPv4);
networkUrlIPv4 = prettyPrintUrl(networkIPv4);
}
if (hostname === '::') {
const networkIPv6 = internalIp.v6.sync();
const networkIPv6 = internalIp.v6.sync();
if (networkIPv6) {
networkUrlForTerminalIPv6 = prettyPrintUrl(networkIPv6);
}
if (networkIPv6) {
networkUrlIPv6 = prettyPrintUrl(networkIPv6);
}
} else if (parsedIP.range() === 'loopback') {
if (parsedIP.kind() === 'ipv4') {
loopbackIPv4 = prettyPrintUrl(parsedIP.toString());
} else if (parsedIP.kind() === 'ipv6') {
loopbackIPv6 = prettyPrintUrl(parsedIP.toString());
}
} else {
if (parsedIP.range() === 'loopback') {
localhostForTerminal = prettyPrintUrl('localhost');
}
networkUrlIPv4 =
parsedIP.kind() === 'ipv6' && parsedIP.isIPv4MappedAddress()
? prettyPrintUrl(parsedIP.toIPv4Address().toString())
: prettyPrintUrl(address);
if (parsedIP.kind() === 'ipv6') {
if (parsedIP.isIPv4MappedAddress()) {
networkUrlForTerminalIPv4 = prettyPrintUrl(
parsedIP.toIPv4Address().toString()
);
}
} else {
networkUrlForTerminalIPv4 = prettyPrintUrl(hostname);
networkUrlIPv6 = prettyPrintUrl(address);
}
}
if (parsedIP.kind() === 'ipv6') {
networkUrlForTerminalIPv6 = prettyPrintUrl(hostname);
}
this.logger.info('Project is running at:');
if (server) {
this.logger.info(`Server: ${colors.info(useColor, server)}`);
}
if (isUnspecified) {
this.logger.info('Project is running at:');
this.logger.info(`Local: ${colors.info(useColor, localhostForTerminal)}`);
if (localhost || loopbackIPv4 || loopbackIPv6) {
const loopbacks = []
.concat(localhost ? [colors.info(useColor, localhost)] : [])
.concat(loopbackIPv4 ? [colors.info(useColor, loopbackIPv4)] : [])
.concat(loopbackIPv6 ? [colors.info(useColor, loopbackIPv6)] : []);
const networkUrlsForTerminal = []
.concat(
networkUrlForTerminalIPv4
? [`${colors.info(useColor, networkUrlForTerminalIPv4)} (IPv4)`]
: []
)
.concat(
networkUrlForTerminalIPv6
? [`${colors.info(useColor, networkUrlForTerminalIPv6)} (IPv6)`]
: []
);
this.logger.info(`Loopback: ${loopbacks.join(', ')}`);
}
this.logger.info(`On Your Network: ${networkUrlsForTerminal.join(', ')}`);
} else {
const networkUrlsForTerminal = []
.concat(
localhostForTerminal
? [`${colors.info(useColor, localhostForTerminal)}`]
: []
)
.concat(
networkUrlForTerminalIPv4
? [`${colors.info(useColor, networkUrlForTerminalIPv4)} (IPv4)`]
: []
)
.concat(
networkUrlForTerminalIPv6
? [`${colors.info(useColor, networkUrlForTerminalIPv6)} (IPv6)`]
: []
);
if (networkUrlIPv4) {
this.logger.info(
`On Your Network (IPv4): ${colors.info(useColor, networkUrlIPv4)}`
);
}
if (networkUrlIPv6) {
this.logger.info(
`Project is running at ${networkUrlsForTerminal.join(', ')}`
`On Your Network (IPv6): ${colors.info(useColor, networkUrlIPv6)}`
);

@@ -723,9 +749,6 @@ }

if (this.options.open || this.options.openPage) {
const uri =
localhostForTerminal ||
networkUrlForTerminalIPv4 ||
networkUrlForTerminalIPv6;
if (this.options.open) {
const openTarget = prettyPrintUrl(this.hostname || 'localhost');
runOpen(uri, this.options, this.logger);
runOpen(openTarget, this.options.open, this.logger);
}

@@ -735,3 +758,11 @@ }

listen(port, hostname, fn) {
this.hostname = hostname;
if (hostname === 'local-ip') {
this.hostname = internalIp.v4.sync() || internalIp.v6.sync() || '0.0.0.0';
} else if (hostname === 'local-ipv4') {
this.hostname = internalIp.v4.sync() || '0.0.0.0';
} else if (hostname === 'local-ipv6') {
this.hostname = internalIp.v6.sync() || '::';
} else {
this.hostname = hostname;
}

@@ -749,4 +780,3 @@ if (typeof port !== 'undefined' && port !== this.options.port) {

this.port = port;
return this.server.listen(port, hostname, (err) => {
return this.server.listen(port, this.hostname, (error) => {
if (this.options.hot || this.options.liveReload) {

@@ -763,3 +793,3 @@ this.createSocketServer();

if (fn) {
fn.call(this.server, err);
fn.call(this.server, error);
}

@@ -772,5 +802,5 @@

})
.catch((err) => {
.catch((error) => {
if (fn) {
fn.call(this.server, err);
fn.call(this.server, error);
}

@@ -959,7 +989,9 @@ })

}
// Serve a page that executes the javascript
const queries = req._parsedUrl.search || '';
const responsePage = `<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body><script type="text/javascript" charset="utf-8" src="${_path}.js${queries}"></script></body></html>`;
res.send(responsePage);
} catch (err) {
} catch (error) {
return next();

@@ -966,0 +998,0 @@ }

@@ -15,6 +15,9 @@ 'use strict';

const decorateConnection = SockjsSession.prototype.decorateConnection;
// eslint-disable-next-line func-names
SockjsSession.prototype.decorateConnection = function (req) {
decorateConnection.call(this, req);
const connection = this.connection;
if (

@@ -21,0 +24,0 @@ connection.headers &&

'use strict';
const url = require('url');
const ip = require('internal-ip');

@@ -12,5 +11,3 @@ function createDomain(options, server) {

if (options.useLocalIp) {
hostname = ip.v4.sync() || '0.0.0.0';
} else if (server) {
if (server) {
hostname = server.address().address;

@@ -17,0 +14,0 @@ } else {

@@ -58,3 +58,3 @@ 'use strict';

const clientEntry = `${require.resolve(
'../../client/default/'
'../../client/'
)}?${domain}${host}${path}${port}`;

@@ -61,0 +61,0 @@

@@ -6,2 +6,3 @@ 'use strict';

let clientImplFound = true;
switch (typeof options.transportMode.client) {

@@ -8,0 +9,0 @@ case 'string':

@@ -101,2 +101,7 @@ 'use strict';

// Enable client overlay by default
if (typeof options.client.overlay === 'undefined') {
options.client.overlay = true;
}
options.client.path = `/${

@@ -103,0 +108,0 @@ options.client.path ? options.client.path.replace(/^\/|\/$/g, '') : 'ws'

@@ -5,3 +5,2 @@ 'use strict';

const { join } = require('path');
const getPaths = require('webpack-dev-middleware/dist/utils/getPaths').default;

@@ -17,11 +16,7 @@ const clientBasePath = join(__dirname, '..', '..', 'client');

createReadStream(join(clientBasePath, 'sockjs/sockjs.bundle.js')).pipe(res);
createReadStream(
join(clientBasePath, 'modules/sockjs-client/index.js')
).pipe(res);
});
app.get('/webpack-dev-server.js', (req, res) => {
res.setHeader('Content-Type', 'application/javascript');
createReadStream(join(clientBasePath, 'default/index.bundle.js')).pipe(res);
});
app.get('/webpack-dev-server/invalidate', (_req, res) => {

@@ -33,76 +28,43 @@ server.invalidate();

app.get('/webpack-dev-server', (req, res) => {
res.setHeader('Content-Type', 'text/html');
middleware.waitUntilValid((stats) => {
res.setHeader('Content-Type', 'text/html');
res.write(
'<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>'
);
res.write(
'<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>'
);
const statsForPrint =
typeof stats.stats !== 'undefined'
? stats.toJson().children
: [stats.toJson()];
const filesystem = middleware.context.outputFileSystem;
const paths = getPaths(middleware.context);
res.write(`<h1>Assets Report:</h1>`);
for (const { publicPath, outputPath } of paths) {
writeDirectory(publicPath, outputPath);
}
statsForPrint.forEach((item, index) => {
res.write('<div>');
res.end('</body></html>');
const name =
item.name || (stats.stats ? `unnamed[${index}]` : 'unnamed');
function writeDirectory(baseUrl, basePath) {
if (baseUrl === 'auto') {
baseUrl = '';
}
res.write(`<h2>Compilation: ${name}</h2>`);
res.write('<ul>');
const content = filesystem.readdirSync(basePath);
const publicPath = item.publicPath === 'auto' ? '' : item.publicPath;
res.write('<ul>');
for (const asset of item.assets) {
const assetName = asset.name;
const assetURL = `${publicPath}${assetName}`;
// sort file data so that files are listed before directories
// this forces Windows to have consistent behavior, as it seems
// to list directories first for the default memfs filesystem
// of webpack-dev-middleware
const fileData = content
.map((item) => {
const p = `${basePath}/${item}`;
return {
item,
isFile: filesystem.statSync(p).isFile(),
path: p,
};
})
.sort((item1, item2) => {
if (item1.isFile && !item2.isFile) {
return -1;
} else if (!item1.isFile && item2.isFile) {
return 1;
// sort alphabetically if both are files or directories
} else if (item1.item < item2.item) {
return -1;
} else if (item2.item < item1.item) {
return 1;
}
return 0;
});
res.write(
`<li>
<strong><a href="${assetURL}" target="_blank">${assetName}</a></strong>
</li>`
);
}
fileData.forEach((data) => {
const { item, isFile, path: p } = data;
if (isFile) {
res.write(`<li><a href="${baseUrl + item}">${item}</a></li>`);
if (/\.js$/.test(item)) {
const html = item.substr(0, item.length - 3);
const containerHref = baseUrl + html;
res.write(`<li><a href="${containerHref}">${html}</a>`);
}
} else {
res.write(`<li>${item}<br>`);
writeDirectory(`${baseUrl + item}/`, p);
res.write('</li>');
}
res.write('</ul>');
res.write('</div>');
});
res.write('</ul>');
}
res.end('</body></html>');
});
});

@@ -109,0 +71,0 @@ }

@@ -8,25 +8,71 @@ 'use strict';

// https://github.com/webpack/webpack-dev-server/issues/1990
let openOptions = { wait: false };
let openOptionValue = '';
const defaultOpenOptions = { wait: false };
const openTasks = [];
if (typeof options.open === 'string') {
openOptions = Object.assign({}, openOptions, { app: options.open });
openOptionValue = `: "${options.open}"`;
} else if (typeof options.open === 'object') {
openOptions = options.open;
openOptionValue = `: "${JSON.stringify(options.open)}"`;
const getOpenTask = (item) => {
if (typeof item === 'boolean') {
return [{ target: uri, options: defaultOpenOptions }];
}
if (typeof item === 'string') {
return [{ target: item, options: defaultOpenOptions }];
}
let targets;
if (item.target) {
targets = Array.isArray(item.target) ? item.target : [item.target];
} else {
targets = [uri];
}
return targets.map((target) => {
const openOptions = defaultOpenOptions;
if (item.app) {
openOptions.app = item.app;
}
return { target, options: openOptions };
});
};
if (Array.isArray(options)) {
options.forEach((item) => {
openTasks.push(...getOpenTask(item));
});
} else {
openTasks.push(...getOpenTask(options));
}
const pages =
typeof options.openPage === 'string'
? [options.openPage]
: options.openPage || [''];
return Promise.all(
pages.map((page) => {
const pageUrl = page && isAbsoluteUrl(page) ? page : `${uri}${page}`;
openTasks.map((openTask) => {
let openTarget;
return open(pageUrl, openOptions).catch(() => {
if (openTask.target) {
if (typeof openTask.target === 'boolean') {
openTarget = uri;
} else {
openTarget = isAbsoluteUrl(openTask.target)
? openTask.target
: new URL(openTask.target, uri).toString();
}
} else {
openTarget = uri;
}
return open(openTarget, openTask.options).catch(() => {
logger.warn(
`Unable to open "${pageUrl}" in browser${openOptionValue}. If you are running in a headless environment, please do not use the --open flag`
`Unable to open "${openTarget}" page${
// eslint-disable-next-line no-nested-ternary
openTask.options.app
? Array.isArray(openTask.options.app)
? ` in "${
openTask.options.app[0]
}" app with "${openTask.options.app
.slice(1)
.join(' ')}" arguments`
: ` in "${openTask.options.app}" app`
: ''
}. If you are running in a headless environment, please do not use the "--open" flag or the "open" option.`
);

@@ -33,0 +79,0 @@ });

@@ -23,9 +23,4 @@ 'use strict';

}
if (server.options.stdin) {
process.stdin.on('end', closeAndExit);
process.stdin.resume();
}
}
module.exports = setupExitSignals;
{
"name": "webpack-dev-server",
"version": "4.0.0-beta.1",
"version": "4.0.0-beta.2",
"description": "Serves a webpack app. Updates the browser on changes.",

@@ -18,8 +18,8 @@ "bin": "bin/webpack-dev-server.js",

"lint:prettier": "prettier \"{**/*,*}.{js,json,md,yml,css}\" --list-different",
"lint:prettier:fix": "npm run lint:prettier -- --write",
"lint:js": "eslint . --cache",
"lint:js:fix": "npm run lint:js -- --fix",
"lint": "npm-run-all -l -p \"lint:**\"",
"lint:fix": "npm run lint:prettier:fix && npm run lint:js:fix",
"lint:type": "tsc --noEmit",
"fix:prettier": "npm run lint:prettier -- --write",
"fix:js": "npm run lint:js -- --fix",
"fix": "npm-run-all fix:js fix:prettier",
"commitlint": "commitlint --from=master",

@@ -31,9 +31,4 @@ "test:only": "jest --forceExit",

"pretest": "npm run lint",
"prepare": "npm run build:client",
"build:client:default": "babel client-src/default --out-dir client/default --ignore \"./client-src/default/*.config.js\"",
"build:client:clients": "babel client-src/clients --out-dir client/clients",
"build:client:index": "webpack --color --config client-src/default/webpack.config.js",
"build:client:sockjs": "webpack --color --config client-src/sockjs/webpack.config.js",
"build:client:transpiled-modules": "webpack --color --config client-src/transpiled-modules/webpack.config.js",
"build:client": "rimraf ./client/* && npm-run-all -s -l -p \"build:client:**\"",
"prepare": "npm run build:client && husky install",
"build:client": "rimraf ./client/* && babel client-src/ --out-dir client/ --ignore \"webpack.config.js\" && webpack --config client/webpack.config.js",
"webpack-dev-server": "node examples/run-example.js",

@@ -52,10 +47,10 @@ "release": "standard-version"

"graceful-fs": "^4.2.6",
"html-entities": "^2.1.1",
"http-proxy-middleware": "^1.0.6",
"html-entities": "^2.3.2",
"http-proxy-middleware": "^1.1.0",
"internal-ip": "^6.2.0",
"ipaddr.js": "^1.9.1",
"ipaddr.js": "^2.0.0",
"is-absolute-url": "^3.0.3",
"killable": "^1.0.1",
"open": "^7.4.2",
"p-retry": "^4.4.0",
"p-retry": "^4.5.0",
"portfinder": "^1.0.28",

@@ -66,7 +61,5 @@ "schema-utils": "^3.0.0",

"sockjs": "^0.3.21",
"sockjs-client": "^1.5.0",
"spdy": "^4.0.2",
"strip-ansi": "^6.0.0",
"url": "^0.11.0",
"util": "^0.12.3",
"webpack-dev-middleware": "^4.1.0",

@@ -76,9 +69,10 @@ "ws": "^7.4.4"

"devDependencies": {
"@babel/cli": "^7.13.10",
"@babel/core": "^7.13.10",
"@babel/cli": "^7.13.14",
"@babel/core": "^7.13.14",
"@babel/plugin-transform-object-assign": "^7.12.13",
"@babel/plugin-transform-runtime": "^7.13.10",
"@babel/preset-env": "^7.13.12",
"@babel/runtime": "^7.13.10",
"@commitlint/cli": "^12.0.1",
"@commitlint/config-conventional": "^12.0.1",
"@commitlint/cli": "^12.1.1",
"@commitlint/config-conventional": "^12.1.1",
"@jest/test-sequencer": "^26.6.3",

@@ -89,4 +83,5 @@ "acorn": "^8.1.0",

"body-parser": "^1.19.0",
"css-loader": "^5.1.3",
"eslint": "^7.22.0",
"core-js": "^3.10.0",
"css-loader": "^5.2.0",
"eslint": "^7.23.0",
"eslint-config-prettier": "^8.1.0",

@@ -98,3 +93,3 @@ "eslint-config-webpack": "^1.2.5",

"html-webpack-plugin": "^4.5.2",
"husky": "^4.3.8",
"husky": "^6.0.0",
"jest": "^26.6.3",

@@ -106,3 +101,3 @@ "jest-circus": "^26.6.3",

"marked": "^2.0.1",
"memfs": "^3.2.0",
"memfs": "^3.2.2",
"npm-run-all": "^4.1.5",

@@ -113,2 +108,3 @@ "prettier": "^2.2.1",

"rimraf": "^3.0.2",
"sockjs-client": "^1.5.1",
"standard-version": "^9.1.1",

@@ -120,4 +116,4 @@ "style-loader": "^2.0.0",

"url-loader": "^4.1.1",
"webpack": "^5.27.2",
"webpack-cli": "^4.5.0",
"webpack": "^5.30.0",
"webpack-cli": "^4.6.0",
"webpack-merge": "^5.7.3"

@@ -124,0 +120,0 @@ },

@@ -71,2 +71,3 @@ <div align="center">

--env <value...> Environment passed to the configuration when it is a function.
--node-env <value> Sets process.env.NODE_ENV to the specified value.
--progress [value] Print compilation progress during build.

@@ -83,2 +84,3 @@ -j, --json [value] Prints result as JSON or store it in a file.

-t, --target <value...> Sets the build target e.g. node.
--no-target Negative 'target' option.
--watch-options-stdin Stop watching when stdin stream has ended.

@@ -97,10 +99,14 @@ --no-watch-options-stdin Do not stop watching when stdin stream has ended.

--bonjour Broadcasts the server via ZeroConf networking on start.
--no-bonjour Do not broadcast the server via ZeroConf networking on start.
--client-progress Print compilation progress in percentage in the browser.
--hot-only Do not refresh page if HMR fails.
--no-client-progress Do not print compilation progress in percentage in the browser.
--client-overlay Show a full-screen overlay in the browser when there are compiler errors or warnings.
--no-client-overlay Do not show a full-screen overlay in the browser when there are compiler errors or warnings.
--setup-exit-signals Close and exit the process on SIGINT and SIGTERM.
--no-setup-exit-signals Do not close and exit the process on SIGNIT and SIGTERM.
--stdin Close when stdin ends.
--open [value] Open the default browser, or optionally specify a browser name.
--use-local-ip Open default browser with local IP.
--open-page <value...> Open default browser with the specified page.
--open [value...] Open the default browser.
--no-open Do not open the default browser.
--open-app <value> Open specified browser.
--open-target [value...] Open specified route in browser.
--no-open-target Do not open specified route in browser.
--client-logging <value> Log level in the browser (none, error, warn, info, log, verbose).

@@ -114,2 +120,3 @@ --history-api-fallback Fallback to /index.html for Single Page Applications.

--no-firewall Disable firewall.
--watch-files <value...> Watch static files for file changes.

@@ -132,4 +139,6 @@ Global options:

```json
"scripts": {
"start:dev": "webpack serve"
{
"scripts": {
"serve": "webpack serve"
}
}

@@ -136,0 +145,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc