什么是 Angular6 SSR
Angular6 SSR(Server-Side Rendering)是指在服务器端将 Angular6 应用程序渲染成 HTML,然后将其发送到浏览器。这种技术的好处是可以提高应用程序的性能、SEO、用户体验等方面。在使用 Angular6 SSR 时,需要注意一些问题,下面将详细介绍。
问题一:如何启用 SSR
在 Angular6 中,启用 SSR 需要进行以下步骤:
- 安装 @angular/platform-server 模块和 ts-loader 模块。
npm install @angular/platform-server ts-loader --save
- 修改应用程序的主模块,将其导出为一个函数,并添加 @NgModule 装饰器。
// javascriptcn.com 代码示例 import { NgModule } from '@angular/core'; import { ServerModule } from '@angular/platform-server'; import { AppModule } from './app.module'; import { AppComponent } from './app.component'; @NgModule({ imports: [AppModule, ServerModule], bootstrap: [AppComponent], }) export class AppServerModule {}
- 创建一个服务器端入口文件,用于加载应用程序的主模块并渲染 HTML。
// javascriptcn.com 代码示例 import 'zone.js/dist/zone-node'; import { enableProdMode } from '@angular/core'; import { renderModuleFactory } from '@angular/platform-server'; import { readFileSync } from 'fs'; import { join } from 'path'; import * as express from 'express'; import { AppServerModuleNgFactory } from './dist/server/main'; const PORT = process.env.PORT || 4000; const DIST_FOLDER = join(process.cwd(), 'dist'); const app = express(); const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString(); enableProdMode(); app.engine('html', (_, options, callback) => { const opts = { document: template, url: options.req.url }; renderModuleFactory(AppServerModuleNgFactory, opts) .then(html => { callback(null, html); }); }); app.set('view engine', 'html'); app.set('views', join(DIST_FOLDER, 'browser')); app.get('*.*', express.static(join(DIST_FOLDER, 'browser'))); app.get('*', (req, res) => { res.render('index', { req }); }); app.listen(PORT, () => { console.log(`Node server listening on http://localhost:${PORT}`); });
问题二:如何处理样式
在使用 SSR 时,需要注意样式的处理。由于服务器端渲染的 HTML 中不包含 CSS 样式,因此需要在客户端重新加载样式。可以使用以下两种方式来处理样式:
- 将样式文件通过 webpack 打包成一个文件,然后在 HTML 中引用该文件。
<link rel="stylesheet" href="styles.css">
- 将样式文件以内联样式的方式嵌入到 HTML 中。
// javascriptcn.com 代码示例 import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Meta, Title } from '@angular/platform-browser'; import { ActivatedRoute } from '@angular/router'; import { TransferState, makeStateKey } from '@angular/platform-browser'; import { HttpClient } from '@angular/common/http'; const STYLES_KEY = makeStateKey<string>('styles'); @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], encapsulation: ViewEncapsulation.None, }) export class AppComponent implements OnInit { constructor( private meta: Meta, private title: Title, private route: ActivatedRoute, private transferState: TransferState, private http: HttpClient, ) {} ngOnInit() { this.title.setTitle('My App'); const styles = this.transferState.get<string>(STYLES_KEY, ''); this.meta.addTag({ name: 'style', content: styles }); if (!styles) { this.http.get('/styles.css', { responseType: 'text' }).subscribe(css => { this.transferState.set(STYLES_KEY, css); this.meta.addTag({ name: 'style', content: css }); }); } } }
问题三:如何处理路由
在使用 SSR 时,需要注意路由的处理。由于服务器端渲染的 HTML 中不包含 JavaScript,因此需要在客户端重新加载 JavaScript 并初始化路由。可以使用以下两种方式来处理路由:
- 将路由信息通过 webpack 打包成一个文件,然后在 HTML 中引用该文件。
<script src="main.js"></script>
- 将路由信息以 JSON 格式嵌入到 HTML 中,并在客户端加载后解析并初始化路由。
// javascriptcn.com 代码示例 import { Component, OnInit, ViewEncapsulation, Inject, PLATFORM_ID } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; import { isPlatformBrowser } from '@angular/common'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], encapsulation: ViewEncapsulation.None, }) export class AppComponent implements OnInit { constructor( private router: Router, @Inject(PLATFORM_ID) private platformId: Object, ) {} ngOnInit() { if (isPlatformBrowser(this.platformId)) { const routes = JSON.parse(document.getElementById('routes').textContent); this.router.resetConfig(routes); this.router.initialNavigation(); } } }
总结
Angular6 SSR 技术可以提高应用程序的性能、SEO、用户体验等方面。在使用 Angular6 SSR 时,需要注意样式、路由等方面的处理。通过本文的介绍,相信读者已经掌握了 SSR 的基本原理和使用方法,可以在实际项目中灵活运用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/650c45a295b1f8cacd64dc95