Code Monkey home page Code Monkey logo

webpack-hot-client's Introduction

npm node deps tests chat size

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 WebSockets, 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.

License

webpack-hot-client's People

Contributors

alecmev avatar jounqin avatar kamilbrk avatar lynxtaa avatar michael-ciniawsky avatar michaelbergquistsuarez avatar ndelangen avatar noppa avatar pqml avatar ryanclark avatar shellscape avatar theprivileges avatar threehams avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webpack-hot-client's Issues

Multiple Entrypoints with HtmlWebpackPlugin

  • Operating System: all
  • Node Version: all
  • NPM Version: all
  • webpack Version: 4.6.0
  • webpack-hot-client Version: 2.2.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
{
  entry: {
    main: ['zone.js/dist/zone', './src/main.ts'],
    styles: ['./src/styles.scss', './src/theme.scss'],
    polyfills: ['./src/polyfills.ts'],
    scripts: ['./node_modules/hammerjs/hammer.min.js'],
  },
}

Expected Behavior

In this scenario, hot-client is applying the client entry to each of the entries listed here. In a multi-page scenario, where only one entry per page is being loaded, this is acceptable. In a MultiCompiler scenario this is acceptable.

Actual Behavior

In a scenario where html-webpack-plugin is being used to combine all entries into a single html file for single-page applications, this will cause unwanted side effects:

  • The client entries is applied to all entry compilations, resulting in each entry script on the same page vying for control of the page.
  • Multiple client WebSockets will be created on the same page.

For Bugs; How can we reproduce the behavior?

For Features; What is the motivation and/or use-case for the feature?

We need some kind of mechanism to combat this and configure things correctly for each scenario. There are also going to be exceptions, where for some reason someone will want what is normally incorrect behavior. We also need to be opinionated on what the default behavior is.

This will be a breaking change.

Default

The client entry should only be added to the first config entry of any type of compilation - single or multi.

For a MultiCompiler config the client should only be added to the first entry of the first compilation config. Not sure in which scenarios this is needed.

Introduce autoEntry: false option to disable automatic injection of the client and HotModuleReplacementPlugin so users can manually configure their compilers as needed.

docs: Difference with Webpack Hot Middleware

  • This is a bug
  • This is a feature request
  • This is a modification request

Hi, I have gone away from the template a little to make it more clear, feel free to close if it was out of line.

Difference with Webpack Hot Middleware

Would be nice if the documentation could state what the difference between this project and Webpack Hot Middleware. Does not need to be a list of features or anything like that, could just be the goals of this project made clear. My assumption is that this will be recommended way going forward since it's part of the webpack-contrib organization but maybe they both are good alternatives for different use cases.

Drop (revert) `allEntries` option in favor `autoConfigure`

  • Operating System: Ubuntu 18.04
  • Node Version: 10.2.1
  • NPM Version: 6.1.0
  • webpack Version: 4.10.0
  • webpack-hot-client Version: 3.0.0
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

i think not required

Expected Behavior

We implement allEntries option (but not released). After spend a lot of time on migration from webpack-dev-server to webpack-serve in many projects (i use git version and build script, because i needed add hot client not only first entry point) i found this option is misleading and unnecessary.

We already have autoConfigure option and we can implement more universal solution:

  1. autoConfigure: true (maybe add alias first) - mean modify only first entry (as works right now).
  2. autoConfigure: 'all - modify all entries.
  3. autoConfigure: ['list', 'of', 'entries'] - modify only entries which in array.

This values of option are enough in 99% use case. Also no new option and more universal solution.

Actual Behavior

allEntries configure only all entry points. Also no easy solution to configure list of entries.

For Bugs; How can we reproduce the behavior?

not the bug

For Features; What is the motivation and/or use-case for the feature?

not the feature

Feature Request: Support Filtering Warnings

  • Operating System: N/A
  • Node Version :N/A
  • NPM Version: N/A
  • webpack Version: N/A
  • webpack-hot-client Version: 4.0.3
  • This is a bug
  • This is a feature request
  • This is a modification request

What is the motivation and/or use-case for the feature?

Webpack supports filtering warnings by default using the stats field in the configuration object, which is very neat on some use-cases. It would be nice if the webpack-hot-client would also support this pattern and not just a flag for enabling/disabling warnings and errors in general.
Documentation for stats describing : https://webpack.js.org/configuration/stats/
Implementation in webpack: https://github.com/webpack/webpack/blob/949890acdf1d00d9e53054b56ad3e7215215416d/lib/Stats.js#L26

`logLevel` is not honoured by client logger (?)

I am investigating webpack-contrib/webpack-serve#289. After adding console logs, I can see the logLevel is passed through to this module. I can also see that we assign the logLevel option value to the client log:

log.level = options.logLevel;

However, in my testing, this doesn't seem to actually effect the log level in my browser console. I still get warnings even when logLevel is set to error, for example.

Sorry I couldn't provide a small test case to reproduce the exact issue. It's not easy to do when you're trying to navigate between lots of small modules, as is the case with webpack-serve et al.

I also skimmed the docs of loglevelnext, which this module uses, to see if I could find documentation demonstrating the behaviour of re-assigning the level property to effect the log level—to no avail.

Need to see a working example

Documentation Is:

  • Missing
  • Needed
  • Confusing
  • Not Sure?

Please Explain in Detail...

I'd like to see more examples; possibly and actual working project, so I could replicate exactly what you've done. I've implemented the small example into my own project, but I haven't seen it work yet. It might be a timing issue where Express loads before hotClient and that's causing the .use statement in .on('listening') to not work properly. Either way, this isn't described in the docs. Even copy-pasting that example doesn't give any working code.

Another example is the server prop. I don't know what this does. What if I already have a WebSocket instance running on that port? Will I still be able to use the server prop?

Your Proposal for Changes

I think it'd be best to have a full example in there with the various options like passing in a server prop so we know what everything does and how to use it.

reload is broken

  • Operating System: Ubuntu 18.04
  • Node Version: 8.11.3
  • NPM Version: 6.2.0
  • webpack Version: 4.16.1
  • webpack-hot-client Version: 4.1.1

Expected Behavior

Page doesn't reload.

Actual Behavior

Page should reload.

Code

https://github.com/webpack-contrib/webpack-serve/blob/master/docs/addons/static-content-options.config.js

How Do We Reproduce?

  1. Run example above.
  2. Change something in app.js (page has not been reloaded, because initial: true -> https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/client/index.js#L30 and https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/client/index.js#L78)
  3. Change something again (page has been reloaded, all fine)
  4. Change again something in app.js (page has not been reloaded, because after reload page initial was setted in true https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/client/index.js#L30)

Related problem with css (style-loader and css-loader) - first change not applied because initial: true.

Duplicated “single” runtime

  • Operating System: Alpine 3.7.0
  • Node Version: 10.6.0
  • NPM Version: 6.1.0
  • webpack Version: 4.15.1
  • webpack-hot-client Version: 4.1.1

Expected Behavior

When optimization.runtimeChunk is single the client script should be injected in the runtime only.

Actual Behavior

The client script is injected in the runtime then the runtime is injected in the entrypoint. Also HMR doesn't work without allEntries: true; not sure if it's normal.

EDIT: it's normal I just didn't understand I needed it in my case.

Code

webpack.config.js

https://gist.github.com/MatTheCat/2e11f1ddbdf8bee2663fa2a5d2a227a2

serve.config.js

module.exports = {
  clipboard: false,
  devMiddleware: {
    publicPath: '/pattern-library/dist/'
  },
  hotClient: {
    host: {
      client: '*',
      server: 'webpack'
    },
    port: {
      client: +process.env.WEBPACK_HOT_PORT,
      server: 8081
    }
  },
  host: '0.0.0.0'
}

How Do We Reproduce?

Enable webpack-hot-client with optimization.runtimeChunk = 'single'.

feat: Overlay support request

  • This is a bug
  • This is a feature request
  • This is a modification request

Hi, I have gone away from the template a little to make it more clear, feel free to close if it was out of line.

Overlay support

The current implementation logs everything in the console in a really nice way and it would be sweet to also have the option to use an overlay similar to the one used in create-react-app #1101 and like what can be enabled in Webpack Hot Middleware using the overlay option.

This can probably be supported in one of two ways.

  1. Adding a overlay that can be enabled through configuration.
  2. Add documentation on how this can be done manually using a standalone overlay with potentially some new hooks for integration.

Or maybe this is out of scope entirely?

Unable to run well with Docker

  • Operating System: macOS Mojave
  • Node Version: v10.9.0
  • NPM Version: 6.2.0
  • webpack Version: 4.17.1
  • webpack-hot-client Version: 4.1.1

Expected Behavior

Run well with Docker

Actual Behavior

connection closed before receiving a handshake response connect @ socket.js:19 (anonymous) @ socket.js:47

Code

https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/client/socket.js#L12

How to manually set webSocket.port?

I'm using koa-webpack which uses koa-hot-client actually, webSocket server port in Docker should be 0.0.0.0 so that we can connect it outside Docker container, but then websock in client side uses 0.0.0.0 also, it that possible to set them separately?

How Do We Reproduce?

https://github.com/JounQin/docker-study/tree/bug/koa-hot-client

Install Docker first, then run yarn dev:build and yarn dev, open http://localhost:7000.

You can change the code above to hostname: window.location.hostname, then it will work correctly.

`babel` related packages should be included in `devDependencies`

  • Operating System: macOS 10.12
  • Node Version: v9.3.0
  • NPM Version: 5.6.0
  • webpack Version: 3.10.0
  • webpack-dev-server Version: none
  • This is a bug
  • This is a feature request
  • This is a modification request

Expected Behavior

Run well with babel 7, @babel/preset-env,etc

Actual Behavior

Error: Couldn't find preset "@babel/env" relative to directory "/local/GitHub/react-hackernews"

For Features; What is the motivation and/or use-case for the feature?

babel is not needed after published for this module.

Webpack-Hot-Client not working with entrypoints at different routes

  • Operating System: Windows 10 64-bit
  • Node Version: 8.11.3
  • yarn Version: 1.8.0
  • webpack Version: 4.16.0
  • webpack-hot-client Version: 4.1.1

Expected Behavior

Webpack-Hot-Client runs on all entrypoints on all routes.

Actual Behavior

Webpack-Hot-Client only runs on routes that reference back to / and not any other routes using differing entrypoints.

Code

Webpack Entrypoint Configs

Client

  entry: {
    app: [
      'react-hot-loader/patch',
      '/app/entrypoints/client.js',
    ],
    tests: [
      'react-hot-loader/patch',
      '/app/entrypoints/clientTests.js',
    ],
  },

Server

  entry: {
    app: '/app/entrypoints/server.js',
    tests: '/app/entrypoints/serverTests.js',
  },

Express Config

.get('/tests', '/bundles/serverTests.js')
.all('*', '/bundles/server.js')

HTML

/

<script defer src="/app.client.js" />

/tests

<script defer src="/tests.client.js" />

How Do We Reproduce?

Setup a path in Express on / to run one entrypoint and set another path on /something to run a different entrypoint. Only the entrypoint at / will get Webpack-Hot-Client.

Allow specifying client "server host" independently (from server "host")

  • Operating System: Linux desmas-l.desmas 4.15.0-1-amd64 #1 SMP Debian 4.15.4-1 (2018-02-18) x86_64 GNU/Linux buster/sid
  • Node Version: v9.6.0
  • NPM Version: 5.6.0
  • webpack Version: 4.1.1
  • webpack-hot-client Version: 2.0.0
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js

Expected Behavior

Actual Behavior

For Bugs; How can we reproduce the behavior?

For Features; What is the motivation and/or use-case for the feature?

It's conceivable that the client will be configured to connect to the server via a different host/port. This can be accommodated with minimal code change, simply by allowing to specify a different host/port for the client.

For example, imagine the server (webpack-hot-client, and thus webpack proper) is running on a hypervisor guest ("inside a virtual machine"; Vagrant, etc.), or contained inside an LXC container (Docker), or behind a reverse proxy, or even on a remote machine. As it stands, the codes assume the client environment is the same as the server and forces the use of the server options (https://github.com/webpack-contrib/webpack-hot-client/blob/master/index.js#L55).

Trivially, this could be done by allowing a webSocket.host/webSocket.port option (https://github.com/webpack-contrib/webpack-hot-client#clientcompiler-options). This could be improved/normalized however appropriate.

Less trivially, and more generally, the codes could check for a webpack-hot-client/client entry before augmenting and skip the step if it exists. This would allow a user-in-the-know to manually configure all of the client options (if I understand the code correctly, that is).

My particular use-case is "containerized build via Docker," and using 0.0.0.0 as the host option gets me what I need, but is a real hack (as the client connects to the socket on ws://0.0.0.0, and 0.0.0.0 is not required to resolve, though implementations tend to allow it: https://unix.stackexchange.com/questions/419880/connecting-to-ip-0-0-0-0-succeeds-how-why)

Readme example of passing a `server`

  • This is a bug
  • This is a feature request
  • This is a modification request

I'm attempting to set config options for webpack-hot-client in koa-webpack.

It'd be useful to see an example in the readme of passing in a server object, so that the WebSockets port used can sync with the main HTTP server.

There are two things that are unclear from the current readme.

  1. Should server be an instance of Express/Koa, or the instance returned by Node's http.createServer()?

  2. If it's the latter (and it seems to be, given the calls to .address().address/port here, then how should a server object be passed to Express/Koa middleware before the server has been created, either by a call to koa.listen() or by creating a separate server with http.createServer(koa.callback())?

My suggestion is therefore is to either:

a) Add an example to the readme to show how this can be done manually

or (and this is probably an issue for koa-webpack, but I'll suggest it here for now to avoid redundancy)

b) Automatically set the server option when using koa-webpack, since that's more likely to be able to set it automatically through the Koa ctx object.

I apologise in advance if I'm missing anything obvious - on initial glance, this seems to be a circular dependency (middleware needs a server, but the server won't be created until the middleware has already been set up) that the readme doesn't address.

hot doesn't work when you have two or more websocket clients

  • Operating System: Ubuntu 18.04
  • Node Version: v8.11.3
  • NPM Version: 6.2.0
  • webpack Version: 4.16.1
  • webpack-hot-client Version: 4.1.1

Expected Behavior

When two/more websocket clients connected all should get messages (hash, ok and etc).

Actual Behavior

When you have two websocket clients, only first connected get information, second don't get nothing (i.e. hot doesn't work es expected) on connection.

Now

Code

Example from webpack-serve https://github.com/webpack-contrib/webpack-serve/blob/master/docs/addons/watch-content.config.js

How Do We Reproduce?

  1. Clone repo from example
  2. Look on WS messages in dev tools.

Why?

After run example above websocket client from example (https://github.com/webpack-contrib/webpack-serve/blob/master/docs/addons/watch-content.config.js#L25) connected first and websocket server send messages, when i open development site, websocket client from hot client (https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/client/socket.js#L18) connected to websocket server, but don't get messages due in server.clients.size === 1 (https://github.com/webpack-contrib/webpack-hot-client/blob/master/lib/socket-server.js#L71) and hot doesn't work as expected.

It is regression, because in webpack-hot-client@3 all works fine:

Solution:

  1. Return behavior from webpack-hot-client@3
  2. net.Server from (https://github.com/webpack-contrib/webpack-serve#listening) should contain websocker server (server.wss property) to allow send messages without additional websocket clients (in some cases developers can use more when one websocket client, looks it is bad solution)

Can't read log output on dark theme Chrome or FireFox because the font color isn't high contrast

  • Operating System: Darwin 17.4.0
  • Node Version: 9.5.0
  • NPM Version 5.6.0
  • webpack Version 4.1.1
  • webpack-hot-client Version: 1.3.0
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

See https://github.com/joshunger/bugrepro

Expected Behavior

A user can read the logs.

Actual Behavior

Can't read the logs because of the text color.
image

For Bugs; How can we reproduce the behavior?

Clone https://github.com/joshunger/bugrepro

cd bugrepro
yarn
yarn start

Open browser.
Change devtools to Dark Theme in Chrome or FireFox.
Load URL.

For Features; What is the motivation and/or use-case for the feature?

Error output in browser contains ANSI escape codes

  • Operating System: MacOS Sierra
  • Node Version: 8.11.1
  • NPM Version: 5.6.0
  • webpack Version: 4.5.0
  • webpack-hot-client Version: 2.2.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

I've been witnessing this with a more complex setup, but just created a simple usecase:
https://github.com/mcjfunk/hot-output-issue

Expected Behavior

Error output in browser is legible.

Actual Behavior

Error output contains ANSI escape codes as if for the terminal. It looks like the colors that the error uses are the culprit. They look nice in the terminal, but not the browser:

screen shot 2018-04-16 at 8 01 53 pm

Here's the error, in all its glory, within the mac terminal:
screen shot 2018-04-16 at 8 16 47 pm

For Bugs; How can we reproduce the behavior?

In the repo above...

  1. run npm start
  2. open localhost:8080 in browser
  3. in src/index.js remove a ( from the ReactDOM.render line creating a syntax error.
  4. view the output in the browser

Please note, I'm not entirely sure the fix for this resides in webpack-hot-client. Logging takes place here, but it's unclear if cleansing the error that is delivered is its responsibility. But I thought I'd start the conversation here.

I'd love for there to be a magic config option that I've missed, but I've searched and tried many things without luck.

Thanks!

Build time reported by webpack always has 11 seconds added to it

  • Operating System: macos
  • Node Version: v8.5.0
  • NPM Version: 5.3.0
  • webpack Version: 4.9.1
  • webpack-serve Version: 1.0.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

Repo is available at https://github.com/eddiesholl/webpack-timing-bug

Expected Behavior

Continuing discussion from webpack-contrib/webpack-serve#152.

The build time reported by webpack should be correct.

Actual Behavior

When webpack runs inside webpack-serve, the build time reported by webpack is 11 seconds longer than it should be, because react-hot-client is pushing the startTime back by 11 seconds at

result.startTime -= timefix; // eslint-disable-line no-param-reassign
.

This is a fix/hack to try to avoid issues when watching files that have been created recently. There is a solution in place in webpack-serve to use time-fix-plugin to roll this time back and then forward again, which should hopefully end up with the correct startTime in place. But this explicit rollback here in react-hot-client will always push the value out, it is not cleaned up anywhere. It needs a symmetrical roll forward of the startTime.

For Bugs; How can we reproduce the behavior?

Repo linked above with simple reproduction steps.

`module.hot` is replaced by `false` on development

This issue is moved from webpack/webpack#6276

  • Operating System: macOS 10.12
  • Node Version: v9.3.0
  • NPM Version: 5.6.0
  • webpack Version: 4.0.0-alpha.4
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

// webpack.config.js
import path from 'path'

import HtmlWebpackPlugin from 'html-webpack-plugin'
import webpack from 'webpack'

const NODE_ENV = process.env.NODE_ENV || 'development'

const isProd = NODE_ENV === 'production'

export default {
  mode: NODE_ENV,
  output: {
    filename: `[name].[${isProd ? 'chunkhash' : 'hash'}].js`,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'src/index.html',
      minify: {
        collapseWhitespace: isProd,
      },
    }),
  ],
}
// src/index.js
if (module.hot) {
  console.log('This will never be called')
}

Expected Behavior

log 'This will never be called'

Actual Behavior

module.hot is replaced by false, and log will never be called

For Bugs; How can we reproduce the behavior?

https://github.com/JounQin/webpack-next-study/tree/module.hot

branch module.hot, simply run yarn dev and open http://localhost:4000

it seems reload not working while ignored an update to unaccepted module

Just read a little bit code of webpack-hot-client, in lib/client/hot.js, unaccepted module has been handled like this:

onUnaccepted(data) {
    const chain = [].concat(data.chain);
    const last = chain[chain.length - 1];

    if (last === 0) {
      chain.pop();
    }

    log.warn(`Ignored an update to unaccepted module ${chain.join(' ➭ ')}`);
 }

just warnings no refresh. and what I saw in my project is no refresh.
I suppose there should be a refresh here for:

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.

or maybe I can do a pull request.

sorry for my poor english😄

Error when loading webpack-hot-client from a package that brings it in

  • Operating System: Windows 10 64-bit
  • Node Version: 8.11.3
  • yarn Version: 1.8.0
  • webpack Version: 4.16.0
  • webpack-hot-client Version: 4.1.1

Expected Behavior

Webpack-Hot-Client loads as usual.

Actual Behavior

ERROR in multi webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e react-hot-loader/patch ./app/entrypoints/client
Module not found: Error: Can't resolve 'webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e' in '[FULL PROJECT PATH]'
 @ multi webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e react-hot-loader/patch ./app/entrypoints/client app[0]

ERROR in multi webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e react-hot-loader/patch [NODE_MODULES_PATH]/app/entrypoints/clientTests
Module not found: Error: Can't resolve 'webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e' in '[FULL PROJECT PATH]'
 @ multi webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e react-hot-loader/patch ../apps-client-packages/app/entrypoints/clientTests tests[0]

ERROR in multi webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e react-hot-loader/patch ./app/entrypoints/angularJs
Module not found: Error: Can't resolve 'webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e' in '[FULL PROJECT PATH]'
 @ multi webpack-hot-client/client?4fabb837-9d08-4ee3-a3c2-5a114dfd758e react-hot-loader/patch ./app/entrypoints/angularJs angularJs[0]

I receive this error probably because the app I'm in brings in another package which itself has webpack-hot-client pulled in. It's looking in ./app instead of app. None of these files are in the relative root of the config file ./. For whatever reason, this works in the package, but not when the package is running from node_modules/.

Outputting the entrypoint paths, I'm seeing this:

client [FULL PROJECT PATH]\app\entrypoints\client
clientTests [NODE_MODULES PATH]\app\entrypoints\clientTests
angularJs [FULL PROJECT PATH]\app\entrypoints\angularJs

I don't exactly know what's going on here.

Code

index.js

require('app-module-path/register')
require('package-in-node-modules')

Package's index.js

require('app-module-path/register')
require('scripts/runWebpack')()

Package's Webpack config

  entry: {
    app: [
      'react-hot-loader/patch',
      '[FULL PROJECT PATH]\app\entrypoints\client',
    ],
    tests: [
      'react-hot-loader/patch',
      '[NODE_MODULES PATH]\app\entrypoints\clientTests',
    ],
    angularJs: [
      'react-hot-loader/patch',
      '[FULL PROJECT PATH]\app\entrypoints\angularJs',
   ],
  },

How Do We Reproduce?

Create an npm package that contains the webpack code and run that code from an app that uses that npm package. That's how I'm doing it at least. Seems to be the only difference between the two.

TypeScript Error.

  • Operating System: Windows
  • Node Version:9.0.0
  • NPM Version:5.0.0
  • webpack Version:2.2
  • webpack-hot-client Version:
  • [ x] This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
  // additional code, remove if not needed.

Expected Behavior- APp should run

Actual Behavior- Everytime it is showing the typescript error.

For Bugs; How can we reproduce the behavior?

For Features; What is the motivation and/or use-case for the feature?

Client WebSockets Should Use Channels

  • Operating System: all
  • Node Version: all
  • NPM Version: all
  • webpack Version: 4.6.0
  • webpack-hot-client Version: 2.2.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
n/a

Expected Behavior

n/a

Actual Behavior

n/a

For Bugs; How can we reproduce the behavior?

n/a

For Features; What is the motivation and/or use-case for the feature?

Client WebSockets that originate from hot-client should use channels to specify that they're intended for HMR purposes and are not third-party sockets. Log message should be updated to include the channel. Broadcast should be updated to be able to target a channel.

`warningsFilter` is not honoured

  • Operating System: macOS 10.13.5
  • Node Version: 9.8.0
  • NPM Version: 5.10.0
  • webpack Version: 4.12.0
  • webpack-hot-client Version: 4.1.1

Expected Behavior

webpack's stats.warningsFilter should be honoured in the log output of webpack-hot-client.

Actual Behavior

webpack's stats.warningsFilter is not honoured in the log output of webpack-hot-client.

Code

{
  stats: {
    warningsFilter: /export .* was not found in/
  }
}

image

How Do We Reproduce?

Define a stats.warningsFilter and observe the log output.

TypeError: Cannot read property 'beforeCompile' of undefined

  • Operating System: Windows 10 64-bit
  • Node Version: 8.11.2
  • NPM Version: yarn 1.6.0
  • webpack Version: 3.11.0
  • webpack-hot-client Version: 4.0.4
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
  // additional code, remove if not needed.
  modifyCompiler(compiler, options) {
    for (const comp of [].concat(compiler.compilers || compiler)) {
      // since there's a baffling lack of means to un-tap a hook, we have to
      // keep track of a flag, per compiler indicating whether or not we should
      // add a DefinePlugin before each compile.
      comp.hotClient = { optionsDefined: false };

      comp.hooks.beforeCompile.tap('WebpackHotClient', () => {
        if (!comp.hotClient.optionsDefined) {
          comp.hotClient.optionsDefined = true;

Looking at this code, it creates a brand new array, then tries to do comp.hooks.beforeCompile on that array. Since there's no null-propagation, it will error because hooks hasn't yet been defined on that array.

Expected Behavior

I can run Express without this erroring.

Actual Behavior

I receive an error:

TypeError: Cannot read property 'beforeCompile' of undefined
    at modifyCompiler (webpack-hot-client\lib\compiler.js:136:18)
    at module.exports (webpack-hot-client\lib\index.js:22:3)
    at Object.<anonymous> (scripts\server\develop\getHttpServerConfig.js:20:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (scripts\server\develop\index.js:1:91)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
i 「hot」: WebSocket Server Listening on localhost:56699

For Bugs; How can we reproduce the behavior?

Call webpackHotClient and pass the webpackCompiler object.

webpackHotClient(webpackCompiler)

For Features; What is the motivation and/or use-case for the feature?

N/A

Client port ignored

  • Operating System: Alpine 3.7.0
  • Node Version: 10.6.0
  • NPM Version: 6.1.0
  • webpack Version: 4.15.1
  • webpack-hot-client Version: 4.1.0

Expected Behavior

Websocket client uses client port.

Actual Behavior

Websocket client try using server port.

Code

  $ webpack-serve docs/webpack.config.js
serve.config.js
module.exports = {
  clipboard: false,
  devMiddleware: {
    publicPath: '/pattern-library/dist/'
  },
  hotClient: {
    allEntries: true,
    host: {
      client: '*',
      server: '127.0.0.1'
    },
    port: {
      client: 8082,
      server: 8081
    }
  },
  host: '0.0.0.0'
}

How Do We Reproduce?

Set hotClient.port as an object with different ports for client and server.

I tracked the issue until modifyCompiler. options.webSocket changes between the function call and beforeCompile event. No idea why.

`allEntries: true` only configures the first entry

  • Operating System: MacOS 10.13.4
  • Node Version: v9.10.1
  • NPM Version: 6.1.0
  • webpack Version: 4.10.2
  • webpack-hot-client Version: 3.0.0
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
  entry: {
    app: ['./client/app'],
    admin: ['./client/admin']
  }
  // ...
// Using webpack-serve
serve({
  config: require('./webpack.config.js'),
  host: 'localhost',
  port: '3000',
  logLevel: 'debug',
  // options passed to webpack-hot-client
  hot: {
    allEntries: true,
    autoConfigure: true
  },
  dev: {
    publicPath: '/',
    headers: { 'Access-Control-Allow-Origin': '*' },
    stats: {
      colors: true,
      children: false
    }
  }
});

Expected Behavior

webpack-hot-client is configured with both entry points, app and admin.

Actual Behavior

webpack-hot-client is only configured with the first entry:

 [0] multi ./client/app 28 bytes {app} [built]
[14] multi ./client/admin 28 bytes {admin} [built]
[17] multi webpack-hot-client/client?b068869c-deaf-4240-811a-b153750bcbd8 ./client/app 40 bytes {app} [built]

If I switch the entry points around, like so:

  // webpack.config.js
  entry: {
    admin: ['./client/admin'],
    app: ['./client/app']
  }
  // ...

Then only the admin entry point is enabled:

 [0] multi ./client/admin 28 bytes {admin} [built]
 [9] multi ./client/app 28 bytes {app} [built]
[17] multi webpack-hot-client/client?5b77d4a2-d4cd-490c-aa0a-9f704bf2f2be ./client/admin 40 bytes {admin} [built]

For Bugs; How can we reproduce the behavior?

See above?

For Features; What is the motivation and/or use-case for the feature?

To have HMR enabled on both entry points (main app and admin app).

Add server/client configuration to port option (like with "host" option)

  • Operating System: Ubuntu 18.04
  • Node Version: 8.11.1
  • NPM Version: 6.0.0
  • webpack Version: 4.12.0
  • webpack-hot-client Version: 4.0.3
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

// Suggested Configuration:
{
      host: {
        client: "my.website.com",
        server: "0.0.0.0"
      },
      https: true,
      port:{
        client: false, // number or false
        server: 8081
      }
    }

For Features; What is the motivation and/or use-case for the feature?

This would allow users who have a proxy configuration set up to allow the default port 443 for wss:// connections to work as intended. The issue I'm having is that the address the websocket tries to listen over is wss://my.website.com:8081 which means I have to set my nginx server running on docker to also listen to port 8081 as well as 443. The ideal way this would work for me would be that the client just tries to connect to wss://my.website.com without any port information added. Then it would route correctly through 443

Granular Control of Compilation Errors and Warnings In Client Console

  • Operating System: all
  • Node Version: all
  • NPM Version: all
  • webpack Version: 4.6.0
  • webpack-hot-client Version: 2.2.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
n/a

Expected Behavior

n/a

Actual Behavior

n/a

For Bugs; How can we reproduce the behavior?

n/a

For Features; What is the motivation and/or use-case for the feature?

Much of the time compilation errors and warnings in the client/browser console are just noise. Introduce options that allow for preventing compilation errors and warnings in the browser console.

How to delay auto reload?

hi, i'm currently running fullstack project. is there any way to delay automatic reload for about 0.5s? i want to load server before client. for now client loads before server and that forces me to refresh page manually (server resources aren't ready for client)

hot-client should also be available with target "electron-renderer"

  • Operating System: Arch Linux 4.15.10-1-ARCH x86_64
  • Node Version: 9.8.0
  • NPM Version: 5.7.1
  • webpack Version: 4.1.1
  • webpack-hot-client Version: 2.0.0
  • This is a bug
  • This is a feature request
  • This is a modification request

I'm struggling on build a development envirement with Electron and HMR enabled, so the config.target was set to "electron-renderer". The dev-server.js below aims to start server with hot reload, so I chose webpack-serve. However when I create Electron BorwserWindow points to that server address, not-reload not presented as expected.

if (compiler.options.target !== 'web') {
return;
}

code above seems to provide hot-client to target "web" only. After deleted those lines in my local node_modules, hot-reload seems to work.

so why "electron-renderer" is not accepted by default? Is it by design, or just other reasons?

Code

webpack.config.renderer.js
'use strict';

const webpack = require('webpack');
const packageJson = require('../package.json');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const { absPath, DefaultEnv } = require('./util');

let cfg = {
    mode: DefaultEnv,
    context: absPath('src/renderer'),
    target: 'electron-renderer',
    entry: {
        renderer: ['./index.tsx']
    },
    output: {
        path: absPath('dist/static'),
        filename: '[name].js'
    },
    resolve: {
        extensions: ['.js', '.ts', '.tsx', '.json'],
    },
    performance: {
        hints: false
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader'
                })
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'less-loader']
                })
            },
            {
                test: /\.ts$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.tsx$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            babelrc: false,
                            plugins: [
                                "babel-plugin-syntax-jsx",
                                ["babel-plugin-inferno", { imports: true }]
                            ]
                        }
                    },
                    'ts-loader'
                ],
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                use: {
                    loader: 'file-loader',
                    query: {
                        name: 'imgs/[name].[ext]'
                    }
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                use: {
                    loader: 'file-loader',
                    query: {
                        name: 'fonts/[name].[ext]'
                    }
                }
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('styles.css')
    ]
};
util.js
'use strict';

const { join } = require('path');

const DefaultEnv = process.env.NODE_ENV || 'development';
const ProjectRoot = join(__dirname, '..');

function absPath(...paths) {
    return join(ProjectRoot, ...paths);
}

module.exports = {
    DefaultEnv,
    absPath
};
dev-server.js
const rendererCfg = require('./webpack.config.renderer');

const serve = { host: '127.0.0.1', port: 5146 };
const hot = { host: '127.0.0.1', port: 5147 };

WebpackServe({
    config: rendererCfg,
    clipboard: false,
    hot: hot,
    ...serve
});

Expected Behavior

hot-client should also work with target "electron-renderer"

Actual Behavior

there won't be hot-reload with target "electron-renderer"

Option to set websocket path

Feature Use Case

Using webpack-hot-client under some sort of orchestration system to tie together a bunch of microservers, like an ingress server in minikube or the kubernetes in docker-for-mac

Feature Proposal

Allow the websocket path to be specified both on the client and the server. I'd prefer they both be set the same so I don't need to use url-rewriting.

Current ugly workaround

setting options:

host: {
    server: '0.0.0.0',
    client: 'localhost/hot',
},
port: 3002

and useing the ingress:

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hot
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/ssl-redirect: "false"
    nginx.org/websocket-services: "app"
    nginx.ingress.kubernetes.io/rewrite-target: '/'
spec:
  rules:
  - http:
      paths:
        - path: /hot:3002
          backend:
            serviceName: app
            servicePort: 3002

It's an ugly hack, but by setting host.client to 'localhost/hot', the resulting url is 'ws://localhost/hot:3002'

README: client per entry vs single client per all entries

  • Operating System: macOS 10.13.4
  • Node Version: 8.10.0
  • NPM Version: 5.80
  • webpack Version: 4.8.2
  • webpack-hot-client Version: 3.0.0
  • This is a bug
  • This is a feature request
  • This is a modification request

Description

I am using webpack-hot-client together with webpack-serve. Now with version 3.0.0 being out and #53 and #58 merged, how can one configure webpack-hot-client to have a client per entry as opposed to only one client per all entries? Would be great to have it mentioned somewhere in the README

logLevel "info" too verbose

Operating System: MacOS Sierra
Node Version: 8.11.1
NPM Version: 5.6.0
webpack Version: 4.5.0
webpack-hot-client Version: 2.2.2

  • This is a bug
  • This is a feature request
  • This is a modification request

What is the motivation and/or use-case for the feature?

For application development, since the browser console is the go-to area for debugging, it is distracting to have webpack-hot-client to be so chatty. But by setting logLevel to "error" silences everything. Since HMR can feel like voodoo at times with the developer thinking, "did that update?", we don't want it to be completely silent.

Ideas:

1) logLevel: "info"

  • Start up messages are currently useful 👍
  • During HMR, this lib outputs 6 lines to the console, including the modules that were updated.
  • Instead, during HMR, how about one line: 「hot」 App updated at 3:32:13 PM
  • The timestamp becomes useful when things have updated many times, it helps distinguish updates

2) logLevel: "debug"

  • Put those extra lines that I'm suggesting be removed from "info" here.
  • It seems to me those are only useful when debugging webpack-serve or webpack-hot-client, which, once things are working, isn't very often at all.

Thanks for considering this. I'm digging these new libs and want to see them succeed.

Read `window.location` for client host

  • Operating System: Linux
  • Node Version: v9.11.1
  • NPM Version: 5.6.0
  • webpack Version: 4.6.0
  • webpack-hot-client Version: 2.2.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

diff --git a/lib/client/socket.js b/lib/client/socket.js
index aec287c..7182107 100644
--- a/lib/client/socket.js
+++ b/lib/client/socket.js
@@ -8,8 +8,8 @@ let retry = maxRetries;
 
 module.exports = function connect(options, handler) {
   const socketUrl = url.format({
-    protocol: options.https ? 'wss' : 'ws',
-    hostname: options.webSocket.host,
+    protocol: window.location.protocol === 'https:' ? 'wss' : 'ws',
+    hostname: window.location.hostname,
     port: options.webSocket.port,
     slashes: true
   });

(It should of course not look like this since the normal ways of specifying the socket url should still work. This is just to relay the idea.)

For Features; What is the motivation and/or use-case for the feature?

Instead of having to specify the client host for the websocket server, it would be nice if it was possible to use the window.location host (and perhaps the protocol, https/http) instead of having to hardcode that before the server is run.

In some setups it is possible to access a host with many different ip addresses that are isolatet from each other. Our current setup runs the webpack hot client on the host machine and then uses multiple virtual machines running different os and web browser for testing purposes. In this setup each of the virtual machines could have a different ip address for this machine.

It would also make it easier to test this in a setup where your computer is connected to multiple networks, with multiple network cards. This is another setup that we have as well.

Is this something that you would conciser adding? If so I'll write up a better patch for this. Perhaps specifying a function to the host field or adding a new setting for this?

Allow specifying client "server host" independently (from server "host")

It's conceivable that the client will be configured to connect to the server via a different host/port. This can be accommodated with minimal code change, simply by allowing to specify a different host/port for the client.

For example, imagine the server (webpack-hot-client, and thus webpack proper) is running on a hypervisor guest ("inside a virtual machine"; Vagrant, etc.), or contained inside an LXC container (Docker), or behind a reverse proxy, or even on a remote machine. As it stands, the codes assume the client environment is the same as the server and forces the use of the server options (https://github.com/webpack-contrib/webpack-hot-client/blob/master/index.js#L55).

Trivially, this could be done by allowing a webSocket.host/webSocket.port option (https://github.com/webpack-contrib/webpack-hot-client#clientcompiler-options). This could be improved/normalized however appropriate.

Less trivially, and more generally, the codes could check for a webpack-hot-client/client entry before augmenting and skip the step if it exists. This would allow a user-in-the-know to manually configure all of the client options (if I understand the code correctly, that is).

My particular use-case is "containerized build via Docker," and using 0.0.0.0 as the host option gets me what I need, but is a real hack (as the client connects to the socket on ws://0.0.0.0, and 0.0.0.0 is not required to resolve, though implementations tend to allow it: https://unix.stackexchange.com/questions/419880/connecting-to-ip-0-0-0-0-succeeds-how-why)

Crash, invalid hook returns number as filePath

  • Operating System: Fedora 29
  • Node Version: 10.15.0
  • NPM Version: 6.4.1
  • webpack Version: 4.28.4
  • webpack-hot-client Version: 4.1.1

Expected Behavior

I expect that webpack hot client updates normally.

Actual Behavior

After functioning correctly for a while, it crashes semi-randomly. The crash is produced because the function invalid in webpack-hot-client/lib/index.js expects filePath to be a string, but it was the number 1552056541813 at the time of crash.

<path>/node_modules/webpack-hot-client/lib/index.js:49
      .replace(context, '')
       ^

TypeError: (filePath || "<unknown>").replace is not a function
    at invalid (<path>/node_modules/webpack-hot-client/lib/index.js:49:8)
    at comp.hooks.invalid.tap (<path>/node_modules/webpack-hot-client/lib/index.js:65:7)
    at SyncHook.eval [as call] (eval at create (<path>/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
    at Watchpack.watcher.compiler.watchFileSystem.watch (<path>/node_modules/webpack/lib/Watching.js:139:33)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at Watchpack.emit (events.js:214:7)
    at Watchpack._onChange (<path>/node_modules/watchpack/lib/watchpack.js:118:7)
    at Watchpack.<anonymous> (<path>/node_modules/watchpack/lib/watchpack.js:109:8)
    at emitOne (events.js:116:13)
    at Watcher.emit (events.js:211:7)
    at DirectoryWatcher.<anonymous> (<path>/node_modules/watchpack/lib/DirectoryWatcher.js:238:13)
    at _combinedTickCallback (internal/process/next_tick.js:132:7)
    at process._tickCallback (internal/process/next_tick.js:181:9)

Why does webpack return a number as filePath? I don't know, perhaps it is due to:

  • Using webpack chucks
  • Using default memory-fs as filesystem
  • Editing the entry file
  • In a directory watched by webpack, editing a file not included in the compilation .

Code

module.exports = function createWebpackHotCompiler (config) {
  Object.keys(config.entry).forEach(entryName => {
    if (! Array.isArray(config.entry[entryName])) {
      config.entry[entryName] = [config.entry[entryName]];
    }
  });

  const compiler = webpack(config);
  webpackHotClient(compiler, { port: 9090 });

  const middleware = webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
  });

  return {
    compiler,
    middleware,
  };
};

How Do We Reproduce?

// webpack-config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin');
const HTMLPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    app: './app/entry-client.js'
  },
  output: {
    filename: '../ssr/bundle.json',
    path: './assets',
    publicPath: '/assets',
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
        test: /\.s?css$/,
        use: [ 'vue-style-loader', 'css-loader', 'sass-loader' ]
      },
      {
        test: /\.styl(us)?$/,
        use: [ 'vue-style-loader', 'css-loader', 'stylus-loader' ]
      },
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
    new VuetifyLoaderPlugin(),
    new VueSSRClientPlugin({
      filename: '../ssr/clientManifest.json',
    }),
    new HTMLPlugin({
      template: '../template-no-ssr.html',
      filename: 'index.html',
      inject: 'body',
      showErrors: false,
    }),
  ],
};

Browser not reloading on unaccepted changes

  • Operating System: Darwin 17.4.0
  • Node Version: 9.6.1
  • NPM Version: 5.6.0
  • webpack Version: 4.0.1
  • webpack-hot-client Version: 2.0.0
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

You can clone the repo at mgoggin/react-app for an example.

Expected Behavior

When a project file is changed and that module is unaccepted by webpack-hot-client and reload is configured as true, the browser should reload to pull down the newest changes.

Actual Behavior

Webpack compiles the project and the update is sent to the browser, but nothing changes since the module is unaccepted, even though reload is explicitly set to true.

For Bugs; How can we reproduce the behavior?

Multiple bundles result in duplicate logging

Operating System: MacOS Sierra
Node Version: 8.11.1
NPM Version: 5.6.0
webpack Version: 4.5.0
webpack-hot-client Version: 2.2.2

  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js (webpack 4)
     entry: {
        vendor: [
            'react',
            'react-dom'
        ]
    },
    optimization: {
        splitChunks: {
            name: 'vendor',
            minChunks: Infinity
        }
    }
    ...

Expected Behavior

Browser output messages once.

Actual Behavior

Each log line it output twice:
screen shot 2018-04-18 at 3 08 15 pm

It gets really messy with errors. Each error is repeated twice.

I'm curious what happens with code splitting but haven't setup a test with it yet.

For Bugs; How can we reproduce the behavior?

Setup webpack to create a vendor or common bundle, or I bet multiple entrypoints. Start things up, look at browser console.

Thanks again!

auto inject hotModuleReplacement of mini-css-extract-plugin

  • Operating System:
    window10 x64
  • Node Version:
    v 10.16.2
  • NPM Version:
    Node built-in
  • webpack Version:
    v4.39.1
  • webpack-hot-client Version:
    v4.1.2

Feature Proposal

Auto inject mini-css-extract-plugin/dist/hmr/hotModuleReplacement.js like auto inject HotModuleReplacement code.

Now,I must config webpack entry like:

entry: {
    index: ["mini-css-extract-plugin/dist/hmr/hotModuleReplacement.js",path.join(__dirname, "./src/entry-client.js")]
  },

I wish to config less, such as:

entry: {
    index: [path.join(__dirname, "./src/entry-client.js")]
  },

Feature Use Case

In development,hot replace css

Entry as an object-of-arrays-of-strings does not work

  • Operating System: macOS High Sierra
  • Node Version: 10.7.0
  • NPM Version: Yarn 1.7.0
  • webpack Version: 4.16.2
  • webpack-hot-client Version: 4.1.1

Expected Behavior

When entry is configured as described in the README:

..., or an Object who's keys are set to an Array of String.

HMR should detect and handle updates correctly.

Actual Behavior

HMR does not function as expected. Updates are shown in the console, but always show "No Modules Updated". Sample console log:

「hot」 Hot Module Replacement Enabled. Waiting for signal.
「hot」 WebSocket connected
「hot」 App updated. Recompiling src/style.scss
「hot」 webpack: Compiling (<unnamed compiler>)
「hot」 App Updated, Reloading Modules
「hot」 Checking for updates to the bundle.
「hot」 No Modules Updated.
「hot」 App is up to date.

In addition, this seems to prevent fallback to full-page reload from working. A manual reload is required to pick up the changes.

Code

Webpack config: https://gist.github.com/ezzatron/bb4f0609e513d75fd98d070b99fe83c2#file-webpack-config-js

How Do We Reproduce?

I have since "fixed" the issue on the master branch of that same repo, but it required me to use a simple array-of-strings entry configuration, which has flow-on effects for my chunk splitting configuration, which was using the entrypoint name as a way to differentiate chunks.

Module not found: Error: Can't resolve 'webpack-hot-client/client?main'

  • Operating System: Linux
  • Node Version: v8.9.3
  • NPM Version: 5.5.1
  • webpack Version: ^3.10.0
  • webpack-dev-server Version: N/A
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

I'll try to provide a simpler example, meanwhile, here is the full code:

Entry point where the dev middleware is loaded
https://github.com/larriereguichet/universal-react-app/blob/webpack-hot-client/src/server/index.js

Webpack client configuration used by the middleware
https://github.com/larriereguichet/universal-react-app/blob/webpack-hot-client/packages/webpack-config/src/client.js

webpack-hot-client configuration
https://github.com/larriereguichet/universal-react-app/blob/webpack-hot-client/packages/react-dev-middleware/src/index.js

Expected Behavior

N/A

Actual Behavior

ERROR in multi webpack-hot-client/client?main ./src/client/index.js
Module not found: Error: Can't resolve 'webpack-hot-client/client?main' in '...'

For Bugs; How can we reproduce the behavior?

git clone [email protected]:larriereguichet/universal-react-app.git
cd universal-react-app
git checkout webpack-hot-client
lerna bootstrap
lerna run build
npm start

For Features; What is the motivation and/or use-case for the feature?

N/A

Respect "host" option even when "server" is specified

  • Operating System: Windows 10 x64
  • Node Version: 8.11.1
  • NPM Version: N/A (using Yarn 1.5.1)
  • webpack Version: 4.6.0
  • webpack-hot-client Version: 2.2.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
import * as Koa from "koa";
import * as koaWebpack from "koa-webpack";
function hmr(app, server) {
    // server parameter is a Node.js https.Server instance
    app.use(koaWebpack({
        compiler,
        hot: {
            https: true,
            host: "localhost",
            // Pass in the server instance so it can be used by hot module replacement
            server,
            // Reload page if modules can't be patched
            reload: true
        } as any
    }));
}

Expected Behavior

Since server is https.Server, it uses a certificate, which is tied to a host name (localhost in my case). However, server.address() returns the resolved address 127.0.0.1. webpack-hot-client should use host option (which contains value localhost) in client entry code.

Actual Behavior

The resolved address 127.0.0.1 is used in client entry code, causing this error:
WebSocket connection to 'wss://127.0.0.1:8081/' failed: Error in connection establishment: net::ERR_CERT_COMMON_NAME_INVALID
If I manually create a secure WebSocket in browser console like this: var wsc = new WebSocket("wss://localhost:8081"), it works fine.

For Bugs; How can we reproduce the behavior?

Using https.Server as the server option.

For Features; What is the motivation and/or use-case for the feature?

"TypeError: Converting circular structure to JSON" thrown at init when passing in a server instance

  • Operating System: Mac OS X
  • Node Version: 8.9.4
  • NPM Version: 5.6.0
  • webpack Version: [email protected]
  • webpack-dev-server Version: N/A (see explanation in "How to Reproduce")
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

This can be reproduced using the webpack-hot-client project itself. Refer to the "How to Reproduce" section.

Expected Behavior

webpack-hot-client should initialize without an error when supplying a Koa server instance, as the docs mention Koa as a valid source to provide a server instance.

Actual Behavior

webpack-hot-client throws this error:

    TypeError: Converting circular structure to JSON
      at JSON.stringify (<anonymous>)
      at modifyCompiler (/Volumes/foo/work/webpack-hot-client/lib/util.js:7:95)
      at module.exports (/Volumes/foo/work/webpack-hot-client/index.js:3:157)
      at Context.it (/Volumes/foo/work/webpack-hot-client/test/tests/init.js:47:23)

For Bugs; How can we reproduce the behavior?

I've been able to reproduce this error with the webpack-hot-client project itself.

  1. Clone the webpack-hot-client repo. I tested with the project at revision cfca82eb1e1.
  2. Install koa:
  1. Add a new test to test/tests/init.js, to test this scenario:
const Koa = require('koa');

it('should allow passing koa server instance', () => {
  const app = new Koa();
  const server = app.listen(8081);
  const config = require('../fixtures/webpack.config.js');
  const compiler = webpack(config);
  const options = { hot: true, logLevel: 'info', test: true, server: server };
  const { close } = client(compiler, options);
  assert(true);
});

For Features; What is the motivation and/or use-case for the feature?

socket is triggered twice with webpack 4

  • Operating System: linux
  • Node Version: 9.5.0
  • NPM Version: 5.6.0
  • webpack Version: 4.0.1
  • webpack-hot-client Version: 2.0.0
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js
// nothing to display
  // additional code, remove if not needed.
// same...

Expected Behavior

Webpack hot client websocket connects once

Actual Behavior

Webpack hot client websocket connects twice

I've in the console of chrome dev tools:

log.js:48 「hot」 Hot Module Replacement Enabled. Waiting for signal.
log.js:48 「hot」 WebSocket connected
log.js:48 「hot」 Hot Module Replacement Enabled. Waiting for signal.
log.js:48 「hot」 WebSocket connected
log.js:48 「hot」 App Updated, Reloading Modules

I have two websocket connections.

For Bugs; How can we reproduce the behavior?

Use webpack 4.

For Features; What is the motivation and/or use-case for the feature?

Bundled code includes `eval()`, requiring a relaxed CSP

  • Operating System: OSX
  • Node Version: 8.11.3
  • NPM Version: [email protected]
  • webpack Version: 4.9.2
  • webpack-hot-client Version: 4.1.1

Expected Behavior

Webpack hot client should be able to work without requiring an 'unsafe-eval' CSP.

Actual Behavior

I think that requiring the "dist" version of loglevelnext like this results in bundling code with eval()'d modules:

const loglevel = require('loglevelnext/dist/loglevelnext');

Snippet from the resulting bundle:

/***/ "./lib/LogLevel.js":
/*!*************************!*\
  !*** ./lib/LogLevel.js ***!
  \*************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n/* global window: true */\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar PrefixFactory = __webpack_require__(/*! ../factory/PrefixFactory */ \"./factory/PrefixFactory.js\");\n\nvar MethodFactory = __webpack_require__(/*! ./MethodFactory */ \"./lib/MethodFactory.js\");\n\nvar defaults = {\n  factory: null,\n  level: 'warn',\n  name: +new Date(),\n  prefix: null\n};\n\nmodule.exports =\n/*#__PURE__*/\nfunction () {\n  function LogLevel(options) {\n    _classCallCheck(this, LogLevel);\n\n    // implement for some _very_ loose type checking. avoids getting into a\n    // circular require between MethodFactory and LogLevel\n    this.type = 'LogLevel';\n    this.options = Object.assign({}, defaults, options);\n    this.methodFactory = options.factory;\n\n    if (!this.methodFactory) {\n      var factory = options.prefix ? new PrefixFactory(this, options.prefix) : new MethodFactory(this);\n      this.methodFactory = factory;\n    }\n\n    if (!this.methodFactory.logger) {\n      this.methodFactory.logger = this;\n    }\n\n    this.name = options.name || '<unknown>'; // this.level is a setter, do this after setting up the factory\n\n    this.level = this.options.level;\n  }\n\n  _createClass(LogLevel, [{\n    key: \"disable\",\n    value: function disable() {\n      this.level = this.levels.SILENT;\n    }\n  }, {\n    key: \"enable\",\n    value: function enable() {\n      this.level = this.levels.TRACE;\n    }\n  }, {\n    key: \"factory\",\n    get: function get() {\n      return this.methodFactory;\n    },\n    set: function set(factory) {\n      factory.logger = this;\n      this.methodFactory = factory;\n      this.methodFactory.replaceMethods(this.level);\n    }\n  }, {\n    key: \"level\",\n    get: function get() {\n      return this.currentLevel;\n    },\n    set: function set(logLevel) {\n      var level = this.methodFactory.distillLevel(logLevel);\n\n      if (level == null) {\n        throw new Error(\"loglevelnext: setLevel() called with invalid level: \".concat(logLevel));\n      }\n\n      this.currentLevel = level;\n      this.methodFactory.replaceMethods(level);\n\n      if (typeof console === 'undefined' && level < this.levels.SILENT) {\n        // eslint-disable-next-line no-console\n        console.warn('loglevelnext: console is undefined. The log will produce no output.');\n      }\n    }\n  }, {\n    key: \"levels\",\n    get: function get() {\n      // eslint-disable-line class-methods-use-this\n      return this.methodFactory.levels;\n    }\n  }]);\n\n  return LogLevel;\n}();\n\n//# sourceURL=webpack://log/./lib/LogLevel.js?");

/***/ }),

I'm not sure off the top of my head why the dist specifically is being require'd instead of require("loglevelnext") (which I don't think would have this problem).

I know it's probably a little unusual to set a CSP like this in development, but it reflects the way that the code is run in production.

How Do We Reproduce?

Set a CSP that prohibits 'unsafe-eval'.

README: mention to omit the `HotModuleReplacementPlugin`

  • Operating System: OSX
  • Node Version: 8.11.0
  • NPM Version: 5.6.0
  • webpack Version: 4.6.0
  • webpack-hot-client Version: 2.2.2
  • This is a bug
  • This is a feature request
  • This is a modification request

Description

Was using the API for setting up middleware and was not seeing hot reloading and getting a maximum callstack error. I had to omit HotModuleReplacementPlugin from my plugins and all worked. Might be worth a mention in the README. It's great that webpack is working towards zero config, without having to add the entry scripts etc. but I had to dig through source code to see that you were already including HotModuleReplacementPlugin

Browser keeps refreshing with multiple entry points/configurations

  • Operating System: Windows 7
  • Node Version: 6.10
  • NPM Version: 5.3.0
  • webpack Version: 4.6.0
  • webpack-serve Version: 1.0.2

This issue is for a:

  • bug
  • feature request
  • modification request

Code

This the webpack-serve API code.

const config = require('webpack.config')
serve({
 config,
 logLevel: 'trace',
 dev: {
   publichPath: '/'
 },
 add: (app, middleware) => {
   middleware.webpack();
   middleware.content({
      index: 'index.html'
   });
 }
});
webpack.config.js
module.exports = [
  {
     entry: {
       index: [path.resolve(__dirname, 'app.js')],
     },
     mode: 'development',
     output: {
       filename: 'output.js',
     }
  }
  {
     entry: {
       index: [path.resolve(__dirname, 'iframe-app.js')],
     },
     mode: 'development',
     output: {
       filename: 'iframe-bundle.js',
     }
  }
]
<!-- index.html from where I serve my bundles -->

<html>
  <body>
      <iframe src="http://localhost:8080/iframe.html">

      </iframe>
     <script src="output.js"></script>
  </body>
</html>
<!-- iframe.html where I load the second bundle -->

  <div>
     <script src="iframe-bundle.js"></script>
  </div>

Expected Behavior

It should serve both bundles without refreshing the whole web page.

Actual Behavior

The browsers keeps refreshing every time the iframe gets rendered and loads the second output.

How Do We Reproduce?

I managed to have the same 'refreshing loop' by having two entry points that are loaded in the same page or by recreating a situation like mine (which could take longer).

TypeError: webpack-hot-client: `entry` Object values must be an Array

  • Operating System: Windows 7
  • Node Version: 8.9.4
  • NPM Version: 5.2.0
  • webpack Version: ^3.10.0
  • webpack-dev-server Version: Not using it, rather using koa-webpack
  • koa-webpack: ^2.0.3
  • This is a bug
  • This is a feature request
  • This is a modification request

Code

  // webpack.config.js

module.exports = {
  entry: [
    'babel-polyfill', // Support promise for IE browser (for dev)
    'react-hot-loader/patch',
    'webpack-hot-middleware/client?reload=true',
    './src/client.js'
  ]

Expected Behavior

Should not throw above error since entry is an array.

Actual Behavior

Throws TypeError: webpack-hot-client: entry Object values must be an Array

For Bugs; How can we reproduce the behavior?

Just try using an array in the entry section.

This is a bad check. const type = typeof entry will report object for arrays.

Doing a console.log immediately after that line (I modified local node_modules) produces this which only confirms my assertion:

console.log(entry, type, Array.isArray(entry))

// outputs 
[ 'babel-polyfill',
  'react-hot-loader/patch',
  'webpack-hot-middleware/client?reload=true',
  './src/client.js' ] object true

Because of that L#132 gets executed which causes this error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.