RazorClassLibrary Components (#12134)

RazorLibrary components
This commit is contained in:
Ryan Brandenburg 2019-07-19 13:38:29 -07:00 committed by GitHub
parent 5a0a7aa088
commit e69d378442
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 124 additions and 20 deletions

View File

@ -17,6 +17,7 @@
MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion); MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion);
MicrosoftExtensionsHostingPackageVersion=$(MicrosoftExtensionsHostingPackageVersion); MicrosoftExtensionsHostingPackageVersion=$(MicrosoftExtensionsHostingPackageVersion);
MicrosoftNETCoreAppRuntimeVersion=$(MicrosoftNETCoreAppRuntimeVersion); MicrosoftNETCoreAppRuntimeVersion=$(MicrosoftNETCoreAppRuntimeVersion);
TemplateComponentsPackageVersion=$(TemplateComponentsPackageVersion);
</GeneratedContentProperties> </GeneratedContentProperties>
</PropertyGroup> </PropertyGroup>
@ -25,6 +26,7 @@
<PackageVersionVariableReference Include="$(RepoRoot)src\Azure\AzureAD\Authentication.AzureAD.UI\src\Microsoft.AspNetCore.Authentication.AzureAD.UI.csproj" /> <PackageVersionVariableReference Include="$(RepoRoot)src\Azure\AzureAD\Authentication.AzureAD.UI\src\Microsoft.AspNetCore.Authentication.AzureAD.UI.csproj" />
<PackageVersionVariableReference Include="$(RepoRoot)src\Azure\AzureAD\Authentication.AzureADB2C.UI\src\Microsoft.AspNetCore.Authentication.AzureADB2C.UI.csproj" /> <PackageVersionVariableReference Include="$(RepoRoot)src\Azure\AzureAD\Authentication.AzureADB2C.UI\src\Microsoft.AspNetCore.Authentication.AzureADB2C.UI.csproj" />
<PackageVersionVariableReference Include="$(RepoRoot)src\Components\Components\src\Microsoft.AspNetCore.Components.csproj" /> <PackageVersionVariableReference Include="$(RepoRoot)src\Components\Components\src\Microsoft.AspNetCore.Components.csproj" />
<PackageVersionVariableReference Include="$(RepoRoot)src\Components\Web\src\Microsoft.AspNetCore.Components.Web.csproj" />
<PackageVersionVariableReference Include="$(RepoRoot)src\Identity\EntityFrameworkCore\src\Microsoft.AspNetCore.Identity.EntityFrameworkCore.csproj" /> <PackageVersionVariableReference Include="$(RepoRoot)src\Identity\EntityFrameworkCore\src\Microsoft.AspNetCore.Identity.EntityFrameworkCore.csproj" />
<PackageVersionVariableReference Include="$(RepoRoot)src\Identity\UI\src\Microsoft.AspNetCore.Identity.UI.csproj" /> <PackageVersionVariableReference Include="$(RepoRoot)src\Identity\UI\src\Microsoft.AspNetCore.Identity.UI.csproj" />
<PackageVersionVariableReference Include="$(RepoRoot)src\Middleware\Diagnostics.EntityFrameworkCore\src\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.csproj" /> <PackageVersionVariableReference Include="$(RepoRoot)src\Middleware\Diagnostics.EntityFrameworkCore\src\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.csproj" />

View File

@ -11,8 +11,10 @@
<ItemGroup Condition="'$(SupportPagesAndViews)' == 'True'"> <ItemGroup Condition="'$(SupportPagesAndViews)' == 'True'">
<FrameworkReference Include="Microsoft.AspNetCore.App" /> <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(SupportPagesAndViews)' != 'True'"> <ItemGroup Condition="'$(SupportPagesAndViews)' != 'True'">
<PackageReference Include="Microsoft.AspNetCore.Components" Version="${MicrosoftAspNetCoreComponentsPackageVersion}" /> <PackageReference Include="Microsoft.AspNetCore.Components" Version="${MicrosoftAspNetCoreComponentsPackageVersion}" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="${MicrosoftAspNetCoreComponentsWebPackageVersion}" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -22,12 +22,22 @@
"preferNameDirectory": true, "preferNameDirectory": true,
"sources": [ "sources": [
{ {
"modifiers": [{ "modifiers": [
"condition": "(!SupportPagesAndViews)", {
"exclude": [ "condition": "(!SupportPagesAndViews)",
"Areas/**" "exclude": [
] "Areas/**"
}] ]
},
{
"condition": "(SupportPagesAndViews)",
"exclude": [
"Component1.razor",
"ExampleJsInterop.cs",
"wwwroot/**"
]
}
]
} }
], ],
"symbols": { "symbols": {
@ -56,7 +66,7 @@
"SupportPagesAndViews": { "SupportPagesAndViews": {
"type": "parameter", "type": "parameter",
"datatype": "bool", "datatype": "bool",
"defaultValue": "true", "defaultValue": "false",
"description": "Whether to support adding traditional Razor pages and Views in addition to components to this library." "description": "Whether to support adding traditional Razor pages and Views in addition to components to this library."
} }
}, },

View File

@ -12,5 +12,14 @@
}, },
"order": 700, "order": 700,
"icon": "vs-2017.3/RazorClassLibrary.ico", "icon": "vs-2017.3/RazorClassLibrary.ico",
"learnMoreLink": "https://go.microsoft.com/fwlink/?linkid=872103" "learnMoreLink": "https://go.microsoft.com/fwlink/?linkid=872103",
"symbolInfo": [
{
"id": "SupportPagesAndViews",
"name": {
"text": "_Support pages and views"
},
"isVisible": "true"
}
]
} }

View File

@ -0,0 +1,3 @@
<div class="my-component">
This Blazor component is defined in the <strong>RazorClassLibrary-CSharp</strong> package.
</div>

View File

@ -0,0 +1,16 @@
using Microsoft.JSInterop;
using System.Threading.Tasks;
namespace RazorClassLibrary_CSharp
{
public class ExampleJsInterop
{
public static Task<string> Prompt(IJSRuntime jsRuntime, string message)
{
// Implemented in exampleJsInterop.js
return jsRuntime.InvokeAsync<string>(
"exampleJsFunctions.showPrompt",
message);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

View File

@ -0,0 +1,8 @@
// This file is to show how a library package may provide JavaScript interop features
// wrapped in a .NET API
window.exampleJsFunctions = {
showPrompt: function (message) {
return prompt(message, 'Type anything here');
}
};

View File

@ -0,0 +1,11 @@
/*
This file is to show how CSS and other static resources (such as images) can be
used from a library project/package.
*/
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}

View File

@ -111,6 +111,11 @@ namespace Templates.Test
text += LanguageRegex.Match(arguments) text += LanguageRegex.Match(arguments)
.Groups.TryGetValue("language", out var language) ? language.Value.Replace("#", "Sharp") : ""; .Groups.TryGetValue("language", out var language) ? language.Value.Replace("#", "Sharp") : "";
if (arguments.Contains("--support-pages-and-views true"))
{
text += "supportpagesandviewstrue";
}
return text; return text;
} }

View File

@ -41,36 +41,44 @@ namespace Templates.Test.Helpers
public ITestOutputHelper Output { get; set; } public ITestOutputHelper Output { get; set; }
public IMessageSink DiagnosticsMessageSink { get; set; } public IMessageSink DiagnosticsMessageSink { get; set; }
internal async Task<ProcessEx> RunDotNetNewAsync(string templateName, string auth = null, string language = null, bool useLocalDB = false, bool noHttps = false) internal async Task<ProcessEx> RunDotNetNewAsync(string templateName, string auth = null, string language = null, bool useLocalDB = false, bool noHttps = false, string[] args = null)
{ {
var hiveArg = $"--debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\""; var hiveArg = $"--debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\"";
var args = $"new {templateName} {hiveArg}"; var argString = $"new {templateName} {hiveArg}";
if (!string.IsNullOrEmpty(auth)) if (!string.IsNullOrEmpty(auth))
{ {
args += $" --auth {auth}"; argString += $" --auth {auth}";
} }
if (!string.IsNullOrEmpty(language)) if (!string.IsNullOrEmpty(language))
{ {
args += $" -lang {language}"; argString += $" -lang {language}";
} }
if (useLocalDB) if (useLocalDB)
{ {
args += $" --use-local-db"; argString += $" --use-local-db";
} }
if (noHttps) if (noHttps)
{ {
args += $" --no-https"; argString += $" --no-https";
}
if (args != null)
{
foreach (var arg in args)
{
argString += " " + arg;
}
} }
// Save a copy of the arguments used for better diagnostic error messages later. // Save a copy of the arguments used for better diagnostic error messages later.
// We omit the hive argument and the template output dir as they are not relevant and add noise. // We omit the hive argument and the template output dir as they are not relevant and add noise.
ProjectArguments = args.Replace(hiveArg, ""); ProjectArguments = argString.Replace(hiveArg, "");
args += $" -o {TemplateOutputDir}"; argString += $" -o {TemplateOutputDir}";
// Only run one instance of 'dotnet new' at once, as a workaround for // Only run one instance of 'dotnet new' at once, as a workaround for
// https://github.com/aspnet/templating/issues/63 // https://github.com/aspnet/templating/issues/63
@ -78,7 +86,7 @@ namespace Templates.Test.Helpers
await DotNetNewLock.WaitAsync(); await DotNetNewLock.WaitAsync();
try try
{ {
var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), args); var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), argString);
await execution.Exited; await execution.Exited;
return execution; return execution;
} }

View File

@ -48,7 +48,7 @@ namespace Templates.Test.Helpers
NodeLock = NodeLock, NodeLock = NodeLock,
Output = outputHelper, Output = outputHelper,
DiagnosticsMessageSink = DiagnosticsMessageSink, DiagnosticsMessageSink = DiagnosticsMessageSink,
ProjectGuid = Guid.NewGuid().ToString("N").Substring(0, 6) ProjectGuid = Path.GetRandomFileName().Replace(".", string.Empty)
}; };
project.ProjectName = $"AspNet.{key}.{project.ProjectGuid}"; project.ProjectName = $"AspNet.{key}.{project.ProjectGuid}";

View File

@ -21,6 +21,25 @@ namespace Templates.Test
public ProjectFactoryFixture ProjectFactory { get; } public ProjectFactoryFixture ProjectFactory { get; }
public ITestOutputHelper Output { get; } public ITestOutputHelper Output { get; }
[Fact]
public async Task RazorClassLibraryTemplate_WithViews_Async()
{
Project = await ProjectFactory.GetOrCreateProject("razorclasslibwithviews", Output);
var createResult = await Project.RunDotNetNewAsync("razorclasslib", args: new[] { "--support-pages-and-views", "true" });
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
var publishResult = await Project.RunDotNetPublishAsync();
Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
// Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
// The output from publish will go into bin/Release/netcoreapp3.0/publish and won't be affected by calling build
// later, while the opposite is not true.
var buildResult = await Project.RunDotNetBuildAsync();
Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult));
}
[Fact] [Fact]
public async Task RazorClassLibraryTemplateAsync() public async Task RazorClassLibraryTemplateAsync()
{ {

View File

@ -203,7 +203,7 @@ namespace Templates.Test.SpaTemplateTest
{ {
browser.Exists(By.TagName("ul")); browser.Exists(By.TagName("ul"));
// <title> element gets project ID injected into it during template execution // <title> element gets project ID injected into it during template execution
browser.Contains(Project.ProjectGuid, () => browser.Title); browser.Contains(Project.ProjectGuid.Replace(".", "._"), () => browser.Title);
// Initially displays the home page // Initially displays the home page
browser.Equal("Hello, world!", () => browser.FindElement(By.TagName("h1")).Text); browser.Equal("Hello, world!", () => browser.FindElement(By.TagName("h1")).Text);

View File

@ -871,9 +871,20 @@
} }
}, },
"razorclasslib": { "razorclasslib": {
"None": { "ComponentsOnly": {
"Template": "razorclasslib", "Template": "razorclasslib",
"Arguments": "new razorclasslib", "Arguments": "new razorclasslib",
"Files": [
"wwwroot/background.png",
"wwwroot/exampleJsInterop.js",
"wwwroot/styles.css",
"Component1.razor",
"ExampleJsInterop.cs"
]
},
"ViewsOnly": {
"Template": "razorclasslib",
"Arguments": "new razorclasslib --support-pages-and-views true",
"Files": [ "Files": [
"Areas/MyFeature/Pages/Page1.cshtml", "Areas/MyFeature/Pages/Page1.cshtml",
"Areas/MyFeature/Pages/Page1.cshtml.cs" "Areas/MyFeature/Pages/Page1.cshtml.cs"