Skip to content

Commit 97d69fb

Browse files
jelbourntinayuangao
authored andcommitted
build: add ci task for server-side prerender (#4808)
This adds a new task for Travis CI to prerender an app using @angular/material. This change starts off by only adding buttons to the application; more components will be added in a subsequent PR so that this one stays focused on the set-up.
1 parent 7db2762 commit 97d69fb

File tree

11 files changed

+142
-0
lines changed

11 files changed

+142
-0
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
- env: "MODE=e2e"
2121
- env: "MODE=aot"
2222
- env: "MODE=payload"
23+
- env: "MODE=prerender"
2324
- env: "MODE=closure-compiler"
2425
- env: "MODE=saucelabs_required"
2526
- env: "MODE=browserstack_required"

scripts/ci/build-and-test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ elif is_closure_compiler; then
4141
./scripts/closure-compiler/build-devapp-bundle.sh
4242
elif is_unit; then
4343
$(npm bin)/gulp ci:test
44+
elif is_prerender; then
45+
./scripts/ci/prerender.sh
4446
fi
4547

4648
# Upload coverage results if those are present.

scripts/ci/prerender.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
3+
### Pre-renders the app under src/universal-app with platform-server and dumps the
4+
### output to stdout.
5+
6+
# Go to the project root directory
7+
cd $(dirname $0)/../..
8+
9+
# Build the @angular/material package and copy it into node_modules.
10+
# This is a workaround for https://github.com/angular/angular/issues/12249
11+
rm -rf ./node_modules/@angular/material
12+
gulp material:build-release
13+
cp -r ./dist/releases/material ./node_modules/@angular/
14+
15+
# Compile the kitchen sink app (the generated ngfactories are consumed by the prerender script)
16+
$(npm bin)/ngc -p src/universal-app/tsconfig-ngc.json
17+
18+
# Run the prerender script.
19+
# This does not use ts-node because some of the generated ngfactory.ts files are written into a
20+
# directory called "node_modules"; ts-node intentionally will not treat any file inside of a
21+
# "node_modules" directory as TypeScript (with the opinion that node_modules should only contain JS)
22+
$(npm bin)/tsc -p src/universal-app/tsconfig-prerender.json
23+
node ./src/universal-app/dist/prerender.js

scripts/ci/sources/mode.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ is_payload() {
2424
is_unit() {
2525
[[ "$MODE" = saucelabs_required || "$MODE" = browserstack_required ]]
2626
}
27+
28+
is_prerender() {
29+
[[ "$MODE" = prerender ]]
30+
}

src/universal-app/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Angular Material Univeral Kitchen Sink Test</title>
6+
<base href="/">
7+
</head>
8+
<body>
9+
<kitchen-sink>Loading...</kitchen-sink>
10+
</body>
11+
</html>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.kitchen-sink {
2+
color: lightsteelblue;
3+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<h1>Kitchen sink app</h1>
2+
3+
<h2>Buttons</h2>
4+
5+
<button md-button>go</button>
6+
<button md-icon-button>go</button>
7+
<button md-raised-button>go</button>
8+
<button md-fab>go</button>
9+
<button md-mini-fab>go</button>
10+
11+
<a md-button href="https://google.com">Google</a>
12+
<a md-icon-button href="https://google.com">Google</a>
13+
<a md-raised-button href="https://google.com">Google</a>
14+
<a md-fab href="https://google.com">Google</a>
15+
<a md-mini-fab href="https://google.com">Google</a>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {Component, NgModule} from '@angular/core';
2+
import {ServerModule} from '@angular/platform-server';
3+
import {BrowserModule} from '@angular/platform-browser';
4+
import {MdButtonModule} from '@angular/material';
5+
6+
7+
@Component({
8+
selector: 'kitchen-sink',
9+
templateUrl: './kitchen-sink.html',
10+
styleUrls: ['./kitchen-sink.css'],
11+
})
12+
export class KitchenSink { }
13+
14+
15+
@NgModule({
16+
imports: [
17+
BrowserModule.withServerTransition({appId: 'kitchen-sink'}),
18+
MdButtonModule,
19+
],
20+
bootstrap: [KitchenSink],
21+
declarations: [KitchenSink],
22+
})
23+
export class KitchenSinkClientModule { }
24+
25+
26+
@NgModule({
27+
imports: [KitchenSinkClientModule, ServerModule],
28+
bootstrap: [KitchenSink],
29+
})
30+
export class KitchenSinkServerModule { }

src/universal-app/prerender.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'reflect-metadata';
2+
require('zone.js/dist/zone-node.js');
3+
4+
import {enableProdMode} from '@angular/core';
5+
import {renderModuleFactory} from '@angular/platform-server';
6+
import {KitchenSinkServerModuleNgFactory} from './dist/aot/kitchen-sink/kitchen-sink.ngfactory';
7+
import {readFileSync} from 'fs-extra';
8+
9+
enableProdMode();
10+
11+
const result = renderModuleFactory(KitchenSinkServerModuleNgFactory, {
12+
document: readFileSync('src/universal-app/index.html', 'utf-8')
13+
});
14+
15+
result.then(html => console.log(html));
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"compilerOptions": {
3+
"module": "es2015",
4+
"moduleResolution": "node",
5+
"target": "es6",
6+
"noImplicitAny": false,
7+
"sourceMap": false,
8+
"experimentalDecorators": true,
9+
"outDir": "dist",
10+
"declaration": true,
11+
"typeRoots": ["node_modules/@types"]
12+
},
13+
"exclude": [
14+
"node_modules",
15+
"dist",
16+
"prerender.ts"
17+
],
18+
"angularCompilerOptions": {
19+
"annotationsAs": "static fields",
20+
"annotateForClosureCompiler": true,
21+
"genDir": "./dist/aot"
22+
}
23+
}

0 commit comments

Comments
 (0)