Add example of full-page prerendering via a custom action result

This commit is contained in:
SteveSandersonMS
2016-07-19 15:50:54 +01:00
parent edf1f88398
commit 749c7cb3ce
8 changed files with 115 additions and 4 deletions

View File

@@ -0,0 +1,47 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.NodeServices;
using Microsoft.AspNetCore.SpaServices.Prerendering;
using Microsoft.Extensions.DependencyInjection;
namespace Webpack.ActionResults
{
// This is an example of how you could invoke the prerendering API from an ActionResult, so as to
// prerender a SPA component as the entire response page (instead of injecting the SPA component
// into a Razor view's output)
public class PrerenderResult : ActionResult
{
private JavaScriptModuleExport _moduleExport;
private object _dataToSupply;
public PrerenderResult(JavaScriptModuleExport moduleExport, object dataToSupply = null)
{
_moduleExport = moduleExport;
_dataToSupply = dataToSupply;
}
public override async Task ExecuteResultAsync(ActionContext context)
{
var nodeServices = context.HttpContext.RequestServices.GetRequiredService<INodeServices>();
var hostEnv = context.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
var applicationBasePath = hostEnv.ContentRootPath;
var request = context.HttpContext.Request;
var response = context.HttpContext.Response;
var prerenderedHtml = await Prerenderer.RenderToString(
applicationBasePath,
nodeServices,
_moduleExport,
request.GetEncodedUrl(),
request.Path + request.QueryString.Value,
_dataToSupply
);
response.ContentType = "text/html";
await response.WriteAsync(prerenderedHtml.Html);
}
}
}

View File

@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SpaServices.Prerendering;
namespace Webpack.ActionResults
{
public static class PrerenderResultExtensions
{
public static PrerenderResult Prerender(this ControllerBase controller, JavaScriptModuleExport exportToPrerender, object dataToSupply = null)
{
return new PrerenderResult(exportToPrerender, dataToSupply);
}
}
}

View File

@@ -0,0 +1,17 @@
export default function (params: any): Promise<{ html: string, globals?: any }> {
return new Promise((resolve, reject) => {
// Here, you could put any logic that synchronously or asynchronously prerenders
// your SPA components. For example, see the boot-server.ts files in the Angular2Spa
// and ReactReduxSpa templates for ways to prerender Angular 2 and React components.
//
// If you wanted, you could use a property on the 'params.data' object to specify
// which SPA component or template to render.
const html = `
<h1>Hello</h1>
It works! You passed <b>${ JSON.stringify(params.data) }</b>
and are currently requesting <b>${ params.location.path }</b>`;
resolve({ html });
});
};

View File

@@ -0,0 +1,25 @@
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SpaServices.Prerendering;
using Webpack.ActionResults;
namespace Webpack.Controllers
{
// This sample shows how you could invoke the prerendering APIs directly from an MVC
// action result.
public class FullPagePrerenderingController : Controller
{
private static JavaScriptModuleExport BootModule = new JavaScriptModuleExport("Clientside/PrerenderingSample")
{
// Because the boot module is written in TypeScript, we need to specify a webpack
// config so it can be built. If it was written in JavaScript, this would not be needed.
WebpackConfig = "webpack.config.js"
};
public IActionResult Index()
{
var dataToSupply = new { nowTime = DateTime.Now.Ticks };
return this.Prerender(BootModule, dataToSupply);
}
}
}

View File

@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.IO;
using Microsoft.AspNetCore.NodeServices;
namespace Webpack
{
@@ -14,6 +15,7 @@ namespace Webpack
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddNodeServices();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@@ -5,6 +5,9 @@
<h1>Hello</h1>
Hi there. Enter some text: <input />
<hr />
See also: <a asp-controller='FullPagePrerendering'>Full-page prerendering example</a>
@section scripts {
<script src="dist/main.js"></script>
}

View File

@@ -2,15 +2,18 @@
"name": "Webpack",
"version": "0.0.0",
"devDependencies": {
"aspnet-webpack": "^1.0.3",
"css-loader": "^0.23.1",
"extendify": "^1.0.0",
"extract-text-webpack-plugin": "^1.0.1",
"less": "^2.6.0",
"less-loader": "^2.2.2",
"style-loader": "^0.13.0",
"ts-loader": "^0.8.1",
"typescript": "^1.7.5",
"webpack-hot-middleware": "^2.7.1"
},
"dependencies": {
"aspnet-webpack": "^1.0.3",
"aspnet-prerendering": "^1.0.4",
"ts-loader": "^0.8.1",
"typescript": "^1.7.5"
}
}

View File

@@ -1,7 +1,8 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "es5",
"module": "commonjs",
"target": "es6",
"jsx": "preserve",
"sourceMap": true
},