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

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

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

相關連結


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

查看所有标签

猜你喜欢:

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

敏捷估计与规划

敏捷估计与规划

[美] Mike Cohn / 宋锐 / 清华大学出版社 / 2007-7 / 39.90元

《敏捷估计与规划》一书为对敏捷项目进行估计与规划提供了权威实际的指导方针。在本书中,敏捷联盟的共同创始人Mike Cohn讨论了敏捷估计与规划的思想,并使用现实的例子与案例分析向您详细地展示了如何完成工作。本书清晰地阐述了有关的概念,并引导读者逐步认识到下列一些问题的答案:我们要构建什么?它的规模有多大?需要在什么时候完成?到那个时候我们到底能完成多少?您首先会认识到优秀的计划由哪些东西组成,接着......一起来看看 《敏捷估计与规划》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

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

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具