60frames / webpack-hot-server-middleware

:fire: Hot reload webpack bundles on the server
MIT License
324 stars 50 forks source link

webpackDevMiddleware fails to host files at publicPath #19

Closed faceyspacey closed 7 years ago

faceyspacey commented 7 years ago

I've fallen back to using new WriteFilePlugin()

and

app.use(
  publicPath,
  express.static(outputPath),
)

I.e. hosting the files from the file system manually. But I shouldn't have to do that. I noticed this PR to webpack-dev-middleware:

https://github.com/webpack/webpack-dev-middleware/pull/151

So I'm curious how this package successfully hosted files if webpack-dev-middleware itself is struggling to host files from a multi-compiler.

...ps. otherwise, amazing package! I love that require-from-string implementation, pure magic!

rherwig commented 7 years ago

I encountered the problem myself using the following code in dev env.

app.use(require('webpack-hot-server-middleware')(compiler));
app.use('/assets', express.static(path.join(__dirname, 'assets')));

I instead switched to app.get() and it worked.

Like so:

app.get('/', require('webpack-hot-server-middleware')(compiler));

Sadly, this causes browser routing to stop working, due to express wanting to handle the requested route directly. Only alternative is hash routing, which is not that cool

Edit: When I switched static path and middleware statement it works.

app.use('/assets', express.static(path.join(__dirname, 'assets')));
app.use(require('webpack-hot-server-middleware')(compiler));

I suppose that express processes the routes in the occurence order

faceyspacey commented 7 years ago

@rherwig did you use something like write-file-webpack-plugin to write the files to the filesystem first?

Until the following are fixed, I'm trying to find a way that doesn't require an additional webpack plugin in order to make a package I'm working on require as few extra things as possible: https://github.com/webpack/webpack-dev-server/issues/641 https://github.com/webpack/webpack-dev-middleware/pull/151

rherwig commented 7 years ago

I did not use any plugins, except loaders (js, scss).

All my assets (i.e. images) are located in /assets. I use an .ejs template to reference them.

<link rel="icon" href="/assets/icon.png"/>

richardscarrott commented 7 years ago

@faceyspacey I've been unable to reproduce this issue, could you push up an example repo so I can do some investigation / work out what I've been doing differently?

faceyspacey commented 7 years ago

@richardscarrott What's going on brother, I finally finished my tools revolving around chunk flushing. Along with it is a boilerplate that reproduces it:

https://github.com/faceyspacey/flush-chunks-boilerplate

The only thing is that it now uses a fork of webpack-dev-middleware which supports multiple compilers:

http://npmjs.com/package/webpack-dev-middleware-multi-compiler

If you git clone the boilerplate, run yarn add webpack-dev-middleware and switchout the corresponding code in server/index.webpack.js you will see the issue.

Here's the pending PR for the fix by the way: https://github.com/webpack/webpack-dev-middleware/pull/187

I think you got it working by one of 2 ways:

It's probably the first of the 2 in whatever code you're usually running...not that it matters now if you wanna use my fork or upgrade webpack-dev-middleware once the PR is merged.


Otherwise, I got some good news: I finally finished the chunk flushing stuff I was working on; here's a PR to React Loadable that explains it all: https://github.com/thejameskyle/react-loadable/pull/37

I'd be really interested for you to join the conversation in that PR regarding all the new tools mentioned there.

I replaced my serverStats-clientStats linking with your deterministic module ID solution. Very nice! And I'm also using the cleaner webpack-hot-server-middleware API now that takes an options object. I was actually gonna ask you if we could go that route (since I now had null for the serverStats everywhere just complicating my boilerplates), but then I saw you already did it. I do feel like serverRendererOptions is unnecessary nesting and any additional keys can exist parallel to chunkName on the options object and then you just pass the whole thing--just a thought. Either way having that options object is a very useful touch for communicating from Babel code where paths resolve easily to Webpack code where it gets complicated. I'm sure people will find many other reasons to use that.

Anyway, I just wanted to touch base about these things as I basically just launched all my stuff. Checkout the PR to React Loadable for all the relevant links. I have several packages, one very interesting one handling CSS chunks and CSS HMR that I forked from extract-text-webpack-plugin which I'm eager to hear people's opinions about. I won't clutter you with links--it's in the PR.

...but oh yea, so your package (this package, webpack-hot-server-middleware) plays a very important role in the workflow I've laid out. I mean I think this package is fantastic. Everybody should be using it. I give you a lot of props for this package (not as in the ones you pass to React components) in my documentation. It should be just as popular as the client middleware. Not using Webpack on the server is a mistake if you're using it on the client. And if you're using webpack on the server without proper HMR, ur doing it all wrong. I really don't understand why it hasn't blown up...In short, let's blow it up! Talk soon.