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

Hot reload for Blazor #5456

Open
danroth27 opened this issue Jan 25, 2018 · 56 comments
Open

Hot reload for Blazor #5456

danroth27 opened this issue Jan 25, 2018 · 56 comments

Comments

@danroth27
Copy link
Member

@danroth27 danroth27 commented Jan 25, 2018

  • Via dotnet watch
  • Development middleware (websocket connection to receive updates)
@SteveSandersonMS

This comment has been minimized.

Copy link
Member

@SteveSandersonMS SteveSandersonMS commented Mar 16, 2018

See https://github.com/aspnet/blazor/issues/193 for status updates on this work item.

@martasp

This comment has been minimized.

Copy link

@martasp martasp commented Mar 23, 2018

For now, we can use dotnet watch run and recompile every time when the change occurs.
Just using this in csproj file :
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
<Watch Include="**\*.cshtml"/>

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Apr 4, 2018

We've hit a snag with live reload for 0.2.0, so moving this out until we can work through a more robust design.

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Sep 6, 2018

Hi, I'm using dotnet sdk 2.2.100-preview1-009349 and blazor 0.5.1 under Mac.
Live reload doesn't work using "dotnet blazor serve". If I change some html markup in a cshtml file, the app doesn't reload itself and ever after a manual browser reload, the app display the old html content. How can I solve this?

@aspnet-hello aspnet-hello transferred this issue from dotnet/blazor Dec 17, 2018
@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 17, 2018
@mkArtakMSFT

This comment has been minimized.

Copy link
Contributor

@mkArtakMSFT mkArtakMSFT commented Mar 20, 2019

@danroth27, what's #4056 then? Should it be closed?

@dazinator

This comment has been minimized.

Copy link

@dazinator dazinator commented May 11, 2019

Few questions!
1 Does this track live reload for both server side blazor and client side blazor?
2. Will live reload ship in go live release (i.e in net core 3.0) ?
3. Will live reload mechanism lose page state (I.e equivalent to an f5 refresh) or will it behave similar to Hot Module Replacement in javascript land - I.e only the changed Components UI will re-render? If the latter, will there be a mechanism to preserve component state on the client between updates?

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented May 13, 2019

Does this track live reload for both server side blazor and client side blazor?

Yes

Will live reload ship in go live release (i.e in net core 3.0) ?

For .NET Core 3.0 we expect to support auto rebuild based on file changes, but you will still need to manually refresh the browser.

Will live reload mechanism lose page state (I.e equivalent to an f5 refresh) or will it behave similar to Hot Module Replacement in javascript land - I.e only the changed Components UI will re-render? If the latter, will there be a mechanism to preserve component state on the client between updates?

We don't currently have a plan for supporting hot module replacement in a way that preserves client state.

@SteveSandersonMS

This comment has been minimized.

Copy link
Member

@SteveSandersonMS SteveSandersonMS commented May 14, 2019

We don't currently have a plan for supporting hot module replacement in a way that preserves client state.

At least, not automagically. Theoretically if you follow a Redux-like architecture, or anything else that strictly decouples state from display, then you could serialize that state out before unload and restore on reload. However this isn't something we're planning to bake in as a feature, as not everyone wants to follow that kind of architecture.

@dazinator

This comment has been minimized.

Copy link

@dazinator dazinator commented May 14, 2019

then you could serialize that state out before unload and restore on reload.

Thanks. Please, once ready, would you be able to document the appropriate hooks (before unload / reload etc) provided in the design to facilitate this. I'd like to start on an implementation / helper nuget package to enable this pattern for those that want it!

@ahmad2smile

This comment has been minimized.

Copy link

@ahmad2smile ahmad2smile commented May 26, 2019

Couldn't get the dotnet watch run to work, tried following and other options too,

dotnet watch --project "Portfolio.Client" run --project "Portfolio.Server"

Just ended up with the following crude solution using nodemon:

npx nodemon --watch "Portfolio.Client" -e razor,css,html,cs --exec 'dotnet run --project "Portfolio.Server"'

@yberstad

This comment has been minimized.

Copy link

@yberstad yberstad commented May 30, 2019

I thought i was supposed to run:
dotnet watch --project BlazorTest.Client run
But that gave me an error.

If I used:
dotnet watch --project BlazorTest.Server run

With the following in the project BlazorTest.Server.csproj file:

<ItemGroup>
    <Watch Include="..\**\*.razor" />
    <Watch Include="..\**\*.scss" />
    <Watch Include="..\**\*.cs" />
</ItemGroup>

It picked up changes in the BlazorTest.Client project and restarted the server, so I only had to do a manual refresh in the browser.

@dazinator

This comment has been minimized.

Copy link

@dazinator dazinator commented May 30, 2019

It picked up changes in the BlazorTest.Client project and restarted the server, so I only had to do a manual refresh in the browser.

Does that mean the server restarts everytime there is a a css, html change?

@yberstad

This comment has been minimized.

Copy link

@yberstad yberstad commented May 30, 2019

@dazinator, yes :-)

@dazinator

This comment has been minimized.

Copy link

@dazinator dazinator commented May 30, 2019

.. ok just checking but that is a bad thing right? I.e server restart should be unnecessary for a html or css file change as a browser refresh (with cache invalidated) should suffice?

@yberstad

This comment has been minimized.

Copy link

@yberstad yberstad commented May 30, 2019

You are right, that is not necessary. Just add or remove the file extensions you are interested in within the <ItemGroup>. Updated my answer to avoid confusion.

@datvm

This comment has been minimized.

Copy link

@datvm datvm commented Jun 8, 2019

Sorry if off-topic, is there anyway to live reload from Visual Studio right now (Blazor client-side)? Right now for every change excluding wwwroot files, I have to Build the project (Ctrl Shift B) and reload the browser. Would be wonderful if VS can auto build on saving changes.

@MisinformedDNA

This comment has been minimized.

Copy link

@MisinformedDNA MisinformedDNA commented Oct 1, 2019

We've enabled this for server-side Blazor projects, but we need to do some work to enable this again for client-side Blazor projects and Razor class libraries. It will probably be a bit before we get to this as we are focused right now at shipping .NET Core 3.0.

From what I've been able to gather from various GitHub issues is that live-reload only works on server-side Blazor that is run without debugging (and the developer must force refresh the page). Is that correct? I couldn't find any definitive documentation on the subject.

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Oct 1, 2019

What we have right now is really auto-rebuild support for ASP.NET Core projects, where VS will watch the file system for changes and then automatically rebuild and rerun the project. It only works when the debugger is not attached and for files in the current project (dependent projects are not watched).

@Postlagerkarte

This comment has been minimized.

Copy link

@Postlagerkarte Postlagerkarte commented Oct 1, 2019

Is it possible to disable the auto-reconnect attempt in case the reason for the connection loss was a build? Or maybe disable the auto-reconnect at all while developing? I just want to get rid of the those failing re-connect attempts because they bug me and I press F5 anyways :)

@AdmiralSnyder

This comment has been minimized.

Copy link

@AdmiralSnyder AdmiralSnyder commented Oct 1, 2019

So it should be rather easy to have VS detach and reattach automatically, right?

@bansalankit2601

This comment has been minimized.

Copy link

@bansalankit2601 bansalankit2601 commented Oct 3, 2019

Can I get the final solution for Live Reloading for Blazor Server Apps with debugging ?

@0xF6

This comment has been minimized.

Copy link

@0xF6 0xF6 commented Oct 3, 2019

@bansalankit2601 To be implemented in .NET 5.0

@dbulic

This comment has been minimized.

Copy link

@dbulic dbulic commented Oct 16, 2019

I run the watcher as dotnet watch run and use VS to edit the code. When I save, the code is recompiled and the browser locks up, telling me I should reload.

I got tired of pressing F5 and prefer to stay in VS while adjusting things, so TamperMonkey to the rescue:

// @name         Reload the page
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        http://localhost:5000/*
// @grant        none
// ==/UserScript==

    const reloader = () => {
        if (document.body.innerText.indexOf("Reload the page") >= 0) document.location = document.location;
        else setTimeout(reloader, 300);
    }
    console.log('Blazor reloader installed');
    setTimeout(reloader, 300);

Allow the script to run on http://localhost:5000/*

@dharmaturtle

This comment has been minimized.

Copy link

@dharmaturtle dharmaturtle commented Oct 16, 2019

This works for server side: https://github.com/martasp/BlazorLiveReload

The client pings the server every 200ms. When the server goes down due to being recompiled from dotnet watch run, a flag is toggled, and when the server comes back it automatically F5s.

The repo didn't work for me, but I opened an issue with some javascript that does work (at least for me on 3.0)

@moemar

This comment has been minimized.

Copy link

@moemar moemar commented Nov 23, 2019

What is the status of "Live reload" at the moment. Is it supported (without F5 in browser)?
If not, are there any plans on releasing this feature?

@nfplee

This comment has been minimized.

Copy link

@nfplee nfplee commented Nov 23, 2019

@moemar in the latest community standup David Fowler says there are plans for it for possibly the next version but nothing has been put in place yet. https://youtu.be/bBc_NTUVtbE?list=PL1rZQsJPBU2St9-Mz1Kaa7rofciyrwWVx&t=5010

@aszalacinski

This comment has been minimized.

Copy link

@aszalacinski aszalacinski commented Feb 9, 2020

What is the latest on this? 2.5 months since last update...

@bansalankit2601

This comment has been minimized.

Copy link

@bansalankit2601 bansalankit2601 commented Feb 9, 2020

I am also waiting for the same.

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Feb 10, 2020

This is planned for .NET 5, which is scheduled for Nov 2020. We're still having lots of discussions on what approach we want to take here.

@sdiprizio

This comment has been minimized.

Copy link

@sdiprizio sdiprizio commented Feb 21, 2020

For Blazor serverside, what about using the mechanism that handle disconnections :

@dharmaturtle presented a solution that fetches the server every 200ms. It works but it is annoying because it constantly fires requests even when the server runs.

If you override Blazor.defaultReconnectionHandler._reconnectionDisplay from the javascript blazor client, you can catch disconnections and start to fetch the server and wait for it to become live again.

The advantage is that you only have requests when the server is disconnected.

The drawback is that '_reconnectionDisplay' is a private member and you know... this is evil.

As a mitigation, enclose the javascript code in <environment include="Development">. It won't bleed in production server.

Full repo here.

@dharmaturtle

This comment has been minimized.

Copy link

@dharmaturtle dharmaturtle commented Feb 22, 2020

I just switched to this solution a few minutes ago: https://remibou.github.io/Make-your-Blazor-development-faster/

It doesn't continuously ping the server, and it doesn't recompile the entire .sln if the change is in a .html, a .css or a .js file; it merely reloads the page, which is great.

@dazinator

This comment has been minimized.

Copy link

@dazinator dazinator commented Feb 22, 2020

Just linking another example here that's a bit different from above approaches. Just run the project - it doesnt require dotnet watch on the client wasm project. It will reload immediately if you change any css, html or js file in the wwwroot folder of the client wasm. It will rebuild and then reload, if you change any code in the client wasm project like a razor file etc. You have control of this in your startup.cs which is why this is a bit different to other solutions. If you also happen to still be using javascript or other static files that must be pre processed in your project, then you can also find other examples in the same repo that might be useful, such as SystemJS HMR, rollup etc.

https://github.com/dazinator/NetPack/blob/develop/src/NetPack.Web.Blazor.Host/Startup.cs

@martasp

This comment has been minimized.

Copy link

@martasp martasp commented Feb 23, 2020

Made a library that compiles razor components in runtime.

LivePreview

In react we have hot module replacement this feature allows us to change code and see changes immediately in your browser. We can make a similar feature in blazor using Roslyn compiler. Compiling down razor components in runtime and serving with WebSockets on every file change using file watcher.

How it works

It uses razor engine version 3 to compile components to c# classes. Then using Roslyn compiler I compiled down those classes to assembly. Finally, I loaded the app.razor component from an assembly with reflection and with Steve Sanderson Test host modified library I turned component to plain HTML. To serve HTML files in realtime I used WebSockets to have a full-duplex communication.

How can it be better 

Fixing routes instead of using /preview, this could be implemented by injecting WebSocket client into every HTTP request context.

In Blazor web assembly maybe we can load and unload assemblies in the browser?

Using two build servers one for fast previewing and another server with dotnet watch build for actual real longer builds.

In Blazor web assembly maybe we can load and unload assemblies in the browser?

Source: https://github.com/martasp/BlazorLiveReload

@dazinator

This comment has been minimized.

Copy link

@dazinator dazinator commented Feb 23, 2020

@martasp

In Blazor web assembly maybe we can load and unload assemblies in the browser?

It's a version of mono runtime executing blazor wasm apps, but unfortunately you can't create new AppDomains (to my knowledge) and you can't unload assemblies from the default AppDomain.

You can lazy load assemblies, which is how I'm currently dynamically loading component assemblies only on first use (to speed up initial app load time), but once they are loaded the only way to load a new version that I can see is maybe to load a new version of the same assembly into the same AppDomain and switch all references to that new one - leaving the old one there- not sure if that is supported as I'm yet to try it. If you do make in roads; let me know!

I hope one day we might get the .net core runtime running in the browser instead with its support for AssemblyLoadContexts and Assembly.Unload()

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

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.