webpack-hot-client
A client for enabling, and interacting with, webpack Hot Module Replacement.
This is intended to work in concert with webpack-dev-middleware
and allows for adding Hot Module Replacement to an existing server, without a
dependency upon webpack-dev-server
. This comes in handy for testing
in projects that already use server frameworks such as Express
or Koa
.
webpack-hot-client
accomplishes this by creating a WebSocket
server, providing
the necessary client (browser) scripts that communicate via WebSocket
s, and
automagically adding the necessary webpack plugins and config entries. All of
that allows for a seamless integration of Hot Module Replacement Support.
Curious about the differences between this module and webpack-hot-middleware
?
Read more here.
Requirements
This module requires a minimum of Node v6.9.0 and Webpack v4.0.0.
Getting Started
To begin, you'll need to install webpack-hot-client
:
$ npm install webpack-hot-client --save-dev
Gotchas
Entries
In order to use webpack-hot-client
, your webpack
config should include an
entry
option that is set to an Array
of String
, or an Object
who's keys
are set to an Array
of String
. You may also use a Function
, but that
function should return a value in one of the two valid formats.
This is primarily due to restrictions in webpack
itself and the way that it
processes options and entries. For users of webpack v4+ that go the zero-config
route, you must specify an entry
option.
Automagical Configuration
As a convenience webpack-hot-client
adds HotModuleReplacementPlugin
and the necessary entries to your webpack
config for you at runtime. Including
the plugin in your config manually while using this module may produce unexpected
or wonky results. If you have a need to configure entries and plugins for HMR
manually, use the autoConfigure
option.
Best Practices
When using this module manually, along with the default port
option value of
0
, starting compilation (or passing a compiler to webpack-dev-middleware
)
should be done after the socket server has finished listening and allocating
a port. This ensures that the build will contain the allocated port. (See the
Express example below.) This condition does not apply if providing a static
port
option to the API.
Express
For setting up the module for use with an Express
server, try the following:
const hotClient = require('webpack-hot-client');
const middleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const config = require('./webpack.config');
const compiler = webpack(config);
const { publicPath } = config.output;
const options = { ... }; // webpack-hot-client options
// we recommend calling the client _before_ adding the dev middleware
const client = hotClient(compiler, options);
const { server } = client;
server.on('listening', () => {
app.use(middleware(compiler, { publicPath }));
});
Koa
Since Koa
@2.0.0 was released, the patterns and requirements for using
webpack-dev-middleware
have changed somewhat, due to use of async/await
in
Koa. As such, one potential solution is to use koa-webpack
,
which wires up the dev middleware properly for Koa, and also implements this
module. If you'd like to use both modules without koa-webpack
, you may examine
that module's code for implementation details.
Browser Support
Because this module leverages native WebSockets
, the browser support for this
module is limited to only those browsers which support native WebSocket
. That
typically means the last two major versions of a particular browser.
Please visit caniuse.com for a full compatibility table.
Note: We won't be accepting requests for changes to this facet of the module.
API
client(compiler, [options])
Returns an Object
containing:
close()
(Function) - Closes the WebSocketServer started by the module.wss
(WebSocketServer) - A WebSocketServer instance.
options
Type: Object
allEntries
Type: Boolean
Default: false
If true and autoConfigure
is true, will automatically configures each entry
key for the webpack compiler. Typically used when working with or manipulating
different chunks in the same compiler configuration.
autoConfigure
Type: Boolean
Default: true
If true, automatically configures the entry
for the webpack compiler, and adds
the HotModuleReplacementPlugin
to the compiler.
host
Type: String|Object
Default: 'localhost'
Sets the host that the WebSocket
server will listen on. If this doesn't match
the host of the server the module is used with, the module may not function
properly. If the server
option is defined, and the server has been instructed
to listen, this option is ignored.
If using the module in a specialized environment, you may choose to specify an
object
to define client
and server
host separately. The object
value
should match { client: <String>, server: <String> }
. Be aware that the client
host will be used in the browser by WebSockets
. You should not use this
option in this way unless you know what you're doing. Using a mismatched
client
and server
host will be unsupported by the project as the behavior
in the browser can be unpredictable and is specific to a particular environment.
The value of host.client
can also be set to a wildcard character for
Remote Machine Testing.
hmr
Type: Boolean
Default: true
If true, instructs the client script to attempt Hot Module Replacement patching of modules.
https
Type: Boolean
Default: false
If true, instructs the client script to use wss://
as the WebSocket
protocol.
When using the server
option and passing an instance of https.Server
, this
flag must also be true. Otherwise, the sockets cannot communicate and this
module won't function properly. The module will examine the server
instance
passed and if server
is an instance of https.Server
, and https
is not
already set, will set https
to true
.
Note: When using a self-signed certificate on Firefox, you must add a "Server
Exception" for localhost:{port}
where {port}
is either the port
or the
port.server
option for secure WebSocket
to work correctly.
logLevel
Type: String
Default: 'info'
Sets the minimum level of logs that will be displayed in the console. Please see webpack-log/#levels for valid values.
logTime
Type: Boolean
Default: false
If true, instructs the internal logger to prepend log output with a timestamp.
port
Type: Number|Object
Default: 0
The port the WebSocket
server should listen on. By default, the socket server
will allocate a port. If a different port is chosen, the consumer of the module
must ensure that the port is free before hand. If the server
option is defined,
and the server has been instructed to listen, this option is ignored.
If using the module in a specialized environment, you may choose to specify an
object
to define client
and server
port separately. The object
value
should match { client: <Number>, server: <Number> }
. Be aware that the client
port will be used in the browser by WebSockets
. You should not use this
option in this way unless you know what you're doing. Using a mismatched
client
and server
port will be unsupported by the project as the behavior
in the browser can be unpredictable and is specific to a particular environment.
reload
Type: Boolean
Default: true
If true, instructs the browser to physically refresh the entire page if / when webpack indicates that a hot patch cannot be applied and a full refresh is needed.
This option also instructs the browser whether or not to refresh the entire page
when hmr: false
is used.
Note: If both hmr
and reload
are false, and these are permanent settings,
it makes this module fairly useless.
server
Type: Object
Default: null
If a server instance (eg. Express or Koa) is provided, the WebSocket
server
will attempt to attach to the server instance instead of using a separate port.
stats
Type: Object
Default: { context: process.cwd() }
An object specifying the webpack stats configuration. This does not typically need to be modified.
validTargets
Type: Array[String]
Default: ['web']
By default, webpack-hot-client
is meant to, and expects to function on the
'web'
build target. However,
you can manipulate this by adding targets to this property. eg.
// will be merged with the default 'web' target
validTargets: ['batmobile']
Communicating with Client WebSockets
Please see the WebSockets documentation.
Remote Machine Testing
Please see the Remote Machine Testing documentation.
Contributing
We welcome your contributions! Please have a read of CONTRIBUTING for more information on how to get involved.