public void JsModules_CanHaveDifferentBuildAndPublishModules() { // Arrange var testAsset = "BlazorWasmMinimal"; ProjectDirectory = CreateAspNetSdkTestAsset(testAsset); File.WriteAllText(Path.Combine(ProjectDirectory.TestRoot, "wwwroot", "blazorwasm-minimal.lib.module.js"), "console.log('Publish initializer')"); File.WriteAllText(Path.Combine(ProjectDirectory.TestRoot, "wwwroot", "blazorwasm-minimal.lib.module.build.js"), "console.log('Build initializer')"); ProjectDirectory.WithProjectChanges(document => { document.Root.Add(new XElement("ItemGroup", new XElement("Content", new XAttribute("Update", "wwwroot\\blazorwasm-minimal.lib.module.build.js"), new XAttribute("CopyToPublishDirectory", "Never"), new XAttribute("TargetPath", "wwwroot\\blazorwasm-minimal.lib.module.js")))); }); var publish = new PublishCommand(ProjectDirectory); publish.WithWorkingDirectory(ProjectDirectory.TestRoot); var publishResult = publish.Execute("/bl"); publishResult.Should().Pass(); var outputPath = publish.GetOutputDirectory(DefaultTfm).ToString(); var intermediateOutputPath = publish.GetIntermediateDirectory(DefaultTfm, "Debug").ToString(); var path = Path.Combine(intermediateOutputPath, "staticwebassets.publish.json"); new FileInfo(path).Should().Exist(); var manifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)); AssertManifest(manifest, LoadPublishManifest()); var buildLibrary = GetLibraryInitializer(Path.Combine(intermediateOutputPath, "blazor.boot.json")); var publishLibrary = GetLibraryInitializer(Path.Combine(intermediateOutputPath, "blazor.publish.boot.json")); publishLibrary.GetString().Should().NotBe(buildLibrary.GetString()); new FileInfo(Path.Combine(outputPath, "wwwroot", "blazorwasm-minimal.modules.json")).Should().NotExist(); var lib = new FileInfo(Path.Combine(outputPath, "wwwroot", "blazorwasm-minimal.lib.module.js")); lib.Should().Exist(); var wwwrootPublishLibrary = GetLibraryInitializer(Path.Combine(outputPath, "wwwroot", "_framework", "blazor.boot.json")); publishLibrary.GetString().Should().Be(wwwrootPublishLibrary.GetString()); AssertPublishAssets( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)), outputPath, intermediateOutputPath);
public void StaticWebAssets_HostedApp_ReferencingNetStandardLibrary_Works() { // Arrange var testAppName = "BlazorHosted"; ProjectDirectory = CreateAspNetSdkTestAsset(testAppName); ProjectDirectory.WithProjectChanges((project, document) => { if (Path.GetFileNameWithoutExtension(project) == "blazorwasm") { document.Descendants("TargetFramework").Single().ReplaceNodes("net5"); } if (Path.GetFileNameWithoutExtension(project) == "RazorClassLibrary") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } if (Path.GetFileNameWithoutExtension(project) == "classlibrarywithsatelliteassemblies") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } }); var build = new BuildCommand(ProjectDirectory, "blazorhosted"); build.WithWorkingDirectory(ProjectDirectory.TestRoot); var buildResult = build.Execute("/bl"); buildResult.Should().Pass(); var outputPath = build.GetOutputDirectory(DefaultTfm).ToString(); var intermediateOutputPath = build.GetIntermediateDirectory(DefaultTfm, "Debug").ToString(); // GenerateStaticWebAssetsManifest should generate the manifest file. var path = Path.Combine(intermediateOutputPath, "staticwebassets.build.json"); new FileInfo(path).Should().Exist(); var manifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)); AssertManifest(manifest, LoadBuildManifest()); // GenerateStaticWebAssetsManifest should copy the file to the output folder. var finalPath = Path.Combine(outputPath, "blazorhosted.staticwebassets.runtime.json"); new FileInfo(finalPath).Should().Exist(); AssertBuildAssets( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)), outputPath, intermediateOutputPath); }
public void StaticWebAssets_BackCompatibilityPublish_Hosted_Works() { // Arrange var testAppName = "BlazorHosted"; ProjectDirectory = CreateAspNetSdkTestAsset(testAppName); ProjectDirectory.WithProjectChanges((project, document) => { if (Path.GetFileNameWithoutExtension(project) == "blazorwasm") { document.Descendants("TargetFramework").Single().ReplaceNodes("net5"); } if (Path.GetFileNameWithoutExtension(project) == "RazorClassLibrary") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } if (Path.GetFileNameWithoutExtension(project) == "classlibrarywithsatelliteassemblies") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } }); // Check that static web assets is correctly configured by setting up a css file to triger css isolation. // The list of publish files should not include bundle.scp.css and should include blazorwasm.styles.css File.WriteAllText(Path.Combine(ProjectDirectory.TestRoot, "blazorwasm", "App.razor.css"), "h1 { font-size: 16px; }"); var publish = new PublishCommand(ProjectDirectory, "blazorhosted"); publish.WithWorkingDirectory(ProjectDirectory.TestRoot); var publishResult = publish.Execute("/bl"); publishResult.Should().Pass(); var publishPath = publish.GetOutputDirectory(DefaultTfm).ToString(); var intermediateOutputPath = publish.GetIntermediateDirectory(DefaultTfm, "Debug").ToString(); // GenerateStaticWebAssetsManifest should generate the manifest file. var path = Path.Combine(intermediateOutputPath, "staticwebassets.publish.json"); new FileInfo(path).Should().Exist(); var manifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)); AssertManifest(manifest, LoadPublishManifest()); AssertPublishAssets( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)), publishPath, intermediateOutputPath); }
public void StaticWebAssets_BackCompatibilityPublish_Hosted_Works() { // Arrange var testAppName = "BlazorHosted"; ProjectDirectory = CreateAspNetSdkTestAsset(testAppName); ProjectDirectory.WithProjectChanges((project, document) => { if (Path.GetFileNameWithoutExtension(project) == "blazorwasm") { document.Descendants("TargetFramework").Single().ReplaceNodes("net5"); } if (Path.GetFileNameWithoutExtension(project) == "RazorClassLibrary") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } if (Path.GetFileNameWithoutExtension(project) == "classlibrarywithsatelliteassemblies") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } }); // Check that static web assets is correctly configured by setting up a css file to triger css isolation. // The list of publish files should not include bundle.scp.css and should include blazorwasm.styles.css File.WriteAllText(Path.Combine(ProjectDirectory.TestRoot, "blazorwasm", "App.razor.css"), "h1 { font-size: 16px; }"); var publish = new PublishCommand(ProjectDirectory, "blazorhosted"); publish.WithWorkingDirectory(ProjectDirectory.TestRoot); var publishResult = publish.Execute("/bl"); publishResult.Should().Pass(); var publishPath = publish.GetOutputDirectory(DefaultTfm).ToString(); var intermediateOutputPath = publish.GetIntermediateDirectory(DefaultTfm, "Debug").ToString(); // GenerateStaticWebAssetsManifest should generate the manifest file. var path = Path.Combine(intermediateOutputPath, "staticwebassets.publish.json"); new FileInfo(path).Should().Exist(); var manifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)); // We have to special case this test given we are forcing `blazorwasm` to be a `net5` project above. // Given this, the `dotnet.*.js` file produced will be a dotnet.5.*.*.js file in line with the TFM and not the SDK (which is .NET 6 or beyond). // This conflicts with our assumptions throughout the rest of the test suite that the SDK version matches the TFM. // To minimize special casing throughout the entire test suite, we just update this particular test's assets to reflect the SDK version. var numFilesUpdated = 0; var frameworkFolder = Path.Combine(publishPath, "wwwroot", "_framework"); var frameworkFolderFiles = Directory.GetFiles(frameworkFolder, "*", new EnumerationOptions { RecurseSubdirectories = false }); foreach (var f in frameworkFolderFiles) { if (Regex.Match(f, DotNet5JSRegexPattern).Success) { File.Move(f, Regex.Replace(f, DotNet5JSRegexPattern, DotNet5JSTemplate)); numFilesUpdated++; } } Assert.Equal(3, numFilesUpdated); AssertManifest(manifest, LoadPublishManifest()); AssertPublishAssets( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)), publishPath, intermediateOutputPath); }
public void StaticWebAssets_HostedApp_ReferencingNetStandardLibrary_Works() { // Arrange var testAppName = "BlazorHosted"; ProjectDirectory = CreateAspNetSdkTestAsset(testAppName); ProjectDirectory.WithProjectChanges((project, document) => { if (Path.GetFileNameWithoutExtension(project) == "blazorwasm") { document.Descendants("TargetFramework").Single().ReplaceNodes("net5"); } if (Path.GetFileNameWithoutExtension(project) == "RazorClassLibrary") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } if (Path.GetFileNameWithoutExtension(project) == "classlibrarywithsatelliteassemblies") { document.Descendants("TargetFramework").Single().ReplaceNodes("netstandard2.1"); document.Descendants("PropertyGroup").First().Add(new XElement("RazorLangVersion", "3.0")); } }); var build = new BuildCommand(ProjectDirectory, "blazorhosted"); build.WithWorkingDirectory(ProjectDirectory.TestRoot); var buildResult = build.Execute("/bl"); buildResult.Should().Pass(); var outputPath = build.GetOutputDirectory(DefaultTfm).ToString(); var intermediateOutputPath = build.GetIntermediateDirectory(DefaultTfm, "Debug").ToString(); // GenerateStaticWebAssetsManifest should generate the manifest file. var path = Path.Combine(intermediateOutputPath, "staticwebassets.build.json"); new FileInfo(path).Should().Exist(); var manifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)); // We have to special case this test given we are forcing `blazorwasm` to be a `net5` project above. // Given this, the `dotnet.*.js` file produced will be a dotnet.5.*.*.js file in line with the TFM and not the SDK (which is .NET 6 or beyond). // This conflicts with our assumptions throughout the rest of the test suite that the SDK version matches the TFM. // To minimize special casing throughout the entire test suite, we just update this particular test's assets to reflect the SDK version. var numFilesUpdated = 0; foreach (var f in manifest.Assets) { if (Regex.Match(f.RelativePath, DotNet5JSRegexPattern).Success) { f.Identity = Regex.Replace(f.Identity, DotNet5JSRegexPattern, DotNet5JSTemplate); f.RelativePath = Regex.Replace(f.RelativePath, DotNet5JSRegexPattern, DotNet5JSTemplate); f.OriginalItemSpec = Regex.Replace(f.OriginalItemSpec, DotNet5JSRegexPattern, DotNet5JSTemplate); numFilesUpdated++; } } Assert.Equal(2, numFilesUpdated); AssertManifest(manifest, LoadBuildManifest()); // GenerateStaticWebAssetsManifest should copy the file to the output folder. var finalPath = Path.Combine(outputPath, "blazorhosted.staticwebassets.runtime.json"); new FileInfo(finalPath).Should().Exist(); AssertBuildAssets( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)), outputPath, intermediateOutputPath); }
public void Build_SatelliteAssembliesAreCopiedToBuildOutput() { // Arrange var testAppName = "BlazorWasmWithLibrary"; ProjectDirectory = CreateAspNetSdkTestAsset(testAppName); ProjectDirectory.WithProjectChanges((path, project) => { if (path.Contains("blazorwasm")) { var ns = project.Root.Name.Namespace; var propertyGroup = new XElement(ns + "PropertyGroup"); propertyGroup.Add(new XElement("DefineConstants", @"$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies")); var itemGroup = new XElement(ns + "ItemGroup"); itemGroup.Add(new XElement("ProjectReference", new XAttribute("Include", @"..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"))); project.Root.Add(propertyGroup); project.Root.Add(itemGroup); } }); var resxfileInProject = Path.Combine(ProjectDirectory.TestRoot, "blazorwasm", "Resources.ja.resx.txt"); File.Move(resxfileInProject, Path.Combine(ProjectDirectory.TestRoot, "blazorwasm", "Resource.ja.resx")); var buildCommand = new BuildCommand(ProjectDirectory, "blazorwasm"); buildCommand.WithWorkingDirectory(ProjectDirectory.TestRoot); buildCommand.Execute("/bl").Should().Pass(); var outputPath = buildCommand.GetOutputDirectory(DefaultTfm).ToString(); var intermediateOutputPath = buildCommand.GetIntermediateDirectory(DefaultTfm).ToString(); // GenerateStaticWebAssetsManifest should generate the manifest file. var path = Path.Combine(intermediateOutputPath, "staticwebassets.build.json"); new FileInfo(path).Should().Exist(); var manifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)); AssertManifest(manifest, LoadBuildManifest()); // GenerateStaticWebAssetsManifest should copy the file to the output folder. var finalPath = Path.Combine(outputPath, "blazorwasm.staticwebassets.runtime.json"); new FileInfo(finalPath).Should().Exist(); AssertBuildAssets( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)), outputPath, intermediateOutputPath); new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "blazorwasm.dll")).Should().Exist(); new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "classlibrarywithsatelliteassemblies.dll")).Should().Exist(); new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "Microsoft.CodeAnalysis.CSharp.dll")).Should().Exist(); new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll")).Should().Exist(); var bootJsonPath = new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "blazor.boot.json")); bootJsonPath.Should().Contain("\"Microsoft.CodeAnalysis.CSharp.dll\""); bootJsonPath.Should().Contain("\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); }
public void PublishProjectWithReferences_DifferentBuildAndPublish_LibraryInitializers() { var testAsset = "RazorAppWithPackageAndP2PReference"; ProjectDirectory = CreateAspNetSdkTestAsset(testAsset); var restore = new RestoreCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); restore.Execute().Should().Pass(); CreateFile("console.log('Hello world AnotherClassLib publish')", "AnotherClassLib", "wwwroot", "AnotherClassLib.lib.module.js"); CreateFile("console.log('Hello world AnotherClassLib')", "AnotherClassLib", "wwwroot", "AnotherClassLib.lib.module.build.js"); ProjectDirectory.WithProjectChanges((project, document) => { if (project.EndsWith("AnotherClassLib.csproj")) { document.Root.Add(new XElement("ItemGroup", new XElement("Content", new XAttribute("Update", "wwwroot\\AnotherClassLib.lib.module.build.js"), new XAttribute("CopyToPublishDirectory", "Never"), new XAttribute("TargetPath", "wwwroot\\AnotherClassLib.lib.module.js")))); } }); var publish = new PublishCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); publish.WithWorkingDirectory(ProjectDirectory.Path); publish.Execute("/bl").Should().Pass(); var intermediateOutputPath = publish.GetIntermediateDirectory(DefaultTfm, "Debug").ToString(); var outputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); var path = Path.Combine(intermediateOutputPath, "staticwebassets.build.json");; var buildManifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path)); var initializers = buildManifest.Assets.Where(a => a.RelativePath == "AnotherClassLib.lib.module.js"); initializers.Should().HaveCount(1); initializers.Should().Contain(a => a.IsBuildOnly()); AssertManifest( buildManifest, LoadBuildManifest()); var finalPath = Path.Combine(intermediateOutputPath, "staticwebassets.publish.json"); AssertManifest( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(finalPath)), LoadPublishManifest()); AssertBuildAssets( StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(finalPath)), outputPath, intermediateOutputPath); var modulesManifest = new FileInfo(Path.Combine(outputPath, "wwwroot", "AppWithPackageAndP2PReference.modules.json")); modulesManifest.Should().Exist(); modulesManifest.Should().Contain("_content/AnotherClassLib/AnotherClassLib.lib.module.js"); modulesManifest.Should().NotContain("_content/ClassLibrary/AnotherClassLib.lib.module.js"); var moduleFile = new FileInfo(Path.Combine(outputPath, "wwwroot", "_content", "AnotherClassLib", "AnotherClassLib.lib.module.js")); moduleFile.Should().Exist(); moduleFile.Should().Contain("console.log('Hello world AnotherClassLib publish')"); }