如何在 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 專案的 版本變更紀錄

相關連結


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

查看所有标签

猜你喜欢:

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

Effective Java

Effective Java

Joshua Bloch / Addison-Wesley Professional / 2018-1-6 / USD 54.99

The Definitive Guide to Java Platform Best Practices—Updated for Java 9 Java has changed dramatically since the previous edition of Effective Java was published shortly after the release of Jav......一起来看看 《Effective Java》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具