为啥有这篇文章

在之前,类似 Angular、React、Vue 之类的前端框架的一个痛点就是无法在服务端提前把网页内容写入到网页中再发回浏览器,这给网站的 SEO 增加了不少困难,因为爬虫爬到的页面只包含加载内容的 js 源码,而网页内容部分都还是各种模板占位符。现在,Angular4 正式的推出了 angular/universal 这个用来支持在服务端渲染 Angular 应用的包,再加上 Angular 团队与 AspNet 团队的不懈努力,现在在 Asp.Net Core MVC 应用中使用 Angular 作为网站前端框架非常方便,同时支持服务端渲染功能,简直美滋滋。

接下来就让我们通过经典的 英雄指南 应用来快速的感受一下 SSR 的快感。


搭建开发环境

首先,你需要安装以下的软件:

  • dotnet-cli 1.0.4+
  • nodejs 8+
  • Visual Studio 2017 / Visual Studio Code
  • git

注意:下面所有的命令均是在 PowerShell 中执行的

安装完上面的工具之后,将这个仓库克隆到你的电脑上,他是一个相对来说很纯洁的起始模板。

接着来安装 Angular 所需要的依赖:

npm i

然后生成 WebPack 的 vendor.js:

./webpack-restore.ps1

然后再来安装 Asp.Net Core Mvc 需要的 Nuget 包:

dotnet restore

到目前为止,我们的项目就可以运行了:

dotnet run

我们的项目结构大概是这样的:

│  .gitattributes
│  .gitignore
│  MyBlog.sln
│
├─.vscode
│      launch.json
│      settings.json
│      tasks.json
│
└─Blog.Web
    │  appsettings.json
    │  Blog.Web.csproj
    │  global.json
    │  package.json
    │  Program.cs
    │  Startup.cs
    │  tsconfig.json
    │  web.config
    │  webpack-restore.ps1
    │  webpack.config.js
    │  webpack.config.vendor.js
    │
    ├─.template.config
    │      icon.png
    │
    ├─bin
    │
    ├─ClientApp
    │  │  boot-client.ts
    │  │  boot-server.ts
    │  │
    │  ├─app
    │  │  │  app.module.client.ts
    │  │  │  app.module.server.ts
    │  │  │  app.module.shared.ts
    │  │  │
    │  │  └─components
    │  │      └─app
    │  │              app.component.css
    │  │              app.component.html
    │  │              app.component.ts
    │  │
    │  └─dist
    │          main-server.js
    │          vendor-manifest.json
    │          vendor.js
    │
    ├─Controllers
    │      HomeController.cs
    │
    ├─Views
    │  │  _ViewImports.cshtml
    │  │  _ViewStart.cshtml
    │  │
    │  ├─Home
    │  │      Index.cshtml
    │  │
    │  └─Shared
    │          Error.cshtml
    │          _Layout.cshtml
    │
    └─wwwroot
        │  favicon.ico
        │
        ├─css
        │      styles.css
        │
        └─dist
                main-client.js
                main-client.js.map
                vendor-manifest.json
                vendor.js

看起来可能比官方的例子要复杂一些,但至少不是太过复杂,毕竟还包括了一个完整的后台服务器。

保持前端的实时编译

微软团队很周到的考虑到了这个开发过程中的需求,所以这个功能已经集成进你的 C# 代码里面了,所以你不需要做任何额外的配置。

如果你是通过命令行来启动网站,需要手动设置一下环境变量:

$env:ASPNETCORE_ENVIRONMENT="Development"

然后执行:

dotnet run

那么现在,就可以完全按照官方的教程来学习英雄指南了。

针对服务端渲染的一些改变

怎么会有三个 app.module 跟两个 boot.xxx.ts ?

boot.xxx.ts 相当于官方英雄指南中的 main.ts 用于引导 Angualr 应用启动,有两个是为了在浏览器跟服务器环境中使用不同的配置来启动 Angular 应用。

由于不同环境的差异,Angular 需要针对不同的运行环境来引入特定的 module,然后,app.module.shared.ts 就相当于英雄指南中 app.module.ts 了。

index.html 在哪里?

在官方的实例中,有个 index.html,在我们的这个项目中,与之对应的是 Home/Index.cshtml,服务端渲染也是从这里起步的。

全局的 style.css 在哪里?

官方项目的 systemjs 的打包脚本中加入了一个用来存放全局样式的 style.css,我这里就很简单粗暴的放在了 wwwroot/css/style.css ,然后在 Index.cshtml 中直接引用。

服务端渲染时是怎么加载 http 请求获取的数据的?

服务端渲染时会发出请求来获取数据,但是由于服务端没有浏览器的环境,无法对域名做出自己的判断,所以,http 请求的路径必须完整的包含域名与路径,如果为了更好的兼容性,可以这么来写:

import { isPlatformServer } from "@angular/common";
...

constructor(
        private http: Http,
        @Inject(PLATFORM_ID) private platformId: Object) {
        // 针对服务器环境,手动设置请求地址
        if (isPlatformServer(this.platformId)) {
            this.heroesUrl = 'http://localhost:5000' + this.heroesUrl;
        }
    }

学会接受异常输出

由于 Kestrel 的设计原因,在启用了 HMR (Hot Module Replacement)之后,你可能经常的发现会有关于 Kestrel 的异常抛出显示在命令行,不用太过担心,这是 websocket 被强制切断造成的,而且这个异常并不会对你的应用造成负面影响,更何况,在实际的生产阶段,HMR 是被关闭的,所以在开发的时候,稍微忍一忍就好了。

Mock HTTP?

在官方的指南中使用到了一个用来模拟后台服务器的包,但是这对于一个 Asp.Net 程序来说,这个包是完全没有必要的,我们可以使用 EF Core 的 InMemmoryDb 来作为模拟数据库,然后通过 ASP.NET Core MVC 来提供类似的 RESTful API。

总结

Asp.Net Core MVC 对 Angular 的服务端渲染的支持总体来说还是相当不错的,符合微软一贯的风格,开箱即用,封装底层,对于一个普通的后端程序员来说可以很好的避免直接接触 WebPack 这个东西,2333,最后送上完整的 英雄指南

基于 Asp.Net Core MVC 的 Angular4 SSR 英雄指南的更多相关文章

  1. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-1

    来个目录吧: 第一章 第二章 第三章 暂时就这么多.后面路线更新吧 本系列文章为翻译加上我个人的使用心得理解,希望帮助热爱学习的程序员. 珍重声明:本系列文章会跟原文有点出入,去掉了罗里吧嗦的文字. ...

  2. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-4

    来个目录吧: 第一章-入门 第二章- Entity Framework Core Nuget包管理 第三章-创建.修改.删除.查询 第四章-排序.过滤.分页.分组 第五章-迁移,EF Core 的co ...

  3. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-2

    来个目录吧: 第一章 第二章 第三章 暂时就这么多.后面路线更新吧 Entity Framework Core Nuget包管理 如果你创建项目的时候启用了个人身份验证的话,项目中就已经包含了EFCo ...

  4. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-3

    来个目录吧: 第一章 第二章 第三章 暂时就这么多.后面路线更新吧 创建.查询.更新.删除 这章主要讲解使用EF完成 增删改查的功能. 自定义"详情信息"页面 我们通过基架生成的代 ...

  5. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-5

    来个目录吧: 第一章-入门 第二章- Entity Framework Core Nuget包管理 第三章-创建.修改.删除.查询 第四章-排序.过滤.分页.分组 第五章-迁移,EF Core 的co ...

  6. 基于Asp.Net Core MVC和AdminLTE的响应式管理后台之侧边栏处理

    说明: .NET Core版本为:2.2 AdminLTE版本为:2.4.18 Bootstrap版本为:3.4.1 font-awesome版本为:4.7.0 1.新建项目:AdminLteDemo ...

  7. 创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表

    创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表 创建数据模型类(POCO类) 在Models文件夹下添 ...

  8. 基于ASP.NET core的MVC站点开发笔记 0x01

    基于ASP.NET core的MVC站点开发笔记 0x01 我的环境 OS type:mac Software:vscode Dotnet core version:2.0/3.1 dotnet sd ...

  9. ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览

    原文:Overview of ASP.NET Core MVC 作者:Steve Smith 翻译:张海龙(jiechen) 校对:高嵩 ASP.NET Core MVC 是使用模型-视图-控制器(M ...

随机推荐

  1. 动态代理:JDK动态代理和CGLIB代理的区别

    代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法.实际执行的是被代理类的方法. 而AOP,是通过动态代理实现的. 一.简单来说: JD ...

  2. .Net中各种不同的对象创建方式的速度差异

    在.Net中,微软给我们提供了很多不同的创建对象实例的方法,它们的速度又各有不同,以下一一列举. 使用new关键字 这在.Net中是最常见,也是速度最快的方式:                     ...

  3. C#实现将输入的数自动转换为科学计数法

    一朋友写了一个把输入的整型或浮点数转换为科学计数法表示的算法,写好后叫我去帮他看看有没有什么bug之类的没有考虑周全.我还没有细看就已经把我吓到了----整整写了将近三百行代码.我也没说他什么,只是回 ...

  4. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

  5. 【分享】纯jQuery实现星巴克官网导航栏效果

    前言 大冬天的没得玩,只能和代码玩. 所以就无聊研究了一下星巴克官网,在我看来应该是基本还原吧~ 请各位大神指教! 官网效果图 要写的就是最上方的会闪现的白色条条 效果分析 1.在滚动条往下拉到一定距 ...

  6. 创建mysql快捷登录方式

    1.先找到mysql的bin目录,将Mysql.exe发送快捷方式到桌面,到这里还没有完成. 2.然后右键选择属性,将目标后面添加上 -uroot -p 我的完整目标如下: D:\install\my ...

  7. .net core 支付宝,微信支付 二

    源码: https://github.com/aspros-luo/Qwerty.Payment/tree/develop 今天开始微信支付 微信支付坑比较多,支付流程也不太一样,微信支付需要先生成预 ...

  8. STM32F030如何正确配置IO口的复用功能

    本文所使用的单片机型号为STM32F030C8T6. 在030系列的单片机中,PA2引脚除了作为普通的IO引脚用作输入输出功能以外,还可以作为内部外设串口1,串口2,定时器15通道1这三个外设的功能引 ...

  9. 盘点一下立过的flag并立几个flag

    暑假前说了,要学opencv3,要看完冰火,要健身,要家教挣钱. 好样的,全都没落下. opencv3几乎是把80%的demo码了一遍. 冰火看完,还顺带学了一波知识,收获颇丰,搞到了马丁老爷子的几本 ...

  10. EntityFramework For Mysql 动态切换数据源

    1.简介 在工作中遇到一个问题.项目有三个数据库(三个数据库表结构一样),用户可以选择使用哪个数据库.其实就是动态切换数据库连接. 2.EntityFramework For Mysql 先来简单的介 ...