Angular CLI 1.3.0 和 Angular 4.3 版本之前,要使用 SSR (Server Side Rendering) 其實還蠻複雜的,並不是無法做到,只是很麻煩。可是,當版本升級到 Angular 4.3 及 CLI 1.3.0 以後,這一切都變得非常簡單。這裡先說明如何快速地將 SSR 的環境建置起來
前置作業
-
先將 CLI 的版本升級到 1.3.0。可以從這看到目前的釋出版本 CLI Release (2017/08/08 時,CLI版本是 1.3.0-rc.5)
npm install @angular/[email protected]
-
安裝 @angular/platform-server
npm install @angular/platform-server
設定步驟
.angular-cli.json
多新增一個 app
設定
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "name": "universal", "platform": "server", "root": "src", "outDir": "dist-server", "main": "main-server.ts", "tsconfig": "tsconfig.server.json", "environmentSource": "environments/environment.ts", "environments": { "dev": "environments/environment.ts", "prod": "environments/environment.prod.ts" } }
|
main-server.ts
在 scr
資料夾下新增 main-server.ts
檔案
1 2 3 4
| import {enableProdMode} from '@angular/core'; export {AppServerModule} from './app/app-server.module';
enableProdMode();
|
app-server.module
在 src/app
資料夾下,新增 `app-server.module.ts’ 檔案
1 2 3 4 5 6 7 8 9 10
| import {NgModule} from '@angular/core'; import {ServerModule} from '@angular/platform-server';
import {AppComponent} from './app.component'; import {AppModule} from './app.module';
@NgModule({imports: [AppModule, ServerModule], bootstrap: [AppComponent]}) export class AppServerModule { }
|
app.module
修改 app.module.ts
檔案,給予 withServerTransition
的設定值,appId
可以任取。
1 2 3 4 5 6
| ... imports: [ BrowserModule.withServerTransition({appId: 'universal'}), ... ], ...
|
tsconfig.server.json
在 src
資料夾下,新增 tsconfig.server.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| { "extends": "./tsconfig.app.json", "compilerOptions": { "outDir": "../out-tsc/server", "module": "commonjs" }, "exclude": [ "test.ts", "**/*.spec.ts" ], "angularCompilerOptions": { "entryModule": "app/app-server.module#AppServerModule" } }
|
package.json
修改 scripts
指令
「build」: 「ng build --prod && ng build --prod --app universal --output-hashing=none」
這樣子當執行 npm run build
時,就會分別建置瀏覽器端及伺服器端所需要的程式了
設定 node express server
在專案跟目錄下新增 server.js
檔案,這檔案的功能是執行一個 node express
網站伺服器
套件安裝
npm install express @nguniversal/express-engine
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 'use strict';
require('zone.js/dist/zone-node');
const express = require('express'); const ngUniversal = require('@nguniversal/express-engine');
const appServer = require('./dist-server/main.bundle');
function angularRouter(req, res) { res.render('index', {req, res}); }
const app = express();
app.get('/', angularRouter);
app.use(express.static(`${__dirname}/dist`));
app.engine('html', ngUniversal.ngExpressEngine({ bootstrap: appServer.AppServerModuleNgFactory })); app.set('view engine', 'html'); app.set('views', 'dist');
app.get('*', angularRouter);
app.listen(3000, () => { console.log(`Listening on http://localhost:3000`); });
|
執行方式
node server.js
執行上述指令後,就會將一個網站伺服器跑起來,而開啟 http://localhost:3000
的網站,即可看到由伺服器產生的 Angular 網站
參考資料