找了各式各样的文章,一直没有看到完整关于Angular Univeral的详细步骤教学
而在设定时也会有一些小细节需要处理,因此本文将完整从Client Side Render 如何成功导入Server Side Render
让Google的爬虫能够搜寻的到使用 Angular开发的网站。
在2020的今天,随着Web Framework的窜起,使用前端框架如:Angular,React,Vue开发系统早已是见怪不怪的事。
但这种前端主流框架,对于SPA 没办法进行SEO一直以来都是开发者最为头痛的事。
因此就有Next.js 这类的工具可以协助我们进行Server-Side-Render。
而在Angular中,则有Angular Universal可以帮助我们解决问题。
早期Angular 要使用SSR 技术要新增不少的档案与内容,但现在只需要使用cli的指令就可以达成。
加入@nguniversal/express-engine 到专案中
在Angular专案下,我们可以安装
ng add @nguniversal/express-engine --clientProject 專案名稱(可以由angular.json查看名稱)
安装后,我们会发现cli指令帮我们建立了不少档案。
其中最主要的部份则以server.ts
以及app.server.module.ts
这两支档案为主。
这边简单说明一下:
server.ts主要是运行我们SSR最主要的程式,透过这支程式,会自动在部属时自动将首页进行编译,让我们的angular的程式,能够预先载入到index.html中
而不是透过浏览器执行的时候才将js渲染到画面上。简单来说,就是该程式就是将首页的js进行编译,并载入到html中回传静态的网页内容。
app.server.module.ts 则是与app.module.ts相同,但不同的是,透过ssr编译时,会采用的是app.server.module.ts进行呼叫。
在安装好express-engine 套件后,接下来要运行 Universal Web Server。
这里跟一般我们平时在使用ng serve 一样,都是去呼叫node.js的express起来,进行监听。
输入以下指令
npm run build:ssr;npm run serve:ssr
就会执行ssr 的build(部属)以及serve(运行)。
如果正确无误的话,那么你将会看到以下画面:
但如果不能build出现can't find window / localstorage的话。由于SSR是透过nodejs预先将页面进行编译以及载入。
因此在nodejs中并没有windows 或是localStorage等其他在Web上的功能。
尽管可以透过nodeJS进行部分模拟,放入到server.ts中,让node.js读懂这些语法是什么。
但大多数在Client Side中的语法,还是得需要透过浏览器去运行。
让node.js读懂的语法如下:
import 'localStorage-polyfill';
global['localStorage'] = localStorage;
但如果是其他的套件,例如应该要在Client端运行的Ex: jQuery/scroll ...等
就不应该由Server编译的时候执行。
必须区分哪些程式码应该要在Server进行SSR编译时执行,哪些该由Client执行的时候运行。
因此我们需要在Component的constructor 中注入:
constructor(@Inject(PLATFORM_ID) private platformId: any) { }
并且在需要由Client端执行的程式码加入以下判断:
if (isPlatformBrowser(this.platformId)) { const anchorOffset = $('div.anchor-' + this.anchor); $('html,body').animate({ scrollTop: anchorOffset.offset().top - 100 }, 100); }
像上面这种有使用到jQuery还有scroll,牵涉到画面甚至是动画效果的,都应该由Client端执行,而非在Server端中执行。
因此我们就需要透过 isPlatformBrowser(this.platformId) 来判断当前执行此段程式码是否为Browser
若是在SSR编译时期,则该段程式就不会被运行。
注记: 若使用ngModel的话,使用到该物件的所有兜必须要先初始化才能使用,让nodejs编译。
若上述都完成,则会在dist建立browser以及server这两个资料夹。
browser:编译完后所产生的程式码,内含有index.html (和过去使用ng build --prod相同)
server=>在SSR渲染的第一页中,所有用到的图档,以及js都会在这里
若正常完成的话,会自动在localhost端监听4000 port来运行SSR
Node Express server listening on http://localhost:4000
此时将网页按右键检视原始码,将会看到在 中的程式码已经被自动带入