如何在 Angular CLI 建立的專案加入 Angular Universal 伺服器渲染功能

栏目: JavaScript · 发布时间: 7年前

内容简介:如何在 Angular CLI 建立的專案加入 Angular Universal 伺服器渲染功能

自 Angular 4.0 開始 Angular Universal 就已經正式併入 Angular 核心功能,本篇文章將示範如何將一個由 Angular CLI 建立的專案,加入 Angular Universal 伺服器渲染能力,只要透過 Node.js 知名的 Express 網站框架,即可快速實現 Angular 的伺服器渲染能力 ( SSR ) ( Server-side Rendering )。

1. 建立全新 Angular 4 專案

ng new demo1

2. 安裝 ts-node 套件 ( --save-dev )

由於我們的 Express 程式碼會以 TypeScript 撰寫,因此你必須額外安裝 ts-node 套件才能讓 Express + TypeScript 正確執行。

npm install --save-dev ts-node

3. 安裝 @angular/platform-server 套件

注意:自 npm 5.0 之後,npm install 不需要特別加上 --save 參數,只要專案下有 package.json 檔案,在 npm install 之後預設就會自動儲存套件到 package.json 定義檔中。

npm install @angular/platform-server

4. 更新 AppModule 模組 ( src/app/app.module.ts )

修正預設 AppModule 中 BrowserModule 的匯入方式

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'demo1' })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

5. 建立一個全新的 AppServerModule 模組 ( src/app/app.server.module.ts )

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    ServerModule,
    AppModule
  ],
  bootstrap: [AppComponent]
})
export class AppServerModule { }

6. 加入 ExpressJS / Node.js 主程式 ( src/server.ts )

由於 renderModuleFactory 函式需要透過 AOT (Ahead of Time) 編譯過的檔案,其傳入的第一個參數 AppServerModuleNgFactory 必須要先執行 ng server --prod ngc 命令才能產生相關檔案,在這些檔案出現之前,你可能會在 Visual Studio Code 看見找不到參考檔案的錯誤訊息。

import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import { platformServer, renderModuleFactory } from '@angular/platform-server'
import { enableProdMode } from '@angular/core'
import { AppServerModuleNgFactory } from '../dist/ngfactory/src/app/app.server.module.ngfactory'
import * as express from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';

const PORT = 4000;

enableProdMode();

const app = express();

let template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();

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', 'src')

app.get('*.*', express.static(join(__dirname, '..', 'dist')));

app.get('*', (req, res) => {
  res.render('index', { req });
});

app.listen(PORT, () => {
  console.log(`listening on http://localhost:${PORT}!`);
});

7. 更新 src/tsconfig.app.json 定義檔

我們要跳過 Express 程式 ( src/server.ts ),因為這段 Code 是 Node.js 的程式,會影響 Angular 本身的 TypeScript 編譯,因此需要排除在外。

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "es2015",
    "baseUrl": "",
    "types": []
  },
  "exclude": [
    "server.ts",
    "test.ts",
    "**/*.spec.ts"
  ]
}

8. 更新 tsconfig.json 定義檔

請務必加入 "angularCompilerOptions" 設定到 tsconfig.json 定義檔中。

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "baseUrl": "src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2016",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "genDir": "./dist/ngfactory",
    "entryModule": "./src/app/app.module#AppModule"
  }
}

9. 更新 package.json

加入 "start" 與 "prestart" 到 "scripts" 區段中,因為在正式執行 src/server.ts 之前,必須先執行 ng build --prod 與 ngc 命令。

注意:專案內的 ngc 命令 (AOT 編譯工具) 位於 node_modules/.bin 目錄下。

"scripts": {
    "ng": "ng",
    "prestart": "ng build --prod && ngc",
    "start": "ts-node src/server.ts",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },

10. 執行 npm start 即可透過 ExpressJS 執行網站,預設網址為 http://localhost:4000/

如何在 Angular CLI 建立的專案加入 Angular Universal 伺服器渲染功能

如果查看 HTML 原始碼的話,就會發現 Angular Universal 的伺服器渲染機制已經成功啟動! ^__^

如何在 Angular CLI 建立的專案加入 Angular Universal 伺服器渲染功能

本篇文章已經將變更紀錄上傳至 GitHub,想看 Angular CLI 建立之後到底做出了哪些變化,可以參考 angular-universal-demo1 專案的 版本變更紀錄

相關連結


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

搜索引擎

搜索引擎

李晓明 / 科学出版社发行部 / 2005-4 / 33.00元

《搜索引擎:原理技术与系统》系统地介绍了互联网搜索引擎的工作原理、实现技术及其系统构建方案。《搜索引擎:原理技术与系统》分三篇共13章内容,从基本工作原理概述,到一个小型简单搜索引擎具体细节的实现,进而详细讨论了大规模分布式搜索引擎系统的设计要点及其关键技术;最后介绍了面向主题和个性化的web信息服务,阐述了中文网页自动分类等技术及其应用。《搜索引擎:原理技术与系统》层次分明,由浅入深;既有深入的......一起来看看 《搜索引擎》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器