RickStrahl / Westwind.AspnetCore.LiveReload

ASP.NET Core Live Reload Middleware that monitors file changes in your project and automatically reloads the browser's active page
Other
469 stars 42 forks source link

Double reload issue sass #22

Closed dotnetshadow closed 4 years ago

dotnetshadow commented 4 years ago

Hi Rick,

After seeing your notes on 0.1.17 about double reload issues, I've come across a similar issue when using sass and livereload (including previous versions)

Currently my project is setup to use webpack for sass. I noticed upon saving a .scss file that the page would reload several times.

Dev Tools image

Unfortunately my project is too big to show as a sample.

Keep up the great work, much appreciated

RickStrahl commented 4 years ago

Without more info I'm not sure what to do about this. I know there are potential issues for files that are deleted first, then created, then written - it can in some cases result in multiple updates triggering.

I had played around with some limits how frequently this can fire but not had much luck in a good reliable solution to ensure it doesn't fire to quickly in succession. If you have a huge project with lots of stuff updating during an in-place build this can cause problems though and there may not be a good solution around this.

This is why I say - we'd need to look at the specific scenario that's triggering the problem.

dotnetshadow commented 4 years ago

@RickStrahl Yeah you are totally correct, it's all about the timing of files. Currently the solution is good enough and it's a huge improvement in workflow, so it's not a real big issue.

If I can pinpoint the specific scenario that's triggering the problem I'll report back. I think my scenario does fall into the deleting of files because I like to clear out my wwwroot when using webpack to get clean files etc.

I think you can close this issue Thanks again Rick and stay safe

dotlegacy commented 4 years ago

I believe the double reload is due to the issue that I reported on issue#23.

RickStrahl commented 4 years ago

So gave this some more thought. I think the issue here is that files are being updated behind the scenes. Are you adding SCCS to the extensions monitored? If so it might be better to use whatever final output is generated (CSS?) and not monitor SCSS because the build process will eventually create an update CSS file that should trigger the change notification...

dotnetshadow commented 4 years ago

In my particular case these are the files that I'm monitoriing "ClientFileExtensions": ".cshtml,.css,.js,.htm,.html,.ts,.razor,.wc"

I think what's is happening in my case is that:

  1. I save the SCSS file,
  2. Webpack begins to build,
  3. At this stage LiverRload kicks in,
  4. Finally when webpack has finished, it pushes the files to the output directory
  5. LiveReload sees new files so it reloads.

The webpack build in my case can take as long as 5 secs if not longer, The I also use parallel webpack builds like here https://tech.trivago.com/2015/12/15/parallel-webpack/ so not sure if that's got something to do with it.

Not sure if that helps in any way

germanftorres commented 4 years ago

Hi Rick,

I'm experiencing a similar issue but in the opposite direction, some updates are being swallowed after I installed the postcss plugin to the svelte project.

In my case I'm serving a Svelte application from an aspnetcore backend. When I change a source file in the client app (a .svelte file), the rollup>svelte>postcss pipeline kicks in and produces all the output files (bundle.css, bundle.js, global-style.css). Currently all files are being regenerated regardless wheter the change is on the css or the js.

I have noticed that when I change the css part of the svelte file, the updates are appears instantly. But when I change the js part of the .svelte file, the refresh occurs, but you get the last version of the js bundle file.

I think that the rollup compiler produces first the bundle.css file, causing the live reload server to refresh the page, but before in has finished to produce the bundle.js file.

The workaround for me in this situation and knowing that the svelte compiler produces all files regardless of the change was to configure the LiveReload server to only monitor the .js extension which is the last file that apparently gets created.

                builder.Services.AddLiveReload(opt =>
                {
                    opt.LiveReloadEnabled = true;
                    opt.ServerRefreshTimeout = 3000;
                    opt.ClientFileExtensions = ".js,.html";
                });

Thanks for this great work!

dotnetshadow commented 4 years ago

@germanftorres You are spot on with your assessment. Your idea of only using the js and excluding the css helped with the double reloading issue I was having.

I guess my css is getting compiled via webpack, so having just the js is enough to kick the reload off

Thanks for your post

RickStrahl commented 4 years ago

Yeah WebBack bundles everything into JS files so ignoring other file changes in Webpack installs will fix double hits and also fix the timing.

But that begs the question: If you are using WebPack - why aren't just just running the WebPack built-in Web server? WebPack apps typically have a serve command to do both resource loading as well as live reload - for SPA apps that seems like a better way to go since you're already using WebPack anyway. Combine it with dotnet run and that should give you pretty much the same behavior you get with the Live Reload Server or middleware.

Assuming you still wanted to use this tooling, then the question is how could this be handled any differently? Other than providing additional documentation that mentions this use case I'm not sure if there's a solution in the tool itself to address this.

dotnetshadow commented 4 years ago

@RickStrahl I totally agree with you in terms of SPA apps, using webpack to serve up, will provide a better live reload experience.

In my particular case, I'm just using a standard asp.net core mvc app. When the project first started Bower was the standard way to handle client assets (before libman came along). I wanted to be able to write es6 style javascript, so I decided to use webpack instead.

This allowed me to use the webpack task runner: https://github.com/madskristensen/WebPackTaskRunner. Therefore it allowed to have a watch on my files as I was coding would recompile them for me.

I know webpack has the ability to inject the hashed compiled assets into the html (HtmlWebpackPlugin) similar to this approach https://cecilphillip.com/setting-up-webpack-in-asp-net-core-pt-2/ (Templating with the HtmlWebpack Plugin). It would then require the hotmodulereload middleware in asp.net core to be able to reload, but I didn't know how to integrate this well at the time.

The other option I was tried was using the old browser reload functionality in visual studio, but there were some issues with using it. Recently, certain files changes were not triggering the reload.

Therefore when your library came along it was exactly what I required, Not only was it beneficial for client side assets, but it was able to handle the .cshtml and .razor files too,

When I first posed the question, I didn't realise how the reload worked properly, but now that I understand it better, as you said, I think not much can be done except for some guidance in the form of additional documentation perhaps.

Sorry for the long explanation

germanftorres commented 4 years ago

@RickStrahl In my use case I would like to have all /api backend enpoints (aspnetcore) served from the same domain as the SPA so this is why I chose to rely on this middleware for aspnetcore instead of the dev servers provided by the bundlers.

Maybe I should rethink a way to make use parcel/rollup/webpack dev servers with the backend running on a different port (via dotnet run) but still be able to serve backend and frontend from the aspnetcore application when deploying to production.

RickStrahl commented 4 years ago

In my use case I would like to have all /api backend enpoints (aspnetcore) served from the same domain as the SPA

Ah Ok - didn't think about that as I always run out of separate folders and sites. So are you natively running the folders inside of your wwwroot or are you building into that folder even for dev? Still requires WebPack's watch manager to do the build on change though...

In the latter scenario though I would think that you would just monitor js files since that's what WebPack bundles everything into.

Maybe part of the solution is instead of just blindly monitoring all extensions in the site is providing a multiple glob patterns that would allow finetuning where to look and which files to take. More complicated for 'just get it going though' which is not so cool...