Skip to content

WIP: Code splitting and serve through webpack-dev-server #96

New issue

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

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

Already on GitHub? # to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

jthomaschewski
Copy link
Contributor

This PR configures webpack to split everything in node_modules directory into a separate bundle (vendor.bundle.js).
While figuring out how to to this, I also found the proxy option in webpack-dev-server configuration and got it working with meteor. What it does:

All requests to 0.0.0.0:9090 are forwarded to 0.0.0.0:3000 - except assets generated by the dev server. To access the app use 9090 as port instead of 3000 as previously.

This solves some issues:

  • The bundles are served from the same port as the webpage, so the script used to generate the <script> tag is not needed anymore
  • Hot reload works also after errors in JSX code - no more CORS related issues. At least I got any them since. Should fix hot reloading sometimes fails because server doesn't provide CORS header #45 (my fault - it doesn't fix syntax error recovery directly, but it works when using webpack-dev-server iframe mode)

Unsolved / TODO:

  • test production builds/deploy [2]
  • WebSocket connection failed [1] error on every reload
  • XHR finished loading info logs spam in console, change loglevel somehow

Notice: This is more of a discussion than a PR - That's why I added a WIP label (Work In Progress). I was very excited when I found this proxy solution - but maybe there are reasons why this isn't used now and I just don't know them yet.
Maybe some of my changes are useful and can be merged in a separate PR.

[1] WebSocket connection to 'ws://0.0.0.0:9090/sockjs/154/timeznho/websocket' failed: Connection closed before receiving a handshake response - Does not seem to cause issues but doesn't look nice

[2] Had to add vendor bundle to every call in prod, predeploy and dev scripts... Not a nice solution. A more generic solution should be found. Maybe this will be more easily possible with the new webpack plugin.

@jedwards1211
Copy link
Owner

Cool! I had gotten this setup working as well, but I felt ambivalent about the WebSocket connection not working. I'm pretty sure the Meteor WebSocket connection fails to work because webpack-dev-server is already using a WebSocket. If I remember correctly Meteor falls back to using XHRs when it can't use a WebSocket. Maybe not a big deal for development, I'm just not sure whether there's anything to worry about? Using iframe mode doesn't have this problem. To me iframe mode is almost ideal except for one pesky detail: you can't see the app's route in the browser URL bar.

And yeah I'm hoping the new Webpack plugin eliminates the need to make so many changes to the scripts. The question, though, is how best to handle code splitting. Obviously we can automatically add a vendor bundle to a page, but I believe it's possible to use multiple commons chunks such that route A would use commons chunk A and route B would use commons chunk B -- and in that case I don't think there's any way to automatically set up the project so that the correct bundles get loaded in the correct places. I haven't even dug into server side routing myself, which that kind of thing would definitely require. So there's more to investigate before the webpack plugin becomes a full-fledged solution.

@jthomaschewski
Copy link
Contributor Author

Regarding the WebSocket connection: I'm not sure - it seems as if it's working correctly. At least changing something in mongo triggers a instant redraw on the page. This doesn't look like Meteor switched to polling.

Bundles can be created with a name combined with a hash - or some kind of prefix.
Anyway: It might be possible to add some kind of naming schema - everything matching client..bundle.js is automatically moved to meteor_core/client/, server..bundle.js to server/ etc.

That way prod mode should work with auto chunk plugins - or am I missing something?

Only problem: How to load the chunks from webpack dev server in dev mode. Thats problematic as the names of the chunks or unknown. But I think there will be some way to get the list to auto generate loadClientBundle.html.

But that's just my naive theory. It's the first time I'm using webpack so I don't know much about it's internals, how the plugins work exactly etc. I will play a bit more with these bundle things, maybe I find a way...

BTW: Disabling the NoErrorsPlugin fixes hot reload in many error cases. Not all - but e.g a syntax error in BlazeTemplate.js is recovered even in non-iframe mode (Just an example - It doesn't seem to work in the top level component App.jsx - but in second level components it works fine).

@jedwards1211
Copy link
Owner

@JBBr huh, you may be right that the WebSocket connection ends up working. I don't know enough to tell for sure yet.

In contrast to using a naming schema, I think the best thing for the plugin to do (and what it does now) is to move the output assets into <meteor dir>/<publicPath>/<client/server> where publicPath comes from the Webpack config. That way Meteor will serve them up from the same route (I think?) in prod mode as webpack-dev-server does in dev mode.

If the names of the chunks are unknown beforehand, it's no problem: the stats returned by Webpack when it's done compiling give all the final names of the chunks, including hashes if so configured.

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

Successfully merging this pull request may close these issues.

hot reloading sometimes fails because server doesn't provide CORS header
3 participants