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

Use webpack-merge 2.0, fix react hot loader #59

Closed
wants to merge 4 commits into from
Closed

Use webpack-merge 2.0, fix react hot loader #59

wants to merge 4 commits into from

Conversation

eXon
Copy link
Contributor

@eXon eXon commented Dec 29, 2016

Fix #56

All I've done is add unit test for reactHot and update webpack-merge to 2.0.0.

It's a big jump in the version, but it ensures merging the loaders is done correctly for react-hot. However, it looks like the loaders order is now changed a little bit. Not a big deal, but worth testing enough before pushing this.

Copy link
Owner

@andywer andywer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think one change is superfluous and one must be changed, but otherwise fine :)

@@ -18,7 +18,7 @@ export {
*/
function getLoaderConfigByType (context, webpackConfig, fileType) {
const loaderConfig = webpackConfig.module.loaders.find(
(loader) => loader.test === context.fileType(fileType)
(loader) => regexEqual(loader.test, context.fileType(fileType))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have to do a real regex comparison. context.fileType(fileType) should return the same regex reference throughout the whole configuration process.

The only scenario I can think of where it makes a difference: If there are two loader configs matching two file types which have semantically equal regexs to match. But I think we should not even match those as well 😉

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add a comment here making that a little clearer...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is unfortunally not the case anymore when I updated webpack-merge to 2.0.0. A test was failing because it couldn't find the correct loader for text/css.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I propose we first investigate why this is happening. Looks like an easy fix to deep-compare the regexes, but that might be a minor bug in webpack-merge. If so we should not try to fix it afterwards in webpack-blocks, but fix it in webpack-merge.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is because of the deep clone webpack-merge is doing behind the scene. In a strict functional way, it is expected that the Regex instance might be a different one with the same value. I'm not sure it is bad to use a more reliable way to compare regexes. I don't think we can expect two instances with the same value on different loaders. I don't think regex are seen as primitive types in javascript.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really doing a deep clone of the regex (new regex with same value)? I wouldn't expect that... (Or: If it really works this way, maybe this is this the bug 😉)

@@ -23,37 +23,37 @@ test('complete webpack config creation', (t) => {
])

t.is(webpackConfig.module.loaders.length, 8)
t.deepEqual(webpackConfig.module.loaders[0], {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, if the order has changed here, we should re-order the assertions as well. Having the indexes in the order 7, 6, 0, 1, 2 really is confusing.

@andywer
Copy link
Owner

andywer commented Dec 29, 2016

You have some good points here 🙂

Just need to adjust it a little bit.

Copy link
Contributor Author

@eXon eXon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the loaders order. However, for the regex a test was failing because of that. Regex are kinda tricky and if the merge is 100% functional, it probably copy it now.

@@ -18,7 +18,7 @@ export {
*/
function getLoaderConfigByType (context, webpackConfig, fileType) {
const loaderConfig = webpackConfig.module.loaders.find(
(loader) => loader.test === context.fileType(fileType)
(loader) => regexEqual(loader.test, context.fileType(fileType))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is unfortunally not the case anymore when I updated webpack-merge to 2.0.0. A test was failing because it couldn't find the correct loader for text/css.

@andywer
Copy link
Owner

andywer commented Dec 29, 2016

Guess we have to look into that slight comparison issue a little more (see comment in code).

I cannot say when I will be able to have a deeper look into it myself, though. I am at Munich airport between two connecting flights right now and visiting my girlfriend's family for the next few days... But maybe I manage to find some time :)

@andywer
Copy link
Owner

andywer commented Dec 29, 2016

The bright side is, though: The integration tests did their job perfectly fine 👍😄

@andywer andywer changed the title FIx react hot reload Use webpack-merge 2.0, fix react hot loader Dec 30, 2016
@eXon
Copy link
Contributor Author

eXon commented Jan 7, 2017

The problem when comparing with the regex instance instead of the value is it is order specific. Meaning if another block add a loader and then your block adds a loader with the same regex, you don't know it will not use your instance but the existing one.

I honestly believe it's better to go for comparing the regex value. That way, it is more functional :)

@andywer
Copy link
Owner

andywer commented Jan 7, 2017

@eXon Let's discuss this :)

Meaning if another block add a loader and then your block adds a loader with the same regex, you don't know it will not use your instance but the existing one.

If two loaders are going to match the same file extensions then they use the same context.fileType('foo/bar') returning the same regex instance, since that is what the context.fileType is for :) That's how we ensure referential integrity.

The problem about comparing the regex' values is not only that it's slower (I really don't care for this particular use case), but that regex' are bitches that are really hard to compare. If we don't assume referential integrity anymore and always deep-compare the regex' values we encounter a new problem: Regex synonyms. Consider /\.jsx?/ vs /\.js|\.jsx/. Different values, but matching the same extensions.

Referential integrity makes comparing trivial and helps me sleep well at night, without having to fear people open issues, because a comparison does not work for their crazy edge-case 🙈😅

@eXon
Copy link
Contributor Author

eXon commented Jan 7, 2017

@andywer good news! looks like it's not a problem anymore with the last version of webpack-merge 👍

@eXon
Copy link
Contributor Author

eXon commented Jan 8, 2017

Looks like it's still not working. My node_modules folder was not up to date. I'll continue searching why the regex instance is not the same.

@andywer
Copy link
Owner

andywer commented Jan 11, 2017

I was just debugging #76 and tried updating webpack-merge as well.

I found that the last webpack-merge version leaving the regular expressions intact was 1.0.0 1.0.1

@andywer
Copy link
Owner

andywer commented Jan 11, 2017

I stand corrected: webpack-merge v1.0.2 broke it and I even found out why:

They introduced a breaking change and just published as a hot fix version. This commit introduces lodash.cloneDeep to deep-clone any object it sees.

What's happening in webpack-merge (see the commit): _.isPlainObject(/regex/) would be false, but _.isPlainObject({ test: /regex/ }) will be true and I guess the following _.deepClone({ test: /regex/ }) will also deep-clone the regex... :-/

@eXon
Copy link
Contributor Author

eXon commented Jan 11, 2017

When they are comparing the loader test regex, webpack-merge is using String(regex).

Maybe it's good enough for us too?

@andywer
Copy link
Owner

andywer commented Jan 11, 2017

@eXon Yeah, I give in. Let's do it like that as well, but let's add a short comment explaining that we do it because of webpack-merge deep-cloning stuff 😉

@andywer
Copy link
Owner

andywer commented Jan 11, 2017

Created #77, since this was your hot reloading PR. We should start to take more care not to throw different independent features into the same PR. Otherwise we will have "spaghetti PRs" soon :)

@eXon
Copy link
Contributor Author

eXon commented Jan 11, 2017

Well the fix for the hot-reload bug was to upgrade webpack-merge but it will do the job. Awesome thanks 👍

@andywer
Copy link
Owner

andywer commented Jan 11, 2017

@eXon I wasn't even aware of that anymore. So can we close this PR then? Might be good if you check out the latest master and confirm that it works.

@eXon
Copy link
Contributor Author

eXon commented Jan 13, 2017

Your PR diff is almost identical so I'll close this. Thanks for the fix!

@eXon eXon closed this Jan 13, 2017
@eXon eXon deleted the bug/hot-reload branch January 13, 2017 13:20
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.

2 participants