I need to version my Javacript files (for clearing cache purpose) but cannot use asp-append-version
because the script files are used from Javascript import:
import * as Foo from './foo.js'
Therefore, I plan to have a FileProvider
that can serve a file with request like /js/v1.0/app.js
(and so the foo.js
would be serve from /js/v1.0/foo.js
). It's okay to serve /v1.0/js/main.js
, as long as the relative path is maintained.
I tried this:
app.UseStaticFiles(new StaticFileOptions()
{
RequestPath = "/v*",
});
app.UseStaticFiles();
But it wouldn't work, RequestPath
does not support wildcard.
Is there a way to do that without a custom Middleware? A FileProvider middleware is quite overkill for this in my opinion. This is my current temporary solution:
public static IApplicationBuilder UseVersionedScripts(this IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
if (context.Request.Path.HasValue &&
context.Request.Path.Value.ToLower().StartsWith("/js/v"))
{
var filePath = context.Request.Path.Value.Split('/');
// Write the file to response and return if file exist
}
await next.Invoke();
});
return app;
}
Edit: I think in my case, if FileProvider is not supported, a Controller Action maybe better than middleware because PhysicalFile
method can take care of the writing.
I made a reusable FileProvider that "transforms" (removes) the version path: https://github.com/BibliTech/VersionedFileProvider
var versionedFileProvider = new VersionedFileProvider(env.WebRootFileProvider);
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = versionedFileProvider,
});
OLD ANSWER:
In the end I use an Action to serve the file:
[ApiController]
public class FileController : ControllerBase
{
IHostEnvironment env;
public FileController(IHostEnvironment env)
{
this.env = env;
}
[HttpGet, Route("/js/{version}/{**path}")]
public IActionResult JavascriptFile(string version, string path)
{
var filePath = Path.Combine(
env.ContentRootPath,
@"wwwroot\js",
path);
if (System.IO.File.Exists(filePath))
{
return this.PhysicalFile(filePath, "application/javascript");
}
return this.NotFound();
}
}