Garfield.SpaServices.Extensions.Vue 2.0.0

dotnet add package Garfield.SpaServices.Extensions.Vue --version 2.0.0
NuGet\Install-Package Garfield.SpaServices.Extensions.Vue -Version 2.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Garfield.SpaServices.Extensions.Vue" Version="2.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Garfield.SpaServices.Extensions.Vue --version 2.0.0
#r "nuget: Garfield.SpaServices.Extensions.Vue, 2.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Garfield.SpaServices.Extensions.Vue as a Cake Addin
#addin nuget:?package=Garfield.SpaServices.Extensions.Vue&version=2.0.0

// Install Garfield.SpaServices.Extensions.Vue as a Cake Tool
#tool nuget:?package=Garfield.SpaServices.Extensions.Vue&version=2.0.0

0. 源码地址

https://gitee.com/RandyField/spa-services.-extensions.-vue

1. 安装nuget包

Install-Package Garfield.SpaServices.Extensions.Vue -Version 2.0.0
#请使用最新版2.0.0

这是博主根据官方库改写,正如nuget包的文档写点那样:由于官方没有支持Vue,看后续是否支持,如支持,此包将归档废弃。

2. 创建Vue项目

在API项目创建ClientApp文件,在此文件夹下创建或复制Vue项目。

保证以下目录结构即可:

ClientApp/package.json

3 修改package.json

适配后端这边,package.json要做一些调整,主要是端口由后端启动时随机指定可用的。

"scripts": {
    "start": "vue-cli-service serve --port", //edit here
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e"
},

4 修改Startup.cs

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //omit some code..
    app.UseStaticFiles();
    
    //PRODUCTION uses webpack static files
    if (!env.IsDevelopment())
    {
        app.UseSpaStaticFiles();
    }
    app.UseSpa(spa =>
               {
                   spa.Options.SourcePath = "ClientApp";

                   if (env.IsDevelopment())
                   {
                       spa.UseVueCliServer(npmScript: "start");
                       //spa.UseProxyToSpaDevelopmentServer("http://localhost:8080");
                   }
               });
}

5.还原构建-Build

在我们调试之前,一定是构建项目,但是我们的项目现在是一个包含前端Vue后端Webapi的前后端分离项目。后端需要还原各种nuget包,在那之前,前端也需要还原npm包,以前博主是执行npm install

这里介绍下使用MSBuild自动执行,修改csproj,增加Target:

<PropertyGroup>
    
    <SpaRoot>ClientApp\</SpaRoot>
</PropertyGroup>
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
    
    <Exec Command="node --version" ContinueOnError="true">
        <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
    </Exec>
    <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
    <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>

此时就会在Build ASP.NET WebAPI项目前,自动还原前端项目,执行npm install

6.调试-Debug

从效果上来看,两种集成方式貌似没啥大的差别,但是从开发的调试的角度,有各自运用的场景。

6.1 集成调试

保持上面的配置与代码不变,直接运行ASP.NET Web API

Vue将会自动构建,并与ASP.NET Core WebAPI项目将会集成运行,通过访问localhost:port便可以调试访问应用。

6.2 独立调试

如果后端接口稳定,仅仅是前端问题,那么上面的集成调试时比较方便的。想象一下,每次都要重新启动,执行npm start,还是有点费时间。特别是前端已经足够稳定,后端接口修改频繁,那么这样的方式无疑是太慢了,因为每次都需要重新启动vue项目,失去了集成的优势。所以独立调试后端更符合此类场景。

6.2.1 启动前端

cd ClientApp
npm start 8080

6.2.2 修改后端

// spa.UseVueCliServer(npmScript: "start"); //替换如下代码
spa.UseProxyToSpaDevelopmentServer("http://localhost:8080");

当启动 ASP.NET Core 应用时,它不会启动 Vue dev 服务器, 而是使用手动启动的实例。 这使它能够更快地启动和重新启动。 不再需要每次都等待 Vue CLI 重新生成客户端应用。

7.发布-Publish

小项目,我们就不需要nginx去放静态文件,修改配置等等。

以往博主部署这种前后端分离项目,是通过nginx部署静态前端文件,反向代理后端接口。这种方式没问题。但是这里介绍一点新鲜的(至少对博主而言),前端Vue项目通过npm run build构建成一系列的静态文件。这些静态文件就是我们的SPA。说白了,就是一个静态网页。

所以需要静态文件中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //omit some code..
    app.UseStaticFiles();
    if (!env.IsDevelopment())
    {
        app.UseSpaStaticFiles();
    }
}

然后指定我们静态文件的路径

//Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    //omit some code..
    services.AddSpaStaticFiles(c=>
                               {
                                   c.RootPath = "ClientApp/dist";
                               });
}

这里我们把Vue项目包含在webapi项目中,文件夹ClientApp,他构建的文件夹为dist,当然这个也是可以修改的。

alternate text is missing from this package README image

最重要一步来了,发布时让构建好的静态文件随着WebAPI一起发布,而不需要,单独执行npm run build然后手动拷贝,这里还是用到了MSbuild,所以同样需要修改csproj文件,增加publishTarget

<PropertyGroup>
    
    <SpaRoot>ClientApp\</SpaRoot>
</PropertyGroup>  
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    
    
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
    
    <ItemGroup>
        <DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
        <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
            <RelativePath>%(DistFiles.Identity)</RelativePath>
            <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
            <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
        </ResolvedFileToPublish>
    </ItemGroup>
</Target>

大概指令:发布时运行webpack

  • 如果需要的话执行npm install还原(我注释了)
  • 执行npm run build进行构建
  • 拷贝构建好的dist文件夹内容到发布文件夹中

这时再通过Visual Studio后者命令发布时,就会同步构建前端项目,发布后端API且包含前端构建后的dist文件。便可以不用分开部署,从而融合为同一个程序。

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.0 2,371 1/12/2021