Inject blazor.js script tag (with all references) automatically

This commit is contained in:
Steve Sanderson 2017-12-12 00:36:09 +00:00
parent aff369e86d
commit c4fea86603
14 changed files with 121 additions and 71 deletions

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Blazor.Mono;
using Microsoft.Blazor.Server.ClientFilesystem;
using Microsoft.Blazor.Server.FrameworkFiles;
using Mono.Cecil;
using System;
using System.IO;

View File

@ -6,6 +6,5 @@
</head>
<body>
<h1>Hello</h1>
<script src="/_framework/blazor.js" main="HostedInAspNet.Client.dll"></script>
</body>
</html>

View File

@ -22,10 +22,11 @@ namespace HostedInAspNet.Server
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBlazorDevelopmentServer("../HostedInAspNet.Client");
}
app.UseBlazor(clientAssemblyPath: typeof(Client.Program).Assembly.Location);
app.UseBlazor(
assemblyPath: typeof(Client.Program).Assembly.Location,
staticFilesRoot: "../HostedInAspNet.Client/wwwroot");
}
}
}

View File

@ -11,8 +11,10 @@ namespace MonoSanity
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseFileServer();
app.UseBlazor(clientAssemblyPath: typeof(MonoSanityClient.Examples).Assembly.Location);
app.UseFileServer(new FileServerOptions { EnableDefaultFiles = true });
app.UseBlazor(
assemblyPath: typeof(MonoSanityClient.Examples).Assembly.Location,
staticFilesRoot: null);
}
}
}

View File

@ -6,7 +6,5 @@
</head>
<body>
<h1>Hello</h1>
<script src="/_framework/blazor.js" main="StandaloneApp.dll"
references="Microsoft.Blazor.dll, netstandard.dll"></script>
</body>
</html>

View File

@ -133,21 +133,8 @@ function createEmscriptenModuleInstance(loadAssemblyUrls: string[], onReady: ()
mono_string_get_utf8 = Module.cwrap('mono_wasm_string_get_utf8', 'number', ['number']);
mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']);
// TODO: Stop hard-coding this list, and instead automatically load whatever
// dependencies were detected in ReferencedAssemblyFileProvider
const loadBclAssemblies = [
'mscorlib',
'System',
'System.Core',
'System.Console',
'System.Runtime',
];
var allAssemblyUrls = loadAssemblyUrls
.concat(loadBclAssemblies.map(name => `_framework/_bin/${name}.dll`));
Module.FS_createPath('/', 'appBinDir', true, true);
allAssemblyUrls.forEach(url =>
loadAssemblyUrls.forEach(url =>
FS.createPreloadedFile('appBinDir', `${getAssemblyNameFromUrl(url)}.dll`, url, true, false, null, <any>onError));
});

View File

@ -20,8 +20,9 @@ namespace Microsoft.Blazor.DevHost.Server
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
app.UseBlazorDevelopmentServer(".");
app.UseBlazor(clientAssemblyPath: FindClientAssembly(app).Location);
app.UseBlazor(
assemblyPath: FindClientAssembly(app).Location,
staticFilesRoot: "wwwroot");
}
private static Assembly FindClientAssembly(IApplicationBuilder app)

View File

@ -1,11 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Blazor.Server.ClientFilesystem;
using Microsoft.Blazor.Server.FrameworkFiles;
using Microsoft.Blazor.Server.WebRootFiles;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.IO;
using System.Net.Mime;
using System.Reflection;
namespace Microsoft.AspNetCore.Builder
{
@ -13,12 +16,35 @@ namespace Microsoft.AspNetCore.Builder
{
public static void UseBlazor(
this IApplicationBuilder applicationBuilder,
string clientAssemblyPath)
string assemblyPath,
string staticFilesRoot)
{
var frameworkFileProvider = FrameworkFileProvider.Instantiate(assemblyPath);
if (staticFilesRoot != null)
{
var env = applicationBuilder.ApplicationServices.GetRequiredService<IHostingEnvironment>();
var clientWebRoot = Path.GetFullPath(Path.Combine(env.ContentRootPath, staticFilesRoot));
var webRootFileProvider = WebRootFileProvider.Instantiate(
clientWebRoot,
Path.GetFileNameWithoutExtension(assemblyPath),
frameworkFileProvider.GetDirectoryContents("/_bin"));
applicationBuilder.UseDefaultFiles(new DefaultFilesOptions
{
FileProvider = webRootFileProvider
});
applicationBuilder.UseStaticFiles(new StaticFileOptions
{
FileProvider = webRootFileProvider
});
}
applicationBuilder.UseStaticFiles(new StaticFileOptions
{
RequestPath = "/_framework",
FileProvider = ClientFileProvider.Instantiate(clientAssemblyPath),
FileProvider = frameworkFileProvider,
ContentTypeProvider = CreateContentTypeProvider(),
});
}

View File

@ -1,38 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using System.IO;
namespace Microsoft.AspNetCore.Builder
{
public static class DevelopmentServerApplicationBuilderExtensions
{
public static void UseBlazorDevelopmentServer(
this IApplicationBuilder applicationBuilder,
string relativeSourcePath)
{
var env = applicationBuilder.ApplicationServices.GetRequiredService<IHostingEnvironment>();
var sourcePath = Path.Combine(env.ContentRootPath, relativeSourcePath);
ServeWebRoot(applicationBuilder, sourcePath);
}
private static void ServeWebRoot(IApplicationBuilder applicationBuilder, string clientAppSourceRoot)
{
var webRootFileProvider = new PhysicalFileProvider(
Path.Combine(clientAppSourceRoot, "wwwroot"));
applicationBuilder.UseDefaultFiles(new DefaultFilesOptions
{
FileProvider = webRootFileProvider
});
applicationBuilder.UseStaticFiles(new StaticFileOptions
{
FileProvider = webRootFileProvider
});
}
}
}

View File

@ -5,11 +5,10 @@ using Microsoft.Blazor.Browser;
using Microsoft.Blazor.Mono;
using Microsoft.Extensions.FileProviders;
using System.IO;
using System.Reflection;
namespace Microsoft.Blazor.Server.ClientFilesystem
namespace Microsoft.Blazor.Server.FrameworkFiles
{
internal static class ClientFileProvider
internal static class FrameworkFileProvider
{
public static IFileProvider Instantiate(string clientAssemblyPath)
=> new CompositeFileProvider(

View File

@ -7,7 +7,7 @@ using System.Linq;
using Mono.Cecil;
using Microsoft.Blazor.Internal.Common.FileProviders;
namespace Microsoft.Blazor.Server.ClientFilesystem
namespace Microsoft.Blazor.Server.FrameworkFiles
{
internal class ReferencedAssemblyFileProvider : InMemoryFileProvider
{

View File

@ -5,7 +5,7 @@ using Microsoft.Extensions.FileProviders;
using System.IO;
using System.Linq;
namespace Microsoft.Blazor.Server.ClientFilesystem
namespace Microsoft.Blazor.Server.FrameworkFiles
{
internal class ReferencedAssemblyResolver
{

View File

@ -0,0 +1,58 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Blazor.Internal.Common.FileProviders;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.FileProviders;
using System.Linq;
namespace Microsoft.Blazor.Server.WebRootFiles
{
internal class IndexHtmlFileProvider : InMemoryFileProvider
{
public IndexHtmlFileProvider(string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles)
: base(ComputeContents(clientWebRoot, assemblyName, binFiles))
{
}
private static IEnumerable<(string, Stream)> ComputeContents(string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles)
{
var html = GetIndexHtmlContents(clientWebRoot, assemblyName, binFiles);
if (html != null)
{
var htmlBytes = Encoding.UTF8.GetBytes(html);
var htmlStream = new MemoryStream(htmlBytes);
yield return ("/index.html", htmlStream);
}
}
private static string GetIndexHtmlContents(string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles)
{
var indexHtmlPath = Path.Combine(clientWebRoot, "index.html");
if (!File.Exists(indexHtmlPath))
{
return null;
}
// TODO: Consider parsing the HTML properly so for example we don't insert into
// the wrong place if there was also '</body>' in a JavaScript string literal
return File.ReadAllText(indexHtmlPath)
.Replace("</body>", CreateBootMarkup(assemblyName, binFiles) + "\n</body>");
}
private static string CreateBootMarkup(string assemblyName, IEnumerable<IFileInfo> binFiles)
{
var assemblyNameWithExtension = $"{assemblyName}.dll";
var referenceNames = binFiles
.Where(file => !string.Equals(file.Name, assemblyNameWithExtension))
.Select(file => file.Name);
var referencesAttribute = string.Join(',', referenceNames.ToArray());
return $"<script src=\"/_framework/blazor.js\"" +
$" main=\"{assemblyNameWithExtension}\"" +
$" references=\"{referencesAttribute}\"></script>";
}
}
}

View File

@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Extensions.FileProviders;
using System.Collections.Generic;
namespace Microsoft.Blazor.Server.WebRootFiles
{
internal static class WebRootFileProvider
{
public static IFileProvider Instantiate(
string clientWebRoot, string assemblyName, IEnumerable<IFileInfo> binFiles)
=> new CompositeFileProvider(
new IndexHtmlFileProvider(clientWebRoot, assemblyName, binFiles),
new PhysicalFileProvider(clientWebRoot));
}
}