Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove webpack-dev-server/client from entry #1135

Merged
merged 2 commits into from
Apr 22, 2019

Conversation

SleeplessByte
Copy link
Member

@SleeplessByte SleeplessByte commented Apr 17, 2019

Description

According to the webpack-dev-server documentation, the client should not be an entry. It seems to be an old way of configuring (I found this article from 2016 that shows the client as an entry point).

When this line is present, the webpack-dev-server is actually required twice, as you can see in the following image:

  1. once from the entry ('webpack-dev-server/client?...')
  2. once from the plugin ('../../webpack-dev-server/client?...')

This would normally not be an issue. Identical requires are only executed once. However, webpack-dev-server as a plugin expects you to write:

devServer: {
  host: 'hostname-without-scheme',
  port: number
}

And the manual entry expects you to write:

devServer: {
  host: 'http://hostname-without-scheme',
  port: number
}

This results in two unique requires.

This might be a change they made recently, this might be a cross-env issue. I'm not certain. When this line is removed from the configuration, the HMR plugin correct injects this entry into the configuration, only once.

Fixes #1109

Changes/Tasks

  • Changed code

Types of changes

  • Refactoring/add tests (refactoring or adding test which isn't a fix or add a feature)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • I have updated the documentation accordingly
  • I have updated the CHANGELOG with a summary of my changes
  • My changes have tests around them

According to the https://webpack.js.org/guides/hot-module-replacement/ documentation, the client should not be an entry.

It seems to be an old way of configuring (reference: article from 2016 https://medium.com/@rajaraodv/webpacks-hmr-react-hot-loader-the-missing-manual-232336dc0d96).

When this line is removed, the HMR plugin correct _injects_ this entry into the configuration.
@tannerlinsley
Copy link
Contributor

It appears that even after this change, I am seeing 2 versions of only-dev-server and dev-server. Not sure where they're coming from yet, but man... I hate hot-reloading.

@SleeplessByte
Copy link
Member Author

@tannerlinsley that's correct, that's a different "issue". It's probably because you explicitely added 'webpack/hot/only-dev-server', which I don't know about yet :)

I'll read about that next if you'd like and submit another PR.

@SleeplessByte SleeplessByte deleted the hotfix/hmr branch April 22, 2019 22:28
@tannerlinsley
Copy link
Contributor

Ah. I added it because it's mean to override the standard dev server code and not reload the page when things error. It's primarily for supporting things like react-hot-loader that offer inline-reloading of components.

@SleeplessByte
Copy link
Member Author

Got it! I think it's fine (for now) to have both only-dev-server and dev-server, but IIRC, with webpack four, dev-server should be able to support all that.

@dgavara
Copy link

dgavara commented Apr 24, 2019

@tannerlinsley When are you releasing the new version of react-static?

@tannerlinsley
Copy link
Contributor

Still waiting on some changes to play out on master with hot-reloading. Soon.

@SleeplessByte
Copy link
Member Author

SleeplessByte commented Apr 24, 2019

Hey @tannerlinsley. Finally found something sane in the documentation. Combine that with this.

devServer.hotOnly
boolean

Enables Hot Module Replacement (see devServer.hot) without page refresh as fallback in case of build failures.

// webpack.config.js

module.exports = {
  //...
  devServer: {
    hotOnly: true
  }
};

In other words:

  • I think you can remove the hot/only-dev-server line, and rely on hotOnly: true to provide it. Leave the plugin in.
  • This means hot: true is incorrect.

@tannerlinsley
Copy link
Contributor

So remove hot: true and add hotOnly: true?

@SleeplessByte
Copy link
Member Author

Not at my regular machine, so have not tested.

Remove these:

Leave everything else the same.

Can you try that out and see if it works as expected? ❤️

@tannerlinsley
Copy link
Contributor

I'm on it.

@SleeplessByte
Copy link
Member Author

FYI, I'm trying to match this official configuration , but then using the hotOnly option 💯

@tannerlinsley
Copy link
Contributor

Just tried it an hot-reloading fails silently during runtime. Nothing is triggered.

@tannerlinsley
Copy link
Contributor

This is what I have so far:

  • hot: true
    • injects the hot dev client into the browser
    • shows a single listener
    • hot-reloading events are not receieved in the browser
    • hot reloading doesn't work
  • hotOnly: true
    • same as previous
  • hot:true, hotOnly: true
    • same as previous
  • Adding webpack/hot/only-dev-server to any of the above configurations:
    • injects the hot dev client into the browser
    • injects the hotOnly dev client into the browser
    • show 2 listeners
    • hot-reloading events are received in the browser
    • hot reloading works

@tannerlinsley
Copy link
Contributor

I think I know what is happening here:

  • hotOnly is working correctly in webpack dev server

Screen Shot 2019-04-24 at 3 48 08 PM

- Unfortunately, it's using `require.resolve`. Because of this, there end up being 2 different versions/instances of the client, so when the hot events come in to the browser, one instance is receiving them, but has no subscriptions, and the other instance that has the subscription doesn't receive the events.

If webpack-dev-server's code doesn't use require.resolve it works perfectly. Clearly that's not an option (I doubt they would accept a PR like that), so from the other end, I want to figure out which module is trying to import stuff from the webpack-dev-server and instantiating it again. Maybe react-hot-loader?

@SleeplessByte
Copy link
Member Author

Ah, so #1135 (comment) means that the first two options do work correctly if it weren't using require.resolve?

one instance is receiving them, but has no subscriptions, and the other instance that has the subscription doesn't receive the events.

This makes sense that this would be the issue --

Why doesn't require.resolve work? As in, can't we just use that as well?

@SleeplessByte
Copy link
Member Author

react-hot-loader should probably be used on top of hotOnly, right?

@tannerlinsley
Copy link
Contributor

Yes. I don't even know if it's RHL's fault. Something is resolving to a separate copy of the dev server code and not syncing up on the socket instance.

@tannerlinsley
Copy link
Contributor

Here, you can see webpack emitting a hot-reload event through the emitter module:
Screen Shot 2019-04-25 at 10 24 28 AM
And here, you can see where that event is meant to be received and trigger a check (which is what would eventually lead to hot.module.check/accept calls running: Screen Shot 2019-04-25 at 10 24 50 AM

Unfortunately, the underlying emitter is not the same instance between the two, so they never communicate.

@tannerlinsley
Copy link
Contributor

This could even be due to the dev environment of react-static. When npm-linked, webpack (which is running from within react-static files) will resolve to dependencies within react-static instead of the linked project. It's very possible that this isn't even a problem in actual projects that aren't npm-linked, but I don't want that to be an excuse for this not working. We should be able to develop in react-static and on linked projects seamlessly.

Maybe an alias to resolve any emitter imports to the same file would be a good idea?

@SleeplessByte
Copy link
Member Author

This could even be due to the dev environment of react-static. When npm-linked, webpack (which is running from within react-static files) will resolve to dependencies within react-static instead of the linked project. It's very possible that this isn't even a problem in actual projects that aren't npm-linked, but I don't want that to be an excuse for this not working. We should be able to develop in react-static and on linked projects seamlessly.

I wholeheartedly agree with you! This should work regardless of the environment.

Maybe an alias to resolve any emitter imports to the same file would be a good idea?

If that solves this for now, then sure! I'd rather have less duplication / 2 servers running.

@SleeplessByte
Copy link
Member Author

#1135 (comment)

Is this in the same directory? because then it's indeed not the same path.

@tannerlinsley
Copy link
Contributor

Figured it out. An alias in dev mode to resolve webpack/hot/emitter to the same module does the trick!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Local development server broken
3 participants