Browse Source

Merge pull request #6281 from abpframework/refactor-abp-bundle

Bundle command refactoring
pull/6290/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
e8ed831aa0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      docs/en/UI/Blazor/Global-Scripts-Styles.md
  2. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeBundleContributor.cs
  3. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ThemingBundleContributor.cs
  4. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ComponentsWebAssemblyBundleContributor.cs
  5. 2
      framework/src/Volo.Abp.BlazoriseUI/BlazoriseUIBundleContributor.cs
  6. 1
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundleTypeDefinition.cs
  7. 9
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingException.cs
  8. 122
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs
  9. 9
      framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleContext.cs
  10. 6
      framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleDefinition.cs
  11. 2
      framework/src/Volo.Abp.Core/Volo/Abp/Bundling/IBundleContributor.cs
  12. 2
      framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/IdentityModelWebAssemblyBundleContributor.cs
  13. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameBundleContributor.cs
  14. 16
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/index.html

8
docs/en/UI/Blazor/Global-Scripts-Styles.md

@ -4,9 +4,9 @@ Some modules may require additional styles or scripts that need to be referenced
To update script & style references without worrying about dependencies, ordering, etc in a project, you can use the [bundle command](../../CLI.md#bundle). To update script & style references without worrying about dependencies, ordering, etc in a project, you can use the [bundle command](../../CLI.md#bundle).
You can also add custom styles and scripts and let ABP manage them for you. In your Blazor project, you can create a class implementing `IBundleContributer` interface. You can also add custom styles and scripts and let ABP manage them for you. In your Blazor project, you can create a class implementing `IBundleContributor` interface.
`IBundleContributer` interface contains two methods. `IBundleContributor` interface contains two methods.
* `AddScripts(...)` * `AddScripts(...)`
* `AddStyles(...)` * `AddStyles(...)`
@ -17,7 +17,7 @@ Both methods get `BundleContext` as a parameter. You can add scripts and styles
```csharp ```csharp
namespace MyProject.Blazor namespace MyProject.Blazor
{ {
public class MyProjectBundleContributer : IBundleContributer public class MyProjectBundleContributor : IBundleContributor
{ {
public void AddScripts(BundleContext context) public void AddScripts(BundleContext context)
{ {
@ -33,6 +33,6 @@ namespace MyProject.Blazor
} }
``` ```
> There is a BundleContributer class implementing `IBundleContributer` interface coming by default with the startup templates. So, most of the time, you don't need to add it manually. > There is a BundleContributor class implementing `IBundleContributor` interface coming by default with the startup templates. So, most of the time, you don't need to add it manually.
> Bundle command adds style and script references individually. Bundling and minification support will be added to incoming releases. > Bundle command adds style and script references individually. Bundling and minification support will be added to incoming releases.

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeBundleContributer.cs → framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/BasicThemeBundleContributor.cs

@ -2,7 +2,7 @@
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme
{ {
public class BasicThemeBundleContributer : IBundleContributer public class BasicThemeBundleContributor : IBundleContributor
{ {
public void AddScripts(BundleContext context) public void AddScripts(BundleContext context)
{ {

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ThemingBundleContributer.cs → framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/ThemingBundleContributor.cs

@ -2,7 +2,7 @@
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming
{ {
public class ThemingBundleContributer : IBundleContributer public class ThemingBundleContributor : IBundleContributor
{ {
public void AddScripts(BundleContext context) public void AddScripts(BundleContext context)
{ {

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ComponentsWebAssemblyBundleContributer.cs → framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ComponentsWebAssemblyBundleContributor.cs

@ -2,7 +2,7 @@
namespace Volo.Abp.AspNetCore.Components.WebAssembly namespace Volo.Abp.AspNetCore.Components.WebAssembly
{ {
public class ComponentsWebAssemblyBundleContributer : IBundleContributer public class ComponentsWebAssemblyBundleContributor : IBundleContributor
{ {
public void AddScripts(BundleContext context) public void AddScripts(BundleContext context)
{ {

2
framework/src/Volo.Abp.BlazoriseUI/BlazoriseUIBundleContributer.cs → framework/src/Volo.Abp.BlazoriseUI/BlazoriseUIBundleContributor.cs

@ -2,7 +2,7 @@
namespace Volo.Abp.BlazoriseUI namespace Volo.Abp.BlazoriseUI
{ {
public class BlazoriseUIBundleContributer : IBundleContributer public class BlazoriseUIBundleContributor : IBundleContributor
{ {
public void AddScripts(BundleContext context) public void AddScripts(BundleContext context)
{ {

1
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundleTypeDefinition.cs

@ -5,6 +5,7 @@ namespace Volo.Abp.Cli.Bundling
internal class BundleTypeDefinition internal class BundleTypeDefinition
{ {
public int Level { get; set; } public int Level { get; set; }
public Type BundleContributerType { get; set; } public Type BundleContributerType { get; set; }
} }
} }

9
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingException.cs

@ -1,10 +1,9 @@
using System; namespace Volo.Abp.Cli.Bundling
namespace Volo.Abp.Cli.Bundling
{ {
public class BundlingException : Exception public class BundlingException : AbpException
{ {
public BundlingException(string message) : base(message) public BundlingException(string message)
: base(message)
{ {
} }

122
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs

@ -1,5 +1,4 @@
using Microsoft.CodeAnalysis.CSharp; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -29,7 +28,7 @@ namespace Volo.Abp.Cli.Bundling
var projectFiles = Directory.GetFiles(directory, "*.csproj"); var projectFiles = Directory.GetFiles(directory, "*.csproj");
if (!projectFiles.Any()) if (!projectFiles.Any())
{ {
throw new BundlingException("No project file found in the directory"); throw new BundlingException("No project file found in the directory. The working directory must have a Blazor project file.");
} }
var projectFilePath = projectFiles[0]; var projectFilePath = projectFiles[0];
@ -40,7 +39,7 @@ namespace Volo.Abp.Cli.Bundling
{ {
new DotNetProjectInfo(string.Empty, projectFilePath, true) new DotNetProjectInfo(string.Empty, projectFilePath, true)
}; };
DotNetProjectBuilder.BuildProjects(projects, string.Empty); DotNetProjectBuilder.BuildProjects(projects, string.Empty);
} }
@ -63,11 +62,13 @@ namespace Volo.Abp.Cli.Bundling
private BundleContext GetScriptContext(List<BundleTypeDefinition> bundleDefinitions) private BundleContext GetScriptContext(List<BundleTypeDefinition> bundleDefinitions)
{ {
var scriptContext = new BundleContext(); var scriptContext = new BundleContext();
foreach (var bundleDefinition in bundleDefinitions) foreach (var bundleDefinition in bundleDefinitions)
{ {
var contributer = CreateContributerInstance(bundleDefinition.BundleContributerType); var contributer = CreateContributerInstance(bundleDefinition.BundleContributerType);
contributer.AddScripts(scriptContext); contributer.AddScripts(scriptContext);
} }
scriptContext.Add("_framework/blazor.webassembly.js"); scriptContext.Add("_framework/blazor.webassembly.js");
return scriptContext; return scriptContext;
} }
@ -75,11 +76,13 @@ namespace Volo.Abp.Cli.Bundling
private BundleContext GetStyleContext(List<BundleTypeDefinition> bundleDefinitions) private BundleContext GetStyleContext(List<BundleTypeDefinition> bundleDefinitions)
{ {
var styleContext = new BundleContext(); var styleContext = new BundleContext();
foreach (var bundleDefinition in bundleDefinitions) foreach (var bundleDefinition in bundleDefinitions)
{ {
var contributer = CreateContributerInstance(bundleDefinition.BundleContributerType); var contributer = CreateContributerInstance(bundleDefinition.BundleContributerType);
contributer.AddStyles(styleContext); contributer.AddStyles(styleContext);
}; }
return styleContext; return styleContext;
} }
@ -102,9 +105,11 @@ namespace Volo.Abp.Cli.Bundling
content = UpdatePlaceholders(content, StylePlaceholderStart, StylePlaceholderEnd, styleDefinitions); content = UpdatePlaceholders(content, StylePlaceholderStart, StylePlaceholderEnd, styleDefinitions);
content = UpdatePlaceholders(content, ScriptPlaceholderStart, ScriptPlaceholderEnd, scriptDefinitions); content = UpdatePlaceholders(content, ScriptPlaceholderStart, ScriptPlaceholderEnd, scriptDefinitions);
using var writer = new StreamWriter(htmlFilePath, false, fileEncoding); using (var writer = new StreamWriter(htmlFilePath, false, fileEncoding))
await writer.WriteAsync(content); {
await writer.FlushAsync(); await writer.WriteAsync(content);
await writer.FlushAsync();
}
} }
private string UpdatePlaceholders(string content, string placeholderStart, string placeholderEnd, string definitions) private string UpdatePlaceholders(string content, string placeholderStart, string placeholderEnd, string definitions)
@ -118,24 +123,22 @@ namespace Volo.Abp.Cli.Bundling
private string GenerateStyleDefinitions(BundleContext context) private string GenerateStyleDefinitions(BundleContext context)
{ {
var builder = new StringBuilder(); var builder = new StringBuilder();
builder.AppendLine($"{StylePlaceholderStart}"); builder.AppendLine($"{StylePlaceholderStart}");
foreach (var style in context.BundleDefinitions) foreach (var style in context.BundleDefinitions)
{ {
if (style.AdditionalProperties != null && style.AdditionalProperties.Any()) builder.Append($" <link href=\"{style.Source}\" rel=\"stylesheet\"");
{
builder.Append($"\t<link href=\"{style.Source}\" rel=\"stylesheet\" "); foreach (var additionalProperty in style.AdditionalProperties)
foreach (var additionalProperty in style.AdditionalProperties)
{
builder.Append($"{additionalProperty.Key}={additionalProperty.Value} ");
}
builder.AppendLine("/>");
}
else
{ {
builder.AppendLine($"\t<link href=\"{style.Source}\" rel=\"stylesheet\" />"); builder.Append($"{additionalProperty.Key}={additionalProperty.Value} ");
} }
builder.AppendLine("/>");
} }
builder.Append($"\t{StylePlaceholderEnd}");
builder.Append($" {StylePlaceholderEnd}");
return builder.ToString(); return builder.ToString();
} }
@ -146,50 +149,41 @@ namespace Volo.Abp.Cli.Bundling
builder.AppendLine($"{ScriptPlaceholderStart}"); builder.AppendLine($"{ScriptPlaceholderStart}");
foreach (var script in context.BundleDefinitions) foreach (var script in context.BundleDefinitions)
{ {
if (script.AdditionalProperties != null && script.AdditionalProperties.Any()) builder.Append($" <script src=\"{script.Source}\"");
{ foreach (var additionalProperty in script.AdditionalProperties)
builder.Append($"\t<script src=\"{script.Source}\" ");
foreach (var additionalProperty in script.AdditionalProperties)
{
builder.Append($"{additionalProperty.Key}={additionalProperty.Value} ");
}
builder.AppendLine("></script>");
}
else
{ {
builder.AppendLine($"\t<script src=\"{script.Source}\"></script>"); builder.Append($"{additionalProperty.Key}={additionalProperty.Value} ");
} }
builder.AppendLine("></script>");
} }
builder.Append($"\t{ScriptPlaceholderEnd}"); builder.Append($" {ScriptPlaceholderEnd}");
return builder.ToString(); return builder.ToString();
} }
private IBundleContributer CreateContributerInstance(Type bundleContributerType) private IBundleContributor CreateContributerInstance(Type bundleContributerType)
{ {
var instance = Activator.CreateInstance(bundleContributerType); return (IBundleContributor)Activator.CreateInstance(bundleContributerType);
return instance.As<IBundleContributer>();
} }
private void ExecuteBundleContributers(List<BundleTypeDefinition> bundleDefinitions, BundleContext styleContext, BundleContext scriptContext) private void FindBundleContributersRecursively(
Type module,
int level,
List<BundleTypeDefinition> bundleDefinitions)
{ {
foreach (var bundleDefinition in bundleDefinitions) var bundleContributers = module.Assembly
.GetTypes()
.Where(t => t.IsAssignableTo<IBundleContributor>())
.ToList();
if (bundleContributers.Count > 1)
{ {
var contributer = CreateContributerInstance(bundleDefinition.BundleContributerType); throw new BundlingException($"Each project must contain only one class implementing {nameof(IBundleContributor)}");
contributer.AddStyles(styleContext);
contributer.AddScripts(scriptContext);
} }
}
private void FindBundleContributersRecursively(Type module, int level, List<BundleTypeDefinition> bundleDefinitions)
{
var dependencyDescriptors = module
.GetCustomAttributes()
.OfType<IDependedTypesProvider>();
var bundleContributer = module.Assembly.GetTypes().SingleOrDefault(t => t.IsAssignableTo<IBundleContributer>()); if (bundleContributers.Any())
if (bundleContributer != null)
{ {
var bundleContributer = bundleContributers[0];
var definition = bundleDefinitions.SingleOrDefault(t => t.BundleContributerType == bundleContributer); var definition = bundleDefinitions.SingleOrDefault(t => t.BundleContributerType == bundleContributer);
if (definition != null) if (definition != null)
{ {
@ -208,6 +202,10 @@ namespace Volo.Abp.Cli.Bundling
} }
} }
var dependencyDescriptors = module
.GetCustomAttributes()
.OfType<IDependedTypesProvider>();
foreach (var descriptor in dependencyDescriptors) foreach (var descriptor in dependencyDescriptors)
{ {
foreach (var dependedModuleType in descriptor.GetDependedTypes()) foreach (var dependedModuleType in descriptor.GetDependedTypes())
@ -219,19 +217,10 @@ namespace Volo.Abp.Cli.Bundling
private Type GetStartupModule(string assemblyPath) private Type GetStartupModule(string assemblyPath)
{ {
var assembly = Assembly.LoadFrom(assemblyPath); return Assembly
return assembly.GetTypes().SingleOrDefault(IsAbpModule); .LoadFrom(assemblyPath)
.GetTypes()
static bool IsAbpModule(Type type) .SingleOrDefault(AbpModule.IsAbpModule);
{
var typeInfo = type.GetTypeInfo();
return
typeInfo.IsClass &&
!typeInfo.IsAbstract &&
!typeInfo.IsGenericType &&
typeof(IAbpModule).GetTypeInfo().IsAssignableFrom(type);
}
} }
private string GetFrameworkFolderPath(string projectDirectory, string frameworkVersion) private string GetFrameworkFolderPath(string projectDirectory, string frameworkVersion)
@ -244,15 +233,12 @@ namespace Volo.Abp.Cli.Bundling
var document = new XmlDocument(); var document = new XmlDocument();
document.Load(projectFilePath); document.Load(projectFilePath);
var sdk = document.DocumentElement.GetAttribute("Sdk"); var sdk = document.DocumentElement.GetAttribute("Sdk");
if (sdk == SupportedWebAssemblyProjectType) if (sdk != SupportedWebAssemblyProjectType)
{
var frameworkVersion = document.SelectSingleNode("//TargetFramework").InnerText;
return frameworkVersion;
}
else
{ {
throw new BundlingException($"Unsupported project type. Project type must be {SupportedWebAssemblyProjectType}."); throw new BundlingException($"Unsupported project type. Project type must be {SupportedWebAssemblyProjectType}.");
} }
return document.SelectSingleNode("//TargetFramework").InnerText;
} }
private string GetAssemblyFilePath(string directory, string frameworkVersion, string projectFileName) private string GetAssemblyFilePath(string directory, string frameworkVersion, string projectFileName)

9
framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleContext.cs

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
namespace Volo.Abp.Bundling namespace Volo.Abp.Bundling
{ {
@ -17,9 +16,13 @@ namespace Volo.Abp.Bundling
var bundleDefinition = new BundleDefinition var bundleDefinition = new BundleDefinition
{ {
Source = source, Source = source,
AdditionalProperties = additionalProperties
}; };
if (additionalProperties != null)
{
bundleDefinition.AdditionalProperties = additionalProperties;
}
BundleDefinitions.AddIfNotContains((item) => item.Source == bundleDefinition.Source, () => bundleDefinition); BundleDefinitions.AddIfNotContains((item) => item.Source == bundleDefinition.Source, () => bundleDefinition);
} }
} }

6
framework/src/Volo.Abp.Core/Volo/Abp/Bundling/BundleDefinition.cs

@ -5,6 +5,12 @@ namespace Volo.Abp.Bundling
public class BundleDefinition public class BundleDefinition
{ {
public string Source { get; set; } public string Source { get; set; }
public Dictionary<string, string> AdditionalProperties { get; set; } public Dictionary<string, string> AdditionalProperties { get; set; }
public BundleDefinition()
{
AdditionalProperties = new Dictionary<string, string>();
}
} }
} }

2
framework/src/Volo.Abp.Core/Volo/Abp/Bundling/IBundleContributer.cs → framework/src/Volo.Abp.Core/Volo/Abp/Bundling/IBundleContributor.cs

@ -1,6 +1,6 @@
namespace Volo.Abp.Bundling namespace Volo.Abp.Bundling
{ {
public interface IBundleContributer public interface IBundleContributor
{ {
void AddScripts(BundleContext context); void AddScripts(BundleContext context);
void AddStyles(BundleContext context); void AddStyles(BundleContext context);

2
framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/IdentityModelWebAssemblyBundleContributer.cs → framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/IdentityModelWebAssemblyBundleContributor.cs

@ -2,7 +2,7 @@
namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly
{ {
public class IdentityModelWebAssemblyBundleContributer : IBundleContributer public class IdentityModelWebAssemblyBundleContributor : IBundleContributor
{ {
public void AddScripts(BundleContext context) public void AddScripts(BundleContext context)
{ {

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameBundleContributer.cs → templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyProjectNameBundleContributor.cs

@ -2,7 +2,7 @@
namespace MyCompanyName.MyProjectName.Blazor namespace MyCompanyName.MyProjectName.Blazor
{ {
public class MyProjectNameBundleContributer : IBundleContributer public class MyProjectNameBundleContributor : IBundleContributor
{ {
public void AddScripts(BundleContext context) public void AddScripts(BundleContext context)
{ {

16
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/index.html

@ -8,14 +8,14 @@
<base href="/" /> <base href="/" />
<!--ABP:Styles--> <!--ABP:Styles-->
<link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" /> <link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/bootstrap/css/bootstrap.min.css" rel="stylesheet"/>
<link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/fontawesome/css/all.css" rel="stylesheet" /> <link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/fontawesome/css/all.css" rel="stylesheet"/>
<link href="_content/Blazorise/blazorise.css" rel="stylesheet" /> <link href="_content/Blazorise/blazorise.css" rel="stylesheet"/>
<link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet" /> <link href="_content/Blazorise.Bootstrap/blazorise.bootstrap.css" rel="stylesheet"/>
<link href="_content/Blazorise.Snackbar/blazorise.snackbar.css" rel="stylesheet" /> <link href="_content/Blazorise.Snackbar/blazorise.snackbar.css" rel="stylesheet"/>
<link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/flag-icon/css/flag-icon.css" rel="stylesheet" /> <link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/flag-icon/css/flag-icon.css" rel="stylesheet"/>
<link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/libs/abp/css/theme.css" rel="stylesheet" /> <link href="_content/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/libs/abp/css/theme.css" rel="stylesheet"/>
<link href="main.css" rel="stylesheet" /> <link href="main.css" rel="stylesheet"/>
<!--/ABP:Styles--> <!--/ABP:Styles-->
</head> </head>

Loading…
Cancel
Save