For local testing of frontend code there is usually no need for building/publishing the visual studio solution. For your local dev environment, you have several options that will be a lot faster:
A) Symlink from Frontend build-dir to webroot
Set up a symbolic link in the local webroot and point that directory to the output of the frontend build. With webpack this would typically be a bundle in the /dist dir.
Example:
mklink /D "C:\inetpub\wwwroot\my-project.local\assets\mybundle" "c:\dev\myproject\dist\mybundle"
Make sure your assets are not cached by IIS throuhg web.config (only locally):
<configuration>
<location path="assets/mybundle">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</location>
</configuration>
B) Use Nginx as local proxy
If your frontend project supports self-hosting, you can bypass requests to http://my-project.local/assets/mybundle to your self-hosted webserver i.E. http://localhost:1234
nginx.conf:
server {
listen 88;
server_name my-project.local;
location /assets/mybundle/ {
proxy_pass http://localhost:1234/dist/mybundle;
}
}
Now you can access the local site using:
http://my-project.local:88
Requests to frontend resources will be redirected to the self-hosted webserver.
C) xCopy command in conjunction with file watcher
First, set up a batch file for copying your frontend bundle to the IIS webroot i.E.
xcopy "c:\dev\myproject\dist\mybundle\*.*" "C:\inetpub\wwwroot\my-project.local\assets\mybundle" /sy
Then set up a file watcher in the frontend build folder i.E. with this powershell script: https://superuser.com/questions/226828/how-to-monitor-a-folder-and-trigger-a-command-line-action-when-a-file-is-created
General: Referencing frontend assets
A general challenge with all of these options is referencing the generated .js and .css files in razor layouts. Webpack typically generates hash codes in the file names like
main.8cd6d964582176f0ac47.js
A possible solution is to update hashes at runtime based on the files in the bundle directory:
public static IHtmlString Asset(this HtmlHelper helper, string content)
{
var fileName = Path.GetFileName(content);
var fileParts = fileName?.Split('.');
if (fileName == null || fileParts.Length != 2)
{
return new HtmlString(content);
}
var extension = Path.GetExtension(content);
var firstPart = fileParts.FirstOrDefault();
var actualFileName = Directory.GetFiles(Server.MapPath("~/assets/mybundle/"), $"*{extension}").FirstOrDefault(f => Path.GetFileName(f).Split('.').FirstOrDefault() == firstPart);
return new HtmlString(actualFileName);
}
In Razor views:
<script src="@Html().Asset('main.js')"></script>
I would only do this locally for performance reasons.
Summary:
These are just a few of many options. Personally, I have found option A (Symlink) to be the best if the frontend framework supports live building. Otherwise option B (Local Proxy) works best.
In any case, Frontend changes are immediately visible on the local site and no AppPool recycle is required. This greatly speeds up the frontend development process.