65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ASP.Net Core 1.1 + Angular 4.0 的 SPA^2 - 第 9 部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2017 年 4 月 19 日

CPOL

22分钟阅读

viewsIcon

27179

downloadIcon

340

将 ASP.Net Core 1.1 / Angular 4 SPA 发布到 Azure 和外部 IIS 主机。还涵盖了代码清理、优化、捆绑和压缩。Gulp、Grunt、Webpack 以及一些架构和开发理念。

如果上述源代码不可用,您也可以从 GitHub 此处获取最新源代码

引言

本系列文章旨在利用 ASP.Net Core 和 Angular 4 创建一个单页应用程序 (SPA),但并非忽略标签助手、Razor 或 ASP.Net Core 的其他出色特性,而是积极地在客户端与 Angular 4 结合使用这些特性。

第 1 部分第 2 部分第 3 部分涵盖了基本的项目设置,第 4 部分介绍了使用 OpenIdDict 进行令牌认证,在第 5 部分中我们添加了更智能的验证,然后在第 6 部分中使用了 NSwag 创建 Swagger 文档并自动生成代码。最后两部分第 7 部分第 8 部分分别涵盖了使用 VS 2015 和 VS 2017 进行本地发布。

最后,在本系列的最后一部分,我将介绍设计背后的一些原理和决策,我们将进行一些优化,了解如何进行捆绑和压缩,以及如何添加 LESS 或 SASS 样式表,最后是如何发布到外部 Web 主机和 Azure。

优化构建 - 为什么?它是什么?如何做?

为什么要优化构建?这意味着什么?

我假设这里的优化定义为:尽可能地调整 (1) 我们的开发周期(编辑、测试、部署)、(2) 部署(发布时间 + 发布文件大小)和 (3) 用户体验(页面加载时间、页面大小)。最后一部分很重要,“尽可能地”,因为过多的优化会浪费开发时间(付出太多努力却收效甚微),另一方面,优化不足可能会因为用户对您的网站不满意,或者因为网站发布时间过长而导致开发速度变慢,从而浪费您的开发时间。

幸运的是,针对这三个问题中的一个进行修复,通常也会有助于其他两个问题。

部署缓慢和页面加载缓慢的最大原因之一可能是构成我们应用程序的文件数量庞大且体积巨大。

你需要它吗?首先要解决的问题是尝试删除我们不需要的文件。这可能看起来有点基础,但我发现人们很容易添加一个库以备不时之需,结果后来发现根本没有用到。如果您在团队中工作,请养成习惯,在考虑添加新库时与团队成员讨论。查看替代库(您可以使用一个库完成两项工作吗?)或者您可以找到一个更小的库,或者您根本不需要它吗?

你能把它做得更小吗?接下来要看的是捆绑和压缩。捆绑是将许多较小的文件组合成一个文件,因为给定浏览器和您的服务器之间的请求和连接数量有限,如果您能最大限度地减少这些请求的数量,即使三个文件 1k+1k+1K = 3k 的总和没有改变,但分别请求这三个文件与请求一个组合文件所需的每个请求的开销,通常意味着网站对用户来说会显得加载更快。组合文件的另一个好处是存储空间会小一点(一个 1k 文件在您的文件系统中可能需要 4k 或 8k 的存储空间),单个捆绑文件也能节省一些空间。

使文件更小的另一个方面是使用“压缩”。这是一个应用于各种减少给定文件大小的技术的术语。通常,有大量的空白(空格、回车符、制表符)以及较长的人类可读函数名和变量名可以减少。通过使用单个字符而不是较长的单词作为变量名并删除这些空白,我们可以使文件小得多。压缩(和捆绑)可以应用于 .js JavaScript 和 .css 样式表文件。

按照惯例,压缩后的文件会被重命名为带有 .min 后缀。例如,`site.css` 会变成 `site.min.css`,或者 `systemjs.config.js` 会变成 `systemjs.config.min.js`,并且通常与未压缩的文件放在一起。在捆绑的情况下,许多压缩后的文件可以组合成一个文件,在这种情况下,捆绑文件的目标通常是通用的脚本或样式表文件夹。

通常在开发过程中,原始文件用于调试构建,而压缩版本用于发布构建或发布到生产环境。

ASP.Net Core 中已经有一个机制来处理不同的文件名并在需要时提供适当的版本。您将在 `_layout.cshtml` 中看到一个示例。

    <environment names="Development">
              ...
    </environment>
    <environment names="Staging,Production">
              ...
    </environment>

注意:这只是创建 SPA 这种技术的另一个好处,它“实际利用”了 ASP.Net Core 而不仅仅是一个文件服务器,因为在我们的 SPA 中使用纯 .html 文件无法让我们使用内置的环境标签助手,如上所示。

早期 ASP.Net MVC 4.x 框架的用户应该已经习惯了一个 Bundles.cs 类,它负责捆绑和压缩。在 ASP.Net Core 中,您需要有其他机制来完成此任务。有多种替代方案,包括 Gulp、Grunt 和 WebPack,或者一个简单有效的替代方案,微软一位出色的开发人员 Mads Kristensen 创建了一个“BundlerMinifier”,它作为 Visual Studio 的插件提供。Mads 的“BundlerMinifier”可以原地压缩和捆绑,使用起来非常简单,因为它几乎是自动化的。它的优点是允许您在需要时轻松过渡到 Gulp,同时仍保持尽可能简单。

使用 Mads Kristensen 的 “BundlerMinifier”

Mads Kristensen 的 “Bundler Minifier” 插件适用于 VS 2015 和 VS 2017。如果您尚未安装,请转到工具菜单,然后选择扩展和更新。

选择“Bundler & Minifier”,如下图所示,然后单击下载。您可能需要重新启动 Visual Studio 才能启用它,但关于扩展程序,这里快速说一句:在添加 Mads Kristensen 的 BundlerMinifier 的同时,一定要添加 Web Essentials。它是 Visual Studio 一系列非常有用的工具的绝佳集合。

一旦您开始安装 Web Essentials,它将自动加载组件,如下所示

不用太担心 CPU 使用率,这些插件写得非常好;即使在配置一般的电脑上,我也发现效果非常好。

一旦您的 Bundler & Minifier 插件安装完毕,右键单击您想要压缩的 CSS 文件或 JavaScript 文件。

点击“压缩文件”,然后该文件将添加到 bundleconfig.json 中,如下图所示

[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/site.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "wwwroot/js/site.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    }
  },
  {
    "outputFileName": "wwwroot/systemjs.config.min.js",
    "inputFiles": [
      "wwwroot/systemjs.config.js"
    ]
  }
]

在 Windows 资源管理器中快速查看,我们可能节省了大约 800 字节,从 1976 字节减少到 1175 字节。

 

要使此压缩文件生效(而不仅仅是闲置),您现在需要编辑 _layout.chtml 以更改以下内容(显示缩写版本),从以下内容开始

    <environment names="Development">
              ...
        <script src="~/systemjs.config.js"></script>
              ...
    </environment>
    <environment names="Staging,Production">
              ...
        <script src="~/systemjs.config.js"></script>
              ...
    </environment>

变为这样:

    <environment names="Development">
              ...
        <script src="~/systemjs.config.js"></script>
              ...
    </environment>
    <environment names="Staging,Production">
              ...
        <script src="~/systemjs.config.min.js"></script>
              ...
    </environment>

有时,当一个文件依赖于另一个文件而该依赖被遗漏或被认为不需要时,压缩可能会破坏文件。因此,一次不要压缩太多文件是明智的,最好一次压缩一两个文件,看看一切是否仍然正常工作。您可以将压缩版本放入您的开发部分,尝试一下,如果它工作正常,则将 .min 添加到暂存/生产部分,并让开发部分仍运行原始版本。

所以,接下来快速浏览一下 `_Layout.cshtml`,看看是否有其他文件我们也可以压缩,然后我们会将其中一些文件添加到捆绑包中以演示这个概念。首先在 head 部分,有一个未压缩的 toastr.css

    <environment names="Staging,Production">
         ...
        <link rel="stylesheet" href="~/node_modules/ngx-toastr/toastr.css" />
    </environment>

这来自 `/node_modules` 文件夹中的 NPM 模块。检查该软件包是否随压缩版本一起分发(没有),因此我们现在将此文件添加到待压缩文件中。

关于 `/node_modules` 文件夹的快速说明

顺便说一下,默认情况下,VS 2017 会显示 /node_modules 文件夹及其内容,因为它们存在于解决方案空间中,但默认情况下它们不会提交到 GIT 仓库,因为我们的标准 .git ignore 文件恰好有一个条目可以排除 /node_modules 文件夹的内容。

如果您从项目中排除 /node_modules 文件夹(右键单击并排除),您将使发布变得困难,因为它会隐藏该文件夹不进行发布。在某些框架或应用程序中,这可能是可取的,例如,如果您努力将 (许多) 所需文件从 /node_modules 文件夹复制到 /wwwroot 文件夹。但我们不打算这样做,对于中小型 SPA 应用程序,恕我直言,这需要太多的努力和维护。(注意:如果您需要这样做,webpack 或 gulp 可以完成这项工作,但稍后会详细介绍它们,因为它们也需要工作)。

我们回到压缩 `toastr.css` 文件。

在 Visual Studio 的解决方案资源管理器窗口中打开 `/node_modules` 文件夹。找到 `ngx-toast` 文件夹,然后依次找到 `toastr.css` 文件。

右键单击文件,点击“Bundler & Minifier”,然后点击“Minify File”,现在我们的 `bundleconfig.json` 文件将变为

[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/site.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "wwwroot/js/site.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    }
  },
  {
    "outputFileName": "wwwroot/systemjs.config.min.js",
    "inputFiles": [
      "wwwroot/systemjs.config.js"
    ]
  },
  {
    "outputFileName": "node_modules/ngx-toastr/toastr.min.css",
    "inputFiles": [
      "node_modules/ngx-toastr/toastr.css"
    ]
  }
]

请注意,默认选项是压缩给定文件并将其放在原始文件旁边。这通常是一个不错的选择,但是假设我们希望选择将其与其他样式放在一起,这样我们就可以在一个地方查看文件,并稍后进行捆绑。

将此部分从

  {
    "outputFileName": "node_modules/ngx-toastr/toastr.min.css",
    "inputFiles": [
      "node_modules/ngx-toastr/toastr.css"
    ]
  }

改为

  {
    "outputFileName": "wwwroot/css/      toastr.min.css",
    "inputFiles": [
      "node_modules/ngx-toastr/toastr.css"
    ]
  }

保存 `bundlerconfig.json` 更改后不久,`/app/css` 样式表文件夹

 

获得新成员

不难想象,您可以通过几种方式进行捆绑,

一种,我认为最简单的方法是这样

  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/site.css",
      "node_modules/ngx-toastr/toastr.css"
    ]
  },

甚至不用单独压缩 toastr.css 文件。因此,删除创建 `toastr.min.css` 的最后一部分,保留此部分

[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/site.css",
      "node_modules/ngx-toastr/toastr.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "wwwroot/js/site.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    }
  },
  {
    "outputFileName": "wwwroot/systemjs.config.min.js",
    "inputFiles": [
      "wwwroot/systemjs.config.js"
    ]
  }
]

我们最初的 `_layout.cshtml` 也包含 `bootstrap.css` 文件用于开发,但对于暂存和生产环境,则使用带有回退的 CDN(或内容分发网络)。

    <environment names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
        <link rel="stylesheet" href="~/node_modules/ngx-toastr/toastr.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>

为了演示,我们也将 bootstrap 样式表添加进来。编辑 `bundleconfig.json`(仅显示顶部部分)以添加 `bootstrap.css`

  {

    "outputFileName": "wwwroot/css/site.min.css",

    "inputFiles": [

      "wwwroot/css/site.css",

      "wwwroot//lib/bootstrap/dist/css/bootstrap.css",

      "node_modules/ngx-toastr/toastr.css"

    ]

  },

然后更新 `_layout.cshtml` 为

    <environment names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
        <link rel="stylesheet" href="~/node_modules/ngx-toastr/toastr.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>

这三个文件:bootstrap.css (150k)、`style.css` (2k) 和 `toastr.css` (7k),经过压缩和捆绑后,变成了一个 125k 的文件。

为了节省篇幅,我将逐步压缩和捆绑过程作为练习留给您,但是这是我的版本,针对我的通勤(最少的 CDN 使用)和我在本地托管文件进行了优化。例如,您可以轻松添加 `system.config.js` 等文件。

这是更新后的 `bundleconfig.json` 文件

[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/site.css",
      "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
      "node_modules/ngx-toastr/toastr.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "wwwroot/lib/jquery/dist/jquery.js",
      "wwwroot/bootstrap/dist/js/bootstrap.js",
      "wwwroot/js/site.js",
      "node_modules/core-js/client/shim.min.js",
      "node_modules/zone.js/dist/zone.js",
      "node_modules/systemjs/dist/system.src.js",
      "wwwroot/systemjs.config.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    }
  }
]

这是压缩后 `_layout.cshtml` 的 body 部分中更新的脚本

    <environment names="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
        <!-- Polyfill(s) for older browsers -->
        <script src="~/node_modules/core-js/client/shim.min.js"></script>
        <script src="~/node_modules/zone.js/dist/zone.js"></script>
        <script src="~/node_modules/systemjs/dist/system.src.js"></script>
        <script src="~/systemjs.config.js"></script>
        <script>
            System.import('app').catch(function (err) { console.error(err); });
        </script>
    </environment>
    <environment names="Staging,Production">
        <script src="~/js/site.min.js" asp-append-version="true"></script>
        <script>
            System.import('app').catch(function (err) { console.error(err); });
        </script>
    </environment>

仍在运行

Gulp 或 Grunt 怎么样?

Gulp 和 Grunt 可以执行多种角色,包括压缩和捆绑,如前所述,它们可以帮助您使用 LESS 或 SASS 源创建 CSS 样式表,并且还可以帮助您完成简单的文件复制任务。

那么,选哪一个呢?有很多讨论,但 https://www.keycdn.com/blog/gulp-vs-grunt/ 对两者进行了比较,Gulp 在简单性、多功能性、易用性和速度方面似乎更胜一筹。

就我个人而言,我认为如果你能暂时不使用 Gulp 或 Grunt,而是坚持使用像 Mads 的“BundlerMinifier”这样低影响的工具,那么你作为开发人员的生活会更轻松。

这并不是说你不应该考虑任何改变。假设你需要移动文件,那么你可以很容易地从 Mads 的“BundlerMinifier”转到使用 Gulp,只需右键点击 `bundleconfig.json`,选择“Convert to Gulp”。

然后您就可以利用许多 Gulp“插件”来完成您需要的额外任务。

此外,通过从 Mads 的“BundlerMinifier”开始,然后以这种方式转向 Gulp,您可以继续构建 `bundleconfig.json` 文件,并且仍然可以使用右键单击来创建压缩文件,这至少最大限度地减少了配置文件的维护工作。

在转向 Gulp、Grunt(或 Webpack)之前,另一个需要考虑的方面是这些工具可能增加您的开发构建周期时间。本地构建和调试可能不会受到太大影响,因为您通常会在本地使用原始的未压缩版本,但当进行发布构建时,您可能会发现部署时间和 CI 构建时间会增加。

总而言之,请考虑您的开发周期/构建时间、配置文件维护的负担以及用户体验,并确保您不是在“剃牦牛”(yak shaving),或者为微不足道的整体收益而经历太多痛苦。

那 Webpack 呢?

Webpack 包含多项功能,它既是启动 Angular 4 的另一种方式(SystemJs 的替代方案),也是一个任务运行器,可以捆绑和压缩文件,或执行其他任务。

它的工作方式与 Gulp 类似,即各种任务可以通过插件执行,而且与 Gulp 和 Grunt 一样,Webpack 在社区中也拥有相当多的追随者。其优点之一在于它如何跟踪代码中的链接,以找出所需的脚本、模板和样式,然后设置与代码中各种入口点协同工作的捆绑包。这使得大型网站加载速度明显加快,因为用户只接收所需的文件,而不是一次性接收所有文件。

缺点是除了简单场景之外,设置起来都很复杂。您将需要时间来弄清楚如何配置 Webpack,但最终如果您有一个中型到大型的网站,这些好处是值得的。对于小型网站,您可能需要权衡其好处与整合所需的工作量。

由于这种陡峭的学习曲线以及对于小型网站而言不确定的好处,加上我制作本系列的时间限制,我决定这超出了本系列文章的范围,但是尽管在本框架中未经测试,但经过一些努力,它应该能正常工作。

自动化 SQL 迁移

在前面的部分中,部署是通过开发模式开关进行的,打开(或禁用)该开关以启用 startup.cs 中的代码块并执行迁移。

经过各种实验,我不能说这对每个人来说都是最好的,但我发现对我而言,自动化代码迁移效果最好。只要您在代码中设置了保护措施,仅在不存在种子数据(初始数据)时才创建,您就可以对实体框架迁移的其他部分非常有信心,即仅在需要时(数据库不存在时)才创建您的数据库。

要更新项目以使迁移更简单和自动化,需要进行以下更改。

在 `startup.cs` 的底部,删除或注释掉条件语句,如下所示:

            // if you want to use automated deployments, keep the following line remarked out
            // if (CurrentEnvironment.IsDevelopment())
            {
                DbInitializer.Initialize(context);
            }

接下来在包管理器控制台中,输入

add-migration InitialMigration

这将创建您的代码优先迁移类。接下来更新 `\Data` 文件夹中现有的 `DbInitializer` 类,将这一行从

            context.Database.EnsureCreated();

改为这样

            context.Database.Migrate();

然后在顶部添加额外的 using 语句。

using Microsoft.EntityFrameworkCore;

现在,必要时将进行迁移。

同样,如果添加种子数据,请确保您有一个保护子句,如下所示:

            // Look for any test data.
            if (context.TestData.Any())
            {
                return;   // DB has been seeded
            }

迁移已完成。但欲了解更多信息,请参阅 ASP.Net Core 网站上的现有文档 此处

使用 Web Deploy 发布到 IIS Web 主机

本系列的第 7 部分第 8 部分介绍了如何发布到本地 IIS 实例,或具有共享文件文件夹的实例,您可以将发布的文件放入其中。

在另一种常见情况中,您无法直接访问生产 Web 服务器,访问权限由“运维”或支持人员提供,您可能需要提供一份生产代码副本进行部署。在这种情况下,您在第 7 部分第 8 部分发布到本地文件夹的相同文件也可以打包成 ZIP 文件,并作为您新的待发布网站提供给您的“运维”人员,因为这些文件代表了完整的网站。

在自主权或信任度更高,可以直接部署到测试或生产环境的开发人员,可以使用一种不同的发布新网站的方法,称为 Web Deploy。这在 ASP.Net Core 文档网站中有非常深入的介绍,因此我在此只介绍重点。

首先,像以前一样在 IIS 中创建您的网站。在我的例子中,我发布到 LAN 上的服务器,并从网络内部查看它。我使用端口转发,尽管我可以使用 DMZ,让同一台服务器也可以在外部通过我使用 NOIP 动态 DNS 服务注册的域名可见,因为此互联网连接不是静态 IP 地址。如果您发布到托管在其他地方的服务器,您需要确保打开了正确的端口(更多详细信息请参阅上面的 ASP.Net Core 文档)。

 

您需要确保拥有发布到 IIS 的权限,请参见上面的“IIS 管理器权限”图标。这在微软文档中也有详细介绍。

确保您的新网站在设置为“无托管代码”的应用程序池上运行(这在第 7 部分第 8 部分中有更详细的说明)。

回到 Visual Studio,右键单击您的项目,单击“发布”,或者单击“生成”菜单,然后单击“发布”。选择“IIS、FTP 等”。

接下来,您将被要求选择一种发布方法,这次我们将使用 Web Deploy。剩下的框一开始可能会有点令人困惑,所以请注意水印提示。

第一个标有“服务器:”的框应填写服务器的域名。因此,如果您的服务器是 `http://www.example.com`,那么您应该输入 `www.example.com` —— 换句话说,省略地址中的 `http://` 或 `https://` 部分。网站名称将是您要将文件发布到网站中的位置。您需要参考您的 IIS 实例来确定这一点。在我上面的示例中,您会看到我在“默认网站”中创建了一个名为“a2spa”的虚拟目录,因此在此示例中,“网站名称:”应包含“Default Web Site/a2spa”。用户名和密码将是您之前在 IIS 管理器权限中设置的用户名和密码。最后,目标 URL 通常与“服务器:”URL 相同,但这次前面会加上 `http://` 或 `https://` 以构成完整的 URL。

然后您应该点击“验证连接”以确保您的用户名和密码正确。如果失败,请修复直到通过验证。

按照提示操作,您是否记得在服务器上安装 WebDeploy?

重启 IIS 服务(或确保它们正在运行)会有帮助。

或者使用“服务”工具检查 Web 部署服务是否在服务器上运行。

我发现我需要手动编辑 Visual Studio 默认生成的发布配置文件。如果您遇到困难,请保存配置文件(即使它不工作),然后您可以着手解决问题,而不是重新输入所有内容。

Rick Strahl 的博客在我这个案例中找到了答案。打开属性,然后发布配置文件,打开文件进行编辑。

在我的案例中,我将 `MSDeployServiceURL` 修改为 `http://` 而不是 `https://`,并根据 Rick 的建议,将节点 `` 从 `WMSVC` 改为 `RemoteAgent`,然后将节点 `` 从 `True` 改为 `False`。保存并关闭文件,然后再次尝试发布。

第 7 部分第 8 部分中,我们使用文件系统进行了简单的发布,并需要重新启动应用程序池(我们也可以重新启动 IIS 实例)以解除对 `a2spa.dll` 文件的复制阻塞,否则在许多情况下会因为该文件正在使用而失败。使用 Web Deploy,我们可以从项目文件中删除执行此任务的代码。为简洁起见,如果您需要进一步帮助,请参阅第 7 部分第 8 部分

发布成功后,您应该会看到一条成功消息。

然后您就可以继续查看您新部署的网站了。

检查网站是否正常工作,以验证 IIS 和 SQL,并确保我们的依赖项已部署。

发布到 Azure

接下来我们将把我们的简单 A2SPA 网站发布到 Azure。

最简单的起点是在 Azure 中,首先创建 Web 应用程序和 SQL 实例,然后保存发布配置文件。

接下来将此保存的发布配置文件导入 Visual Studio。

也可以在 Visual Studio 中开始,并填写空白以使用现有的 Azure 站点,尽管这可能需要更多时间,因为您必须查找许多不同的设置、用户名和 URL——这些详细信息几乎都在发布文件中。

因此(假设您已设置好 Azure 门户并准备就绪),在 Azure 上创建一个空的 Web 应用 + SQL

只需确保您选择的是 ASP.Net Core Web App + SQL 项目。

给站点起个名字,我用了相当平庸的项目名,a2spa

然后会弹出一个向导,帮助您选择位置、选择计划(免费计划、廉价计划、不太便宜的计划等)。

创建 Web 应用后,您可以创建一个数据库。再次选择数据库类型(我选择了 SQL)、位置和计划。

经过一到两分钟的配置时间(请耐心等待),当网站和数据库创建完成后,您就可以开始了。

在网站设置过程中,如果您已将其固定到仪表板,您将在配置期间收到一个进行中的通知:

最后,当一切就绪后,只需下载 Visual Studio 发布配置文件。

回到 Visual Studio,使用“发布”,“导入”选项,输入您的密码,然后点击“发布”。

如果一切顺利,您应该能够浏览该网站,它现在已发布并托管在 Azure 上。

但是等等,并不完全是——没有 SSL。回想一下,`startup.cs` 中有一条指令,要求在生产环境中强制使用 HTTPS 连接。

我当然可以在 Azure 门户中设置 Azure 上的 SSL。微软在设置 SSL 证书方面有很好的文档,此处。或者 Nik Molnar 的此处博客文章详细介绍了如何使用 Let's Encrypt 的证书为 Azure 设置 SSL。

这很简单,而且有很多地方我可以购买 SSL 证书并进行此操作。甚至有一些组织提供免费*的 SSL 证书。(* 免费,但在实际使用所需时间方面可以说并不便宜)。由于本系列实际上没有给我带来收入,但却耗费了我的时间,因此我选择了不支付 SSL 证书费用。

如果您仍然想使用免费*的 SSL 证书,请尝试 “Let's Encrypt”

另一种“免费”方式是“自酿”,或使用 MakeCert 创建自签名证书。Shing Chen 的博客此处介绍了这一点。

所以最后,网站就是这样了,尽管没有 SSL,但仍然托管在 Azure 上并运行着。
很抱歉地说,当您阅读本文时,它可能无法正常运行,因为我正在使用免费的 Azure 积分,并且宁愿不超出我的限额而收到账单。:)

但为什么不尝试 Azure,设置一个免费试用开发者账户,也试试这个呢。

接下来呢?

希望您现在拥有一些工具,可以帮助您创建和扩展 SPA,利用您现有的 ASP.Net MVC 或 ASP.Net Core 技能,使用 Razor、.cshtml 和标签助手动态创建您的 Angular 模板。

没有理由不能扩展此设计,使其接受视图模型类,并通过单个标签和标签助手动态创建完整的表单或购物车。

进一步的扩展可以着眼于更智能的捆绑和压缩,具有多个入口点,如果网站规模允许,甚至可以集成 Webpack。

我认为这种设计应该足以构建大多数内部网应用程序,并且对于中小型公共互联网应用程序也非常有用。通过数据驱动和使用标签助手,您可以快速响应变化并将复制粘贴代码减少到最低限度。

如果考虑将此用于您的下一个网站,我还建议至少在标签助手周围添加一些服务器端单元测试,并在生成的标记和验证周围添加一些客户端测试。

其他值得关注的扩展点是从 Bootstrap 3 迁移到 Bootstrap 4 或 Material Design 2。

两者都支持 Angular 2 / 原生,并且可以允许您移除 jQuery 和其他一些文件。

您还可以考虑使用 SASS/SCSS 样式表生成,利用 Mads 的更多工具,因为这些工具确实可以在不费太多力气的情况下生成干净整洁的小型 CSS,让您对样式有很好的控制。同样,这些也可以成为后台工具的一部分,无需努力即可“正常工作”,例如 Mads 的 BundlerMinifier。

最后,已经有一些使用 ASP.Net Core 的服务器端预渲染和无 JavaScript 替代方案。Steve Sanderson 和其他人已经编写了一些巧妙的模板,无论是用于 Visual Studio 还是 Yeoman,它们都具有动态构建功能。通过一些努力,这些也可能通过这种设计实现。

如果对将此扩展为一个开源框架,添加一些工具和模板感兴趣,请在评论或电子邮件中告诉我。

希望您发现这是一个很棒的平台和前进方向。ASP.Net Core 和 Angular 拥有美好的未来。

历史

这是第 9 部分,也是本系列的最后一部分,之前的几部分是:

第 1 部分 - 如何集成 ASP.Net Core 和 Angular 2
第 2 部分 - 如何使用标签助手显示数据
第 3 部分 - 如何将标签助手用于数据输入,添加使用 EF Core 的 SQL 后端。
第 4 部分 - 使用 OpenIdDict 添加 JWT 令牌身份验证。 
第 5 部分 - 添加异步服务、服务器端验证、一个简单的 Angular 2 数据网格和更多标签助手。
第 6 部分 - 使用 NSwag 创建 Swagger 文档并生成 Angular 2 / Typescript 数据模型 + 数据服务。
第 7 部分 - 为 VS2015 用户发布到 IIS。
第 8 部分 - 为 VS 2017 用户发布到 IIS。.

这是最后一部分,第 9 部分,涵盖了捆绑、压缩、代码优先迁移、发布到外部 IIS 主机以及发布到 Azure。

© . All rights reserved.