Browse Source

Merge branch 'rel-7.0' of https://github.com/abpframework/abp into rel-7.0

pull/14641/head 7.0.0-rc.1
voloagent 4 years ago
parent
commit
abc99f7f16
  1. 9
      docs/en/CLI.md
  2. 21
      docs/zh-Hans/CLI.md
  3. 3
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundleOptions.cs
  4. 29
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs
  5. 3
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingConsts.cs
  6. 57
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs
  7. 2
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/IBundlingService.cs
  8. 12
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/PathHelper.cs
  9. 25
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BundleCommand.cs

9
docs/en/CLI.md

@ -45,7 +45,7 @@ Here, is the list of all available commands before explaining their details:
* **`login`**: Authenticates on your computer with your [abp.io](https://abp.io/) username and password. * **`login`**: Authenticates on your computer with your [abp.io](https://abp.io/) username and password.
* **`login-info`**: Shows the current user's login information. * **`login-info`**: Shows the current user's login information.
* **`logout`**: Logouts from your computer if you've authenticated before. * **`logout`**: Logouts from your computer if you've authenticated before.
* **`bundle`**: Generates script and style references for an ABP Blazor project. * **`bundle`**: Generates script and style references for ABP Blazor and MAUI Blazor project.
* **`install-libs`**: Install NPM Packages for MVC / Razor Pages and Blazor Server UI types. * **`install-libs`**: Install NPM Packages for MVC / Razor Pages and Blazor Server UI types.
### help ### help
@ -531,7 +531,7 @@ abp logout
### bundle ### bundle
This command generates script and style references for an ABP Blazor WebAssembly project and updates the **index.html** file. It helps developers to manage dependencies required by ABP modules easily. In order ```bundle``` command to work, its **executing directory** or passed ```--working-directory``` parameter's directory must contain a Blazor project file(*.csproj). This command generates script and style references for ABP Blazor WebAssembly and MAUI Blazor project and updates the **index.html** file. It helps developers to manage dependencies required by ABP modules easily. In order ```bundle``` command to work, its **executing directory** or passed ```--working-directory``` parameter's directory must contain a Blazor or MAUI Blazor project file(*.csproj).
Usage: Usage:
@ -543,8 +543,11 @@ abp bundle [options]
* ```--working-directory``` or ```-wd```: Specifies the working directory. This option is useful when executing directory doesn't contain a Blazor project file. * ```--working-directory``` or ```-wd```: Specifies the working directory. This option is useful when executing directory doesn't contain a Blazor project file.
* ```--force``` or ```-f```: Forces to build project before generating references. * ```--force``` or ```-f```: Forces to build project before generating references.
* ```--project-type``` or ```-t```: Specifies the project type. Default type is `webassembly`. Available types:
* `webassembly`
* `maui-blazor`
`bundle` command reads the `appsettings.json` file inside the Blazor project for bundling options. For more details about managing style and script references in Blazor apps, see [Managing Global Scripts & Styles](UI/Blazor/Global-Scripts-Styles.md) `bundle` command reads the `appsettings.json` file inside the Blazor and MAUI Blazor project for bundling options. For more details about managing style and script references in Blazor or MAUI Blazor apps, see [Managing Global Scripts & Styles](UI/Blazor/Global-Scripts-Styles.md)
### install-libs ### install-libs

21
docs/zh-Hans/CLI.md

@ -42,6 +42,7 @@ dotnet tool update -g Volo.Abp.Cli
* **`login`**: 使用你在[abp.io](https://abp.io/)的用户名和密码在你的计算机上认证. * **`login`**: 使用你在[abp.io](https://abp.io/)的用户名和密码在你的计算机上认证.
* **`login-info`**: 展示当前登录用户信息. * **`login-info`**: 展示当前登录用户信息.
* **`logout`**: 在你的计算机注销认证. * **`logout`**: 在你的计算机注销认证.
* **`bundle`**: 为 ABP Blazor 和 MAUI Blazor 项目生成引用的脚本和样式.
* **`install-libs`**: 为 MVC / Razor Pages 和 Blazor Server UI 类型安装NPM包. * **`install-libs`**: 为 MVC / Razor Pages 和 Blazor Server UI 类型安装NPM包.
### help ### help
@ -432,6 +433,26 @@ abp login-info
abp logout abp logout
``` ```
### bundle
这个命令为ABP Blazor WebAssembly 和 MAUI Blazor 项目生成引用的脚本和样式并且更新 **index.html** 文件, 它帮助开发者轻松的管理ABP模块的依赖. 为了使 ```bundle``` 命令工作, 它的**执行目录**或者传递 ```--working-directory``` 参数的目录必须包含Blazor或MAUI Blazor项目文件(*.csproj)
用法:
````bash
abp bundle [options]
````
#### Options
* ```--working-directory``` 或 ```-wd```: 指定当前执行目录, 这个命令在当前目录不包含项目文件时非常有用.
* ```--force``` 或 ```-f```: 在生成引用之前强制构建项目.
* ```--project-type``` 或 ```-t```: 指定项目类型. 默认类型是 `webassembly`. 可用的类型有:
* `webassembly`
* `maui-blazor`
`bundle` command reads the `appsettings.json` file inside the Blazor and MAUI Blazor project for bundling options. For more details about managing style and script references in Blazor or MAUI Blazor apps, see [Managing Global Scripts & Styles](UI/Blazor/Global-Scripts-Styles.md)
### install-libs ### install-libs
为 MVC / Razor Pages 和 Blazor Server UI 类型安装NPM包, 它的 **执行目录** 或者传递的 ```--working-directory``` 目录必须包含一个项目文件(*.csproj). 为 MVC / Razor Pages 和 Blazor Server UI 类型安装NPM包, 它的 **执行目录** 或者传递的 ```--working-directory``` 目录必须包含一个项目文件(*.csproj).

3
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundleOptions.cs

@ -15,6 +15,9 @@ public class BundleOptions
[NotNull] [NotNull]
public string ProjectFileName { get; set; } public string ProjectFileName { get; set; }
[NotNull]
public string ProjectType { get; set; }
public bool Minify { get; set; } public bool Minify { get; set; }
} }

29
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlerBase.cs

@ -35,7 +35,7 @@ public abstract class BundlerBase : IBundler, ITransientDependency
var bundleFileDefinitions = context.BundleDefinitions.Where(t => t.ExcludeFromBundle == false).ToList(); var bundleFileDefinitions = context.BundleDefinitions.Where(t => t.ExcludeFromBundle == false).ToList();
var fileDefinitionsExcludingFromBundle = context.BundleDefinitions.Where(t => t.ExcludeFromBundle).ToList(); var fileDefinitionsExcludingFromBundle = context.BundleDefinitions.Where(t => t.ExcludeFromBundle).ToList();
var bundledContent = BundleFiles(options, bundleFileDefinitions); var bundledContent = options.ProjectType == BundlingConsts.WebAssembly? BundleWebAssemblyFiles(options, bundleFileDefinitions) : BundleMauiBlazorFiles(options, bundleFileDefinitions);
File.WriteAllText(bundleFilePath, bundledContent); File.WriteAllText(bundleFilePath, bundledContent);
return GenerateDefinition(bundleFilePath,fileDefinitionsExcludingFromBundle); return GenerateDefinition(bundleFilePath,fileDefinitionsExcludingFromBundle);
@ -59,7 +59,7 @@ public abstract class BundlerBase : IBundler, ITransientDependency
return false; return false;
} }
private string BundleFiles(BundleOptions options, List<BundleDefinition> bundleDefinitions) private string BundleWebAssemblyFiles(BundleOptions options, List<BundleDefinition> bundleDefinitions)
{ {
var staticAssetsFilePath = Path.Combine(options.Directory, "bin", "Debug", options.FrameworkVersion, var staticAssetsFilePath = Path.Combine(options.Directory, "bin", "Debug", options.FrameworkVersion,
$"{options.ProjectFileName}.staticwebassets.runtime.json"); $"{options.ProjectFileName}.staticwebassets.runtime.json");
@ -99,7 +99,7 @@ public abstract class BundlerBase : IBundler, ITransientDependency
var fileName = var fileName =
definition.Source.Substring(slashIndex + 1, definition.Source.Length - slashIndex - 1); definition.Source.Substring(slashIndex + 1, definition.Source.Length - slashIndex - 1);
var filePath = var filePath =
Path.Combine(PathHelper.GetFrameworkFolderPath(options.Directory, options.FrameworkVersion), Path.Combine(PathHelper.GetWebAssemblyFrameworkFolderPath(options.Directory, options.FrameworkVersion),
fileName); fileName);
content = GetFileContent(filePath, false); content = GetFileContent(filePath, false);
} }
@ -119,6 +119,29 @@ public abstract class BundlerBase : IBundler, ITransientDependency
} }
} }
private string BundleMauiBlazorFiles(BundleOptions options, List<BundleDefinition> bundleDefinitions)
{
var builder = new StringBuilder();
foreach (var definition in bundleDefinitions)
{
var filePath = Path.Combine(definition.Source.Split('/'));
var fileFullPath = Directory.GetFiles(options.Directory, string.Empty, SearchOption.AllDirectories).FirstOrDefault(x => x.EndsWith(filePath));
if(fileFullPath == null)
{
throw new AbpException("Not found: " + definition.Source);
}
var content = GetFileContent(fileFullPath, options.Minify);
content = ProcessBeforeAddingToTheBundle(definition.Source, Path.Combine(options.Directory, "wwwroot"),
content);
builder.AppendLine(content);
}
return builder.ToString();
}
private string GetFileContent(string filePath, bool minify) private string GetFileContent(string filePath, bool minify)
{ {
var content = File.ReadAllText(filePath); var content = File.ReadAllText(filePath);

3
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingConsts.cs

@ -7,4 +7,7 @@ internal static class BundlingConsts
internal const string ScriptPlaceholderStart = "<!--ABP:Scripts-->"; internal const string ScriptPlaceholderStart = "<!--ABP:Scripts-->";
internal const string ScriptPlaceholderEnd = "<!--/ABP:Scripts-->"; internal const string ScriptPlaceholderEnd = "<!--/ABP:Scripts-->";
internal const string SupportedWebAssemblyProjectType = "Microsoft.NET.Sdk.BlazorWebAssembly"; internal const string SupportedWebAssemblyProjectType = "Microsoft.NET.Sdk.BlazorWebAssembly";
internal const string SupportedMauiBlazorProjectType = "Microsoft.NET.Sdk.Razor";
internal const string WebAssembly = "webassembly";
internal const string MauiBlazor = "maui-blazor";
} }

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

@ -29,7 +29,7 @@ public class BundlingService : IBundlingService, ITransientDependency
public IStyleBundler StyleBundler { get; set; } public IStyleBundler StyleBundler { get; set; }
public IConfigReader ConfigReader { get; set; } public IConfigReader ConfigReader { get; set; }
public async Task BundleAsync(string directory, bool forceBuild) public async Task BundleAsync(string directory, bool forceBuild, string projectType = BundlingConsts.WebAssembly)
{ {
var projectFiles = Directory.GetFiles(directory, "*.csproj"); var projectFiles = Directory.GetFiles(directory, "*.csproj");
if (!projectFiles.Any()) if (!projectFiles.Any())
@ -40,9 +40,9 @@ public class BundlingService : IBundlingService, ITransientDependency
var projectFilePath = projectFiles[0]; var projectFilePath = projectFiles[0];
CheckProjectIsSupportedType(projectFilePath); CheckProjectIsSupportedType(projectFilePath, projectType);
var config = ConfigReader.Read(PathHelper.GetWwwRootPath(directory)); var config = projectType == BundlingConsts.WebAssembly? ConfigReader.Read(PathHelper.GetWwwRootPath(directory)): ConfigReader.Read(directory);
var bundleConfig = config.Bundle; var bundleConfig = config.Bundle;
if (forceBuild) if (forceBuild)
@ -55,9 +55,9 @@ public class BundlingService : IBundlingService, ITransientDependency
DotNetProjectBuilder.BuildProjects(projects, string.Empty); DotNetProjectBuilder.BuildProjects(projects, string.Empty);
} }
var frameworkVersion = GetTargetFrameworkVersion(projectFilePath); var frameworkVersion = GetTargetFrameworkVersion(projectFilePath, projectType);
var projectName = Path.GetFileNameWithoutExtension(projectFilePath); var projectName = Path.GetFileNameWithoutExtension(projectFilePath);
var assemblyFilePath = PathHelper.GetAssemblyFilePath(directory, frameworkVersion, projectName); var assemblyFilePath = projectType == BundlingConsts.WebAssembly? PathHelper.GetWebAssemblyFilePath(directory, frameworkVersion, projectName) : PathHelper.GetMauiBlazorAssemblyFilePath(directory, projectName);
var startupModule = GetStartupModule(assemblyFilePath); var startupModule = GetStartupModule(assemblyFilePath);
var bundleDefinitions = new List<BundleTypeDefinition>(); var bundleDefinitions = new List<BundleTypeDefinition>();
@ -65,7 +65,7 @@ public class BundlingService : IBundlingService, ITransientDependency
bundleDefinitions = bundleDefinitions.OrderByDescending(t => t.Level).ToList(); bundleDefinitions = bundleDefinitions.OrderByDescending(t => t.Level).ToList();
var styleContext = GetStyleContext(bundleDefinitions, bundleConfig.Parameters); var styleContext = GetStyleContext(bundleDefinitions, bundleConfig.Parameters);
var scriptContext = GetScriptContext(bundleDefinitions, bundleConfig.Parameters); var scriptContext = GetScriptContext(bundleDefinitions, bundleConfig.Parameters, projectType);
string styleDefinitions; string styleDefinitions;
string scriptDefinitions; string scriptDefinitions;
@ -77,7 +77,8 @@ public class BundlingService : IBundlingService, ITransientDependency
FrameworkVersion = frameworkVersion, FrameworkVersion = frameworkVersion,
ProjectFileName = projectName, ProjectFileName = projectName,
BundleName = bundleConfig.Name.IsNullOrEmpty() ? "global" : bundleConfig.Name, BundleName = bundleConfig.Name.IsNullOrEmpty() ? "global" : bundleConfig.Name,
Minify = bundleConfig.Mode == BundlingMode.BundleAndMinify Minify = bundleConfig.Mode == BundlingMode.BundleAndMinify,
ProjectType = projectType
}; };
Logger.LogInformation("Generating style bundle..."); Logger.LogInformation("Generating style bundle...");
@ -101,17 +102,20 @@ public class BundlingService : IBundlingService, ITransientDependency
} }
private BundleContext GetScriptContext(List<BundleTypeDefinition> bundleDefinitions, private BundleContext GetScriptContext(List<BundleTypeDefinition> bundleDefinitions,
BundleParameterDictionary parameters) BundleParameterDictionary parameters, string projectType)
{ {
var scriptContext = new BundleContext var scriptContext = new BundleContext
{ {
Parameters = parameters Parameters = parameters
}; };
scriptContext.BundleDefinitions.AddIfNotContains( if (projectType == BundlingConsts.WebAssembly)
x => x.Source == "_framework/blazor.webassembly.js", {
() => new BundleDefinition { Source = "_framework/blazor.webassembly.js" }); scriptContext.BundleDefinitions.AddIfNotContains(
x => x.Source == "_framework/blazor.webassembly.js",
() => new BundleDefinition { Source = "_framework/blazor.webassembly.js" });
}
foreach (var bundleDefinition in bundleDefinitions) foreach (var bundleDefinition in bundleDefinitions)
{ {
var contributor = CreateContributorInstance(bundleDefinition.BundleContributorType); var contributor = CreateContributorInstance(bundleDefinition.BundleContributorType);
@ -283,24 +287,41 @@ public class BundlingService : IBundlingService, ITransientDependency
.SingleOrDefault(AbpModule.IsAbpModule); .SingleOrDefault(AbpModule.IsAbpModule);
} }
private string GetTargetFrameworkVersion(string projectFilePath) private string GetTargetFrameworkVersion(string projectFilePath, string projectType)
{ {
var document = new XmlDocument(); var document = new XmlDocument();
document.Load(projectFilePath); document.Load(projectFilePath);
return document.SelectSingleNode("//TargetFramework").InnerText; return projectType switch {
BundlingConsts.WebAssembly => document.SelectSingleNode("//TargetFramework").InnerText,
BundlingConsts.MauiBlazor => document.SelectNodes("//TargetFrameworks")[0].InnerText,
_ => null
};
} }
private void CheckProjectIsSupportedType(string projectFilePath) private void CheckProjectIsSupportedType(string projectFilePath, string projectType)
{ {
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 != BundlingConsts.SupportedWebAssemblyProjectType)
switch (projectType)
{ {
throw new BundlingException( case BundlingConsts.WebAssembly:
$"Unsupported project type. Project type must be {BundlingConsts.SupportedWebAssemblyProjectType}."); if (sdk != BundlingConsts.SupportedWebAssemblyProjectType)
{
throw new BundlingException(
$"Unsupported project type. Project type must be {BundlingConsts.SupportedWebAssemblyProjectType}.");
}
break;
case BundlingConsts.MauiBlazor:
if (sdk != BundlingConsts.SupportedMauiBlazorProjectType)
{
throw new BundlingException(
$"Unsupported project type. Project type must be {BundlingConsts.SupportedMauiBlazorProjectType}.");
}
break;
} }
} }
} }

2
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/IBundlingService.cs

@ -4,5 +4,5 @@ namespace Volo.Abp.Cli.Bundling;
public interface IBundlingService public interface IBundlingService
{ {
Task BundleAsync(string directory, bool forceBuild); Task BundleAsync(string directory, bool forceBuild, string projectType = BundlingConsts.WebAssembly);
} }

12
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/PathHelper.cs

@ -1,20 +1,26 @@
using System.IO; using System.IO;
using System.Linq;
namespace Volo.Abp.Cli.Bundling; namespace Volo.Abp.Cli.Bundling;
internal static class PathHelper internal static class PathHelper
{ {
internal static string GetFrameworkFolderPath(string projectDirectory, string frameworkVersion) internal static string GetWebAssemblyFrameworkFolderPath(string projectDirectory, string frameworkVersion)
{ {
return Path.Combine(projectDirectory, "bin", "Debug", frameworkVersion, "wwwroot", "_framework"); ; return Path.Combine(projectDirectory, "bin", "Debug", frameworkVersion, "wwwroot", "_framework"); ;
} }
internal static string GetAssemblyFilePath(string directory, string frameworkVersion, string projectFileName) internal static string GetWebAssemblyFilePath(string directory, string frameworkVersion, string projectFileName)
{ {
var outputDirectory = GetFrameworkFolderPath(directory, frameworkVersion); var outputDirectory = GetWebAssemblyFrameworkFolderPath(directory, frameworkVersion);
return Path.Combine(outputDirectory, projectFileName + ".dll"); return Path.Combine(outputDirectory, projectFileName + ".dll");
} }
internal static string GetMauiBlazorAssemblyFilePath(string directory, string projectFileName)
{
return Directory.GetFiles(directory, "*.dll", SearchOption.AllDirectories).First(f => !f.Contains("android") && f.EndsWith(projectFileName + ".dll"));
}
internal static string GetWwwRootPath(string directory) internal static string GetWwwRootPath(string directory)
{ {
return Path.Combine(directory, "wwwroot"); return Path.Combine(directory, "wwwroot");

25
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/BundleCommand.cs

@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Bundling; using Volo.Abp.Cli.Bundling;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands; namespace Volo.Abp.Cli.Commands;
@ -29,7 +30,8 @@ public class BundleCommand : IConsoleCommand, ITransientDependency
var forceBuild = commandLineArgs.Options.ContainsKey(Options.ForceBuild.Short) || var forceBuild = commandLineArgs.Options.ContainsKey(Options.ForceBuild.Short) ||
commandLineArgs.Options.ContainsKey(Options.ForceBuild.Long); commandLineArgs.Options.ContainsKey(Options.ForceBuild.Long);
var projectType = GetProjectType(commandLineArgs);
if (!Directory.Exists(workingDirectory)) if (!Directory.Exists(workingDirectory))
{ {
@ -42,7 +44,7 @@ public class BundleCommand : IConsoleCommand, ITransientDependency
try try
{ {
await BundlingService.BundleAsync(workingDirectory, forceBuild); await BundlingService.BundleAsync(workingDirectory, forceBuild, projectType);
} }
catch (BundlingException ex) catch (BundlingException ex)
{ {
@ -68,11 +70,24 @@ public class BundleCommand : IConsoleCommand, ITransientDependency
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("-wd|--working-directory <directory-path> (default: empty)"); sb.AppendLine("-wd|--working-directory <directory-path> (default: empty)");
sb.AppendLine("-f | --force (default: false)"); sb.AppendLine("-f | --force (default: false)");
sb.AppendLine("-t | --project-type (default: webassembly)");
sb.AppendLine(""); sb.AppendLine("");
sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI"); sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI");
return sb.ToString(); return sb.ToString();
} }
private string GetProjectType(CommandLineArgs commandLineArgs)
{
var projectType = commandLineArgs.Options.GetOrNull(Options.ProjectType.Short, Options.ProjectType.Long);
projectType ??= BundlingConsts.WebAssembly;
return projectType.ToLower() switch {
"webassembly" => BundlingConsts.WebAssembly,
"maui-blazor" => BundlingConsts.MauiBlazor,
_ => throw new CliUsageException(ExceptionMessageHelper.GetInvalidOptionExceptionMessage("Project Type"))
};
}
public static class Options public static class Options
{ {
@ -82,6 +97,12 @@ public class BundleCommand : IConsoleCommand, ITransientDependency
public const string Long = "working-directory"; public const string Long = "working-directory";
} }
public static class ProjectType
{
public const string Short = "t";
public const string Long = "project-type";
}
public static class ForceBuild public static class ForceBuild
{ {
public const string Short = "f"; public const string Short = "f";

Loading…
Cancel
Save