如何使用 Angular Universal 进行服务器端渲染

简介

Single-Page Applications(SPA)由最初提供给客户端的_Single_HTML文档组成。应用程序中所需的任何新视图都是通过JavaScript在客户端单独生成的。请求-响应循环仍然会发生,但这通常只适用于REST风格的数据API;或者获取静态资源,如图像。

以这种方式编写应用程序有很多好处。然而,有些东西你会失去,比如网络爬虫遍历你的应用程序的能力,以及当应用程序加载时性能变慢,这可能会花费大量的时间。服务器端渲染(SSR)的出现弥补了这一差距。

在本文中,您将学习如何使用ANGLE Universal进行服务器端呈现。

前提条件

要学习本教程,您需要:

本教程已通过Node v16.4.2、npm v7.19.1、@angular/core v12.1.1和@nguniversal/express-engine v12.1.0验证。

第1步-Angel Universal入门

ANGLE应用程序是一个单页面应用程序--它在客户的浏览器中运行。不过,Angel Universal还允许您在服务器上运行您的Angel应用程序。这使您能够向客户端提供静态HTML。使用ANGLE Universal,服务器将预先呈现页面并向用户显示一些内容,而客户端应用程序则在后台加载。然后,一旦客户端准备就绪,它将从显示服务器呈现的页面无缝切换到客户端应用程序。你的用户应该不会注意到什么不同,除了这样一个事实,即他们至少可以有一些内容来保持他们的参与度,直到他们可以开始使用功能齐全的客户端应用程序,而不是等待你的加载微调工具完成。

使用Angular Universal的SSR需要在客户端应用程序和服务器堆栈中进行更改才能工作。在本文中,我们假设这是一个全新的Angular应用程序,几乎没有使用Angular CLI创建,版本为version >= 7。几乎任何服务器技术都可以运行Universal应用程序,但它必须能够调用Angular Universal提供的一个特殊函数renderModuleFactory(),它本身就是一个Node包;因此从Node/Express服务器服务这个Angular应用程序对这个例子来说是有意义的。

我们将使用一张示意图来让我们迅速起身。

从应用程序目录中打开一个终端并运行以下命令:

1ng add @nguniversal/express-engine

您会注意到,此示意图对您的应用程序进行了几次更改,修改了一些文件并添加了一些文件:

更新angular.json

  • projects.{{project-name}}.architect.build.options.outputPath更改为dist/Browser
  • 增加了一个新的Projects.{{project-name}}.Architecture,称为服务器

这让ANGLE CLI了解我们的ANGLE应用程序的服务器/通用版本。

更新Package.json

除了一些新的依赖项(不出所料)外,我们还获得了一些新的脚本:

  • dev:ssr
  • build:ssr
  • serve:ssr
  • 预渲染

更新main.ts

这一点已被修改,以便该应用程序的浏览器版本在Universal呈现的页面完全加载之前不会开始引导。

更新app.mode.ts

修改为在导入的BrowserModule上执行静态方法.with ServerTaketion。这会告诉应用程序的浏览器版本,客户端将在某个时候从服务器版本转换过来。

创建server.ts

这是NodeJS Express服务器。显然,您不必使用生成的确切服务器设置,但请注意以下行:

1server.engine('html', ngExpressEngine({ ... }))

ngExpressEngineeringrenderModuleFactory的包装器,它使Universal工作。如果你没有在你的设置中使用这个确切的server.ts文件,至少把这个部分复制出来,并整合到你的文件中。

创建tsconfig.server.json

这告诉ANGLE编译器在哪里可以找到Universal应用程序的入口模块。

创建app.server.mode.ts

这仅是服务器版本的根模块。您可以看到,它导入了我们的AppModule,以及@Angel/Platform-server中的ServerModule,并引导了与AppModule相同的AppComponentAppServerModule是通用应用程序的入口点。

创建main.server.ts

这个新文件基本上只导出AppServerModule,它是应用程序通用版本的入口点。我们很快就会重温这一点。

第二步-启动您的万能应用

从命令行运行以下命令:

1npm run build:ssr

然后运行:

1npm run serve:ssr

假设您在构建过程中没有遇到任何问题,打开浏览器进入http://localhost:4000(或为您配置的任何端口),您应该会看到您的通用应用程序正在运行!它看起来不会有什么不同,但第一个页面的加载速度应该比常规的角度应用程序快得多。如果你的应用又小又简单,你可能很难注意到这一点。

你可以尝试通过打开Chrome Dev工具,在网络选项卡下,找到显示在线 的下拉列表,来尝试限制网络速度。选择** 慢速3G** 以模拟慢速网络上的设备-您应该仍然会看到登录页面和您转到的任何路由页面的良好性能。

另外,尝试查看页面源代码(在页面上单击鼠标右键并选择[查看页面源代码])。您将在<BODY>标记中看到所有普通的HTML,该标记与您的页面上显示的内容相匹配--这意味着,您的应用程序可能会被网络爬虫抓取。将其与非通用应用程序的页面源代码进行比较,您将在<Body>标记中看到的全部内容是<app-root>(或您所称的引导AppComponent的选择器)。

总结

在本文中,您了解了如何使用ANGLE Universal进行服务器端呈现。

由于通用应用程序在服务器上运行,而不是在浏览器中运行,因此您需要在应用程序代码中注意以下几点:

  • 检查您是否使用了特定于浏览器的对象,如windowDocumentLocation。这些在服务器上不存在。您无论如何都不应该使用它们;尝试使用可注入的角度抽象,例如DocumentLocation。作为最后的手段,如果您确实需要它们,请将它们的用法包装在条件语句中,这样它们将只在浏览器上按角度使用。您可以通过从@Angel/Common导入函数isPlatformBrowserisPlatformServer,将PLATFORM_ID内标识注入到您的组件中,然后运行导入的函数来查看您是在服务器上还是在浏览器上。
  • 如果您使用ElementRef来获取对HTML元素的句柄,请不要使用nativeElement来操作元素上的属性。相反,注入Renderer2使用there.方法之一
  • 浏览器事件处理不起作用。在服务器上运行时,您的应用程序不会响应点击事件或其他浏览器事件。但是,通过routerLink生成的任何链接都可以用于导航。
  • 尽量避免使用setTimeout
  • 将服务器请求的所有URL设置为绝对URL。从服务器运行时,从相对URL请求数据将失败,即使服务器可以处理相对URL。
  • 类似地,从服务器发出的HTTP请求的安全性与从浏览器发出的不同。服务器请求可能具有不同的安全要求和功能。您必须亲自处理这些请求的安全问题。

继续了解Angel Universal在官方documentation.]中提供的内容

Published At
Categories with 技术
Tagged with
comments powered by Disqus