build: move server rendering to dist (#4822)

* build: move server rendering to dist

* Verifying that Material works with `platform-server` now happens in the `dist/` folder (instead of the src/ folder)
* Adds a gulp task to build the universal application. In the future serving the app will be also part of this

* Address comments
This commit is contained in:
Paul Gschwendtner
2017-05-30 18:22:18 +02:00
committed by mmalerba
parent 12d6e968c2
commit fb5520cebf
11 changed files with 106 additions and 59 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ elif is_closure_compiler; then
elif is_unit; then
$(npm bin)/gulp ci:test
elif is_prerender; then
./scripts/ci/prerender.sh
$(npm bin)/gulp ci:prerender
fi
# Upload coverage results if those are present.
-23
View File
@@ -1,23 +0,0 @@
#!/usr/bin/env bash
### Pre-renders the app under src/universal-app with platform-server and dumps the
### output to stdout.
# Go to the project root directory
cd $(dirname $0)/../..
# Build the @angular/material package and copy it into node_modules.
# This is a workaround for https://github.com/angular/angular/issues/12249
rm -rf ./node_modules/@angular/material
gulp material:build-release
cp -r ./dist/releases/material ./node_modules/@angular/
# Compile the kitchen sink app (the generated ngfactories are consumed by the prerender script)
$(npm bin)/ngc -p src/universal-app/tsconfig-ngc.json
# Run the prerender script.
# This does not use ts-node because some of the generated ngfactory.ts files are written into a
# directory called "node_modules"; ts-node intentionally will not treat any file inside of a
# "node_modules" directory as TypeScript (with the opinion that node_modules should only contain JS)
$(npm bin)/tsc -p src/universal-app/tsconfig-prerender.json
node ./src/universal-app/dist/prerender.js
+1
View File
@@ -0,0 +1 @@
export * from './kitchen-sink/kitchen-sink';
+4 -3
View File
@@ -1,15 +1,16 @@
import 'reflect-metadata';
require('zone.js/dist/zone-node.js');
import 'zone.js';
import {enableProdMode} from '@angular/core';
import {renderModuleFactory} from '@angular/platform-server';
import {KitchenSinkServerModuleNgFactory} from './dist/aot/kitchen-sink/kitchen-sink.ngfactory';
import {join} from 'path';
import {readFileSync} from 'fs-extra';
import {KitchenSinkServerModuleNgFactory} from './kitchen-sink/kitchen-sink.ngfactory';
enableProdMode();
const result = renderModuleFactory(KitchenSinkServerModuleNgFactory, {
document: readFileSync('src/universal-app/index.html', 'utf-8')
document: readFileSync(join(__dirname, 'index.html'), 'utf-8')
});
result.then(html => console.log(html));
+29
View File
@@ -0,0 +1,29 @@
// TypeScript config file that is used to compile the universal-app.
{
"compilerOptions": {
"declaration": true,
"stripInternal": false,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../../dist/packages/universal-app",
"rootDir": ".",
"sourceMap": true,
"target": "es2015",
"lib": ["es2015", "dom"],
"skipLibCheck": true,
"types": [],
"baseUrl": ".",
"paths": {
"@angular/material": ["./material"],
"@angular/cdk": ["./cdk"]
}
},
"files": [
"main.ts"
],
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"genDir": "../../dist/packages/universal-app"
}
}
-23
View File
@@ -1,23 +0,0 @@
{
"compilerOptions": {
"module": "es2015",
"moduleResolution": "node",
"target": "es6",
"noImplicitAny": false,
"sourceMap": false,
"experimentalDecorators": true,
"outDir": "dist",
"declaration": true,
"typeRoots": ["node_modules/@types"]
},
"exclude": [
"node_modules",
"dist",
"prerender.ts"
],
"angularCompilerOptions": {
"annotationsAs": "static fields",
"annotateForClosureCompiler": true,
"genDir": "./dist/aot"
}
}
+19 -9
View File
@@ -1,15 +1,25 @@
// TypeScript config file that is used to compile the files that prerender the Universal app.
{
"compilerOptions": {
"lib": ["es2015", "dom"],
"target": "es6",
"declaration": false,
"stripInternal": false,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"noEmitOnError": true,
"noImplicitAny": true,
"sourceMap": false,
"experimentalDecorators": true,
"types": ["node"]
"outDir": ".",
"rootDir": ".",
"sourceMap": true,
"target": "es2015",
"lib": ["es2015", "dom"],
"skipLibCheck": true,
"types": [],
"baseUrl": ".",
"paths": {
"@angular/material": ["./material"],
"@angular/cdk": ["./cdk"]
}
},
"files": ["prerender.ts"]
"files": [
"prerender.ts"
]
}
+1
View File
@@ -19,3 +19,4 @@ import './tasks/aot';
import './tasks/payload';
import './tasks/coverage';
import './tasks/material-release';
import './tasks/universal';
+3
View File
@@ -16,3 +16,6 @@ task('ci:payload', ['payload']);
/** Task that uploads the coverage results to a firebase database. */
task('ci:coverage', ['coverage:upload']);
/** Task that verifies if all Material components are working with platform-server.*/
task('ci:prerender', ['universal:test-prerender']);
+44
View File
@@ -0,0 +1,44 @@
import {task} from 'gulp';
import {DIST_RELEASES, DIST_ROOT, SOURCE_ROOT} from '../constants';
import {ngcBuildTask, tsBuildTask, copyTask, sequenceTask, execTask} from '../util/task_helpers';
import {join} from 'path';
import {copySync} from 'fs-extra';
const appDir = join(SOURCE_ROOT, 'universal-app');
const outDir = join(DIST_ROOT, 'packages', 'universal-app');
/** Path to the universal-app tsconfig files. */
const tsconfigAppPath = join(appDir, 'tsconfig-build.json');
const tsconfigPrerenderPath = join(outDir, 'tsconfig-prerender.json');
/** Glob that matches all assets that need to copied to the dist. */
const assetsGlob = join(appDir, '**/*.+(html|css|json)');
/** Path to the file that prerenders the universal app using platform-server. */
const prerenderFile = join(appDir, 'prerender.ts');
/** Path to the compiled prerender file. Running this file just dumps the HTML output for now. */
const prerenderOutFile = join(outDir, 'prerender.js');
task('universal:test-prerender', ['universal:build'], execTask('node', [prerenderOutFile]));
task('universal:build', sequenceTask(
'clean',
['material:build-release', 'cdk:build-release'],
'universal:copy-release',
['universal:build-app-ts', 'universal:copy-app-assets', 'universal:copy-prerender-source'],
'universal:build-prerender-ts'
));
task('universal:build-app-ts', ngcBuildTask(tsconfigAppPath));
task('universal:copy-app-assets', copyTask(assetsGlob, outDir));
task('universal:build-prerender-ts', tsBuildTask(tsconfigPrerenderPath));
task('universal:copy-prerender-source', copyTask(prerenderFile, outDir));
// As a workaround for https://github.com/angular/angular/issues/12249, we need to
// copy the Material and CDK ESM output inside of the universal-app output.
task('universal:copy-release', () => {
copySync(join(DIST_RELEASES, 'material'), join(outDir, 'material'));
copySync(join(DIST_RELEASES, 'cdk'), join(outDir, 'cdk'));
});
+4
View File
@@ -37,6 +37,10 @@ export function tsBuildTask(tsConfigPath: string) {
return execNodeTask('typescript', 'tsc', ['-p', tsConfigPath]);
}
/** Creates a task that runs the Angular compiler CLI. */
export function ngcBuildTask(tsConfigPath: string) {
return execNodeTask('@angular/compiler-cli', 'ngc', ['-p', tsConfigPath]);
}
/** Create a SASS Build Task. */
export function sassBuildTask(dest: string, root: string, minify = false) {