Angular 是一款非常流行的前端框架,它拥有强大的模板系统、依赖注入和组件化等特性。开发一个通用应用(Universal Application)后,可以在服务端生成 HTML,并将 CSS 和 JS 打包到一起,从而提高首次加载的速度,增强用户体验。本文将介绍 Angular 通用应用的实践与思考,包括概念解析、实现思路和示例代码等内容。
什么是 Angular 通用应用
通用应用,又称服务器端渲染(Server-Side Rendering,SSR),指的是对于每个 URL 请求,服务器端均返回一个渲染完毕的 HTML 页面。它与传统的客户端渲染(Client-Side Rendering,CSR)相对应,后者在浏览器端加载 JS 代码并执行,呈现出用户界面。
Angular 通用应用的实现,就是将客户端渲染的流程拆分成两个步骤:
- 服务器端渲染:根据路由、数据等信息生成 HTML 页面;
- 客户端重渲染:在浏览器端重新运行 Angular 应用,以便响应用户事件和数据更新等操作。
通过这种方式,我们可以将部分计算和工作从浏览器端转移到服务器端,从而提高页面加载速度、SEO(搜索引擎优化)和渲染性能等方面的优势。
开发流程和实践思路
在实现 Angular 通用应用之前,首先要明确以下几个概念:
- 服务端渲染(Server-Side Rendering,SSR):指的是在服务器端生成完整的 HTML,并返回给客户端;
- 预渲染(Prerendering):指的是在编译阶段生成静态 HTML,部署到服务器上供客户端使用;
- 数据同构(Data Isomorphism):指的是在服务器端和客户端使用相同的数据模型,并使用相同的数据处理逻辑。这样可以避免在客户端重新查询一次数据,提高性能和一致性。
在开发 Angular 通用应用时,需要遵循以下步骤:
1. 安装 Angular CLI
Angular CLI 是一个用于快速启动和管理 Angular 应用的命令行工具。通过以下命令安装:
npm install -g @angular/cli
2. 创建 Angular 通用应用
使用 Angular CLI 创建一个新的应用:
ng new my-app --universal
这将创建一个名为 "my-app" 的新项目,并添加通用应用的支持。
3. 修改应用代码
3.1 修改 app.module.ts 内容
-- -------------------- ---- ------- ------ - -------- - ---- ---------------- ------ - ------------- - ---- ---------------------------- ------ - ------------ - ---- ------------------ ------ - ----------------------- - ---- --------------------------------------- ------ - ---------------- - ---- ----------------------- ------ - ---------------- - ---- ----------------------- ------ - ------------- - ---- ------------------ ------ - ------------ - ---- ------------------ ------ - ------------- - ---- ---------------------------- ------ - -------------------- - ---- -------------------------- ----------- ------------- --------------- -------- - ------------------------------------ ------ ----------- --- ------------------------ ----------------- ----------------- ------------- -- ---------- - - -------- -------------- --------- ------------------------ -- -- - -- -------------- - -------- ------------------ -- -- - --------- --------------------- ------ ----- -- -- ---------- --------------- -- ------ ----- --------- - ------------------- -------- -------------- -------------- -- -- -- - ------ ---------------------------- ------------ --- - ------ - --------- ---------- ---------- ------------------------- -- - -展开代码
- 更改 1:指定根 URL,这里替换成了
http://localhost:4000
。 - 更改 2:添加一个
UniversalInterceptor
拦截器,用于在客户端和服务端执行相同的 AJAX 请求。 - 更改 3:添加
forRoot
方法,用于提供额外的服务或者为应用配置服务。因为构造函数不会在服务端执行,因此要利用forRoot
的一个特性。
3.2 创建 UniversalInterceptor
创建一个名为 universal.interceptor.ts
的文件,添加以下内容:
-- -------------------- ---- ------- ------ - ------------ ---------------- ----------- - ---- ----------------------- ------ - ---------- - ---- ---------------- ------ - ------------- --------- ------------- - ---- ---------------------------- ------ - ----------- -- - ---- ------- ------ - --- - ---- ----------------- ------------- ------ ----- -------------------- ---------- --------------- - ------------------- -------- -------------- -------------- -- ------------------ --------------------- ----- ------------- --------------- - ----- --- - ------------------------------------------- ----- -------------- - -------------------------------------------- ------ -- ---------------- - ------------------------------- ------ --------------- - ----- ------------ - --- -------------------------- -- - -------------------------------- ----- ---------- -- - ------------------------ -- ------ ----- -- - -------------------- -- --------- -- -- - -------------------- -- --- --- ------------------ ------------------ -- - --------------------------- ------------------ -- -- ------ ------------- - -展开代码
这个拦截器的作用是缓存 AJAX 请求结果,以便在客户端渲染时能够快速加载数据。
3.3 修改 app.server.module.ts 文件
在 app.server.module.ts
中,添加以下内容:
-- -------------------- ---- ------- ------ - -------- - ---- ---------------- ------ - ------------- ------------------------- - ---- --------------------------- ------ - --------------------- - ---- ------------------------------------------- ------ - --------- - ---- --------------- ------ - ------------ - ---- ------------------ ----------- -------- - ---------- ------------- -------------------------- ---------------------- -- ---------- --------------- -- ------ ----- --------------- --展开代码
这个模块使 Angular 应用能够在服务器端渲染。
3.4 修改 main.ts 文件
在 main.ts
文件中,添加以下内容:
-- -------------------- ---- ------- ------ - -------------- - ---- ---------------- ------ - --------------- - ---- ---------------------------- ------ - --------- - ---- ------------------- ------ - ----------- - ---- ----------------------------- ------ - ------------- - ---- ------------------ ------ - --------------------- - ---- --------------------------- -- -- - -- ------------------------ - ----------------- - --------------------------------------------- -- -- - ----- -------- - ----------------- - -------- -------------- --------- ----------------------- -- -- -- - ---------------------- -- -- - --- -------- --------- -- -- - -------------------------- -------------- -- - ------------------------------------ --- ---展开代码
- 更改 1:导入
APP_ROUTING_PROVIDERS
。 - 更改 2:指定根 URL。
- 更改 3:在
platformBrowser
中注入APP_ROUTING_PROVIDERS
。 - 更改 4:注入
AppModule
的ngZone
,用于处理跨平台事件和任务。
3.5 添加 prerender.js 文件
创建一个名为 prerender.js
的文件,添加以下内容:
-- -------------------- ---- ------- ----- - ------------------- - - ------------------------------------ ----- - ------------ - - -------------- ----- - ---- - - ---------------- ----- - ------------------------ - - ------------------------------ ----- -------- - ---------------------------- ------- ---------- -------------- --------- --------------------------------------------- - --------- ---- ---- -------------- -- - ------------------ ---展开代码
这个文件将启动一个 Node.js 服务器,用于渲染 Angular 应用。
4. 执行预渲染
在执行预渲染之前,需要确保已经创建了 Angular 通用应用,并已经做好了上述代码的修改和添加。然后,执行以下步骤:
生成构建:
ng build --prod --output-hashing none
该命令会生成一个用于预渲染的前端应用。
运行预渲染命令:
node prerender.js > prerender.html
预渲染命令将生成一个名为
prerender.html
的文件,包含了已经渲染完毕的 HTML 代码。
5. 部署预渲染代码
将 prerender.html
文件部署到服务器上。同时,设置服务器端路由,将所有请求都指向该文件,以便服务器能够返回预渲染后的 HTML。
6. 在客户端中启动 Angular 应用
使用预渲染生成的 HTML 文件,用作 Angular 应用启动前的初始页面。当客户端的 JS 加载和执行完毕后,Angular 应用会重渲染整个页面,同时对数据进行同构处理,在服务器和客户端之间实现状态的传递和更新。
示例代码
完整的 Angular 通用应用示例代码,可以在 GitHub 上找到。这个示例包括了一个使用 Angular CLI 创建的基础骨架,以及一些通用应用的代码修改和添加。同时,还包括了一个 prerender.js
文件,用于执行预渲染。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67be1389a231b2b7ed10ff5a