Awesome
JavaScriptViewEngine
An ASP.NET MVC (MVC Core 1, MVC 6) ViewEngine for rendering markup in a javascript environment. Ideal for React and Angular server-side rendering.
ASP.NET MVC Core 1 | ASP.NET MVC 5 |
---|---|
Why?
The main drive behind this is to support isomorphic/universal rendering. The idea is that your Model
will be passed to a javascript method that will render markup in return. Imagine having a react component tree that is hydrated via a single immutable JSON structure, representing the initial state of the service-side rendered page.
There were existing projects out there that allowed us to render javascript. All of them had their issues.
- NodeServices - https://github.com/aspnet/NodeServices
- pros
- Supports ASP.NET 5 (ASP.NET Core 1)
- .NET Core (Windows/Linux/Mac)
- cons
- Too much .NET integration than what is needed
- Razor is required
- pros
- React.NET - https://github.com/reactjs/React.NET
- pros
- Embedded javascript engine
- Fast
- cons
- Narrow focus (only React, not Angular)
- Limited support for libraries
- Opinionated
- No .NET Core support.
- pros
Example projects
Checkout the JavaScriptViewEngine.Samples repo!
Or, checkout the react-aspnet-boilerplate.
In a nutshell
Getting started is pretty simple.
- Add a reference to the
JavaScriptViewEngine
NuGet package. - Setup things app in your
Startup.cs
.
public class Startup
{
private readonly IHostingEnvironment _env;
public Startup(IHostingEnvironment env)
{
_env = env;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddJsEngine();
services.Configure<RenderPoolOptions>(options =>
{
options.WatchPath = _env.WebRootPath;
options.WatchFiles = new List<string>
{
Path.Combine(options.WatchPath, "default.js")
};
});
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.UseJsEngine(); // this needs to be before MVC
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
}
}
- Create
default.js
in yourWebRootPath
that will be invoked when rendering.
module.exports = {
renderView: function (callback, path, model, viewBag, routeValues) {
callback(null, {
html: "<html><head></head><body><p><strong>Model:</strong> " + JSON.stringify(model) + "</p><p><strong>ViewBag:</strong> " + JSON.stringify(viewBag) + "</p></body>",
status: 200,
redirect: null
});
},
renderPartialView: function (callback, path, model, viewBag, routeValues) {
callback(null, {
html: "<p><strong>Model:</strong> " + JSON.stringify(model) + "</p><p><strong>ViewBag:</strong> " + JSON.stringify(viewBag) + "</p>"
});
}
};
- Get rolling in MVC.
public class HomeController : Controller
{
public IActionResult Index(string greeting = "Hello word!")
{
return View(new GreetingViewModel { Greeting = greeting });
}
}
public class GreetingViewModel
{
public string Greeting { get; set; }
}
How to build
This project uses Cake for building: http://cakebuild.net/
Windows
From a Powershell prompt:
PS> ./build.ps1