Skip to content
This repository has been archived by the owner on Apr 8, 2020. It is now read-only.

HMR runs in production? #264

Closed
onethread opened this issue Aug 15, 2016 · 5 comments
Closed

HMR runs in production? #264

onethread opened this issue Aug 15, 2016 · 5 comments

Comments

@onethread
Copy link

onethread commented Aug 15, 2016

I noticed when I run my site through the CLI in production mode, that the site will still continue to seek out an webpack HMR instance. I wasn't sure if this was by design or not, but after reading around the documentation, I assume it's not. I tried running the MusicStore sample through the CLI as well, and get the same error (listed below).

I assume the intended guidance is to remove the asp-prerender-webpack-config tag in production with environment blocks?

λ dotnet run
Project Microsoft.AspNetCore.NodeServices (.NETStandard,Version=v1.3) was previously compiled. Skipping compilation.
Project Microsoft.AspNetCore.SpaServices (.NETStandard,Version=v1.6) was previously compiled. Skipping compilation.
Project MusicStore (.NETCoreApp,Version=v1.0) will be compiled because expected inputs are missing
Compiling MusicStore for .NETCoreApp,Version=v1.0

Compilation succeeded.
    0 Warning(s)
    0 Error(s)

Time elapsed 00:00:06.2134454


Hosting environment: "Production"
Content root path: C:\Users\Source\Repos\JavaScriptServices\samples\react\MusicStore
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr
@SteveSandersonMS
Copy link
Member

How the behaviour varies between development and production mode just depends on what code you've wrapped in if (env.IsDevelopment()) { ... } blocks. In the Yeoman templates, the code that enables webpack dev middleware (which in turn enables HMR) is in such a block, so will certainly not run in production mode.

Are you reporting this just because you see the following in your console?

  Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr

If so, my guess is that what's happening is that you still have some browser window open that's still running the debug code from before. That client instance will continue making requests for /__webpack_hmr, and since your server is now in production mode, it is handling that like any other request for that URL (and not returning any HMR data).

Can you check whether there was some browser window still open running the debug code? If that turns out not to be the case, please reopen with further details. Thanks!

@onethread
Copy link
Author

Thanks @SteveSandersonMS , that was totally it, my apologies.

Actually, I found that (non)issue while trying to investigate something else. I noticed that in production mode, in conjunction with asp-prerender tags, that the first load takes a long time (about 60s in our setup). It appears to be building our js files for use in memory in a very hot-ish way (it seems to react to changes in files, which I realize theoretically shouldn't happen post-deploy). While in theory it should only be a one time hit, it's still a very large first hit for us. I think it would make more sense if the prerendering and hot dev were separate settings. I apologize if I'm totally off base here.

But in my mind it would be great if I could have the tags that are already there for HMR development, but possibly an additional tag to point towards a prebuilt server-side script. I found a similar example of that here. As it stands, I don't think the asp-prerender-module tag could service both, since it'd result in a chicken and egg scenario.

In the meantime, I'm thinking I'll wrap the index.cshtml divs in environment tags, one pointing to the jsx/tsx version of our boot server code, and the other pointed to a precompiled version.

What do you think?

@SteveSandersonMS
Copy link
Member

I think it would make more sense if the prerendering and hot dev were separate settings.

Do you mean you want to independently control which of these are enabled? If so, that's already the case (you control HMR using the HotModuleReplacement flag in Startup.cs, and you control prerendering using the asp-prerender-module tag helper in your Razor view).

If you meant something else, sorry, I'm not following!

the first load takes a long time (about 60s in our setup

That seems pretty extreme. Do you have an amazingly huge application? Or are you just referencing some large third-party libraries? If the latter, consider referencing the third-party stuff from your webpack.config.vendor.js so that it doesn't get rebuilt on every code change.

@onethread
Copy link
Author

onethread commented Aug 17, 2016

Sorry, I incorrectly thought that the webconfig file for HMR was defined in the asp tag, but it looks like it just happens to default to web.config.js. So scratch that part.

I meant I'd really like to have the option of prerendering without the initial build time (while in production mode). Something similar to the example I mentioned in my other comment, where the server side bundle was pre-built. 60 s is extreme, yes, and we will separate out the vendor packages, but I also think a big part of that is coming from the production-level webpack plugins (dedupe, minify, etc). We could probably further remove those in a web.config.server or something, but it almost just seems like avoiding the elephant in the room - if the client side is precompiled for production, why not the server? I tried running the React music store sample in production, and I believe it was still anywhere between 12 to 24 seconds before first byte while it compiled the server side js.

It does look like it may already be possible with the current version, though, with environment tags and the asp export tag. I'll give that a shot.

@onethread
Copy link
Author

I was able to get it working. For anyone that's curious:
My index.cshtml

<environment names="Development">
    <div id="react-app"
        asp-prerender-module="app/boot/server"
        asp-prerender-webpack-config="webpack.config.js"></div>
</environment>
<environment  names="Staging,Production">
    <div
        id="react-app"
        asp-prerender-module="wwwroot/dist/server.bundle.js"
    ></div>
</environment>

Then in my webpack.config.js,

...

const clientConfig = Object.assign({}, baseConfig, targetConfig);

if (isDevelopment) {
    // aspnet-webpack expects only one configuration
    module.exports = clientConfig;
} else {
    const serverConfig = Object.assign({}, baseConfig, serverSettings);
   // the serverConfig can't have the commons plugin enabled, 
   // or it will export in an unexpected manner
    module.exports = [
        clientConfig,
        serverConfig,
    ];
}

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

No branches or pull requests

2 participants