refactor(docs-infra): update `universal` example to match latest CLI (#36483)

Update the `universal` example (and related files) to match what would
be generated by the latest CLI.

Fixes #35289

PR Close #36483
This commit is contained in:
George Kalpakas 2020-04-08 15:27:42 +03:00 committed by atscott
parent 4d9da9b0a1
commit ec5c108b60
13 changed files with 950 additions and 293 deletions

View File

@ -82,9 +82,6 @@ upgrade-phonecat-2-hybrid/aot/**/*
# styleguide
!styleguide/src/systemjs.custom.js
# universal
!universal/webpack.server.config.js
# stackblitz
*stackblitz.no-link.html
@ -97,4 +94,4 @@ upgrade-phonecat-3-final/rollup-config.js
!upgrade-phonecat-*/**/karma-test-shim.js
# schematics
!schematics-for-libraries/projects/my-lib/package.json
!schematics-for-libraries/projects/my-lib/package.json

View File

@ -6,24 +6,28 @@ import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';
// The Express app is exported so that it can be used by serverless Functions.
export function app() {
const server = express();
const distFolder = join(process.cwd(), 'dist/express-engine-ivy/browser');
const distFolder = join(process.cwd(), 'dist/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// #docregion ngExpressEngine
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
// #enddocregion ngExpressEngine
server.set('view engine', 'html');
server.set('views', distFolder);
// #docregion data-request
// TODO: implement data requests securely
server.get('/api/*', (req, res) => {
res.status(404).send('data requests are not supported');
server.get('/api/**', (req, res) => {
res.status(404).send('data requests are not yet supported');
});
// #enddocregion data-request
@ -37,7 +41,7 @@ export function app() {
// #docregion navigation-request
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render('index', { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
// #enddocregion navigation-request
@ -59,7 +63,8 @@ function run() {
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
if (mainModule && mainModule.filename === __filename) {
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}

View File

@ -1,6 +1,5 @@
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@ -9,11 +8,10 @@ import { AppComponent } from './app.component';
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule
],
providers: [
// Add universal-only providers here
],
bootstrap: [ AppComponent ],
bootstrap: [AppComponent],
})
export class AppServerModule {}

View File

@ -8,5 +8,7 @@ if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
});

View File

@ -1,32 +0,0 @@
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: { server: './server.ts' },
resolve: { extensions: ['.js', '.ts'] },
target: 'node',
mode: 'none',
// this makes sure we include node_modules and other 3rd party libraries
externals: [/node_modules/],
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [{ test: /\.ts$/, loader: 'ts-loader' }]
},
plugins: [
// Temporary Fix for issue: https://github.com/angular/angular/issues/11580
// for 'WARNING Critical dependency: the request of a dependency is an expression'
new webpack.ContextReplacementPlugin(
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, 'src'), // location of your src
{} // a map of your routes
),
new webpack.ContextReplacementPlugin(
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'),
{}
)
]
};

View File

@ -62,10 +62,10 @@ The files marked with `*` are new and not in the original tutorial sample.
To start rendering your app with Universal on your local system, use the following command.
<code-example language="bash">
npm run build:ssr && npm run serve:ssr
npm run dev:ssr
</code-example>
Open a browser and navigate to http://localhost:4000/.
Open a browser and navigate to http://localhost:4200/.
You should see the familiar Tour of Heroes dashboard page.
Navigation via `routerLinks` works correctly because they use the native anchor (`<a>`) tags.
@ -328,7 +328,7 @@ The following code filters for request URLs with no extensions and treats them a
### Serving static files safely
A single `app.use()` treats all other URLs as requests for static assets
A single `server.use()` treats all other URLs as requests for static assets
such as JavaScript, image, and style files.
To ensure that clients can only download the files that they are permitted to see, put all client-facing asset files in

View File

@ -18,7 +18,6 @@
],
"devDependencies": [
"@angular/compiler-cli",
"@angular/platform-server",
"@types/jasmine",
"@types/node",
"jasmine-core",

View File

@ -6,23 +6,24 @@
{ "name": "test", "command": "ng test" },
{ "name": "lint", "command": "ng lint" },
{ "name": "e2e", "command": "ng e2e" },
{ "name": "build:ssr", "command": "npm run build:client-and-server-bundles && npm run webpack:server" },
{ "name": "serve:ssr", "command": "node dist/server.js" },
{ "name": "build:client-and-server-bundles", "command": "ng build --prod && ng run angular.io-example:server" },
{ "name": "webpack:server", "command": "webpack --config webpack.server.config.js --progress --colors" }
{ "name": "dev:ssr", "command": "ng run angular.io-example:serve-ssr" },
{ "name": "build:ssr", "command": "ng build --prod && ng run angular.io-example:server:production" },
{ "name": "serve:ssr", "command": "node dist/server/main.js" },
{ "name": "prerender", "command": "ng run angular.io-example:prerender" }
],
"dependencies": [
"@angular/platform-server",
"@nguniversal/express-engine",
"@nguniversal/module-map-ngfactory-loader"
"express"
],
"devDependencies": [
"@angular-devkit/build-angular",
"@angular/cli",
"@nguniversal/builders",
"@types/express",
"@types/jasminewd2",
"jasmine-spec-reporter",
"karma-coverage-istanbul-reporter",
"ts-loader",
"ts-node",
"webpack-cli"
"ts-node"
]
}

View File

@ -1,4 +1,4 @@
# How to update the CLI project
# How to update the CLI project
The Angular CLI default setup is updated using `ng update`. Any necessary file changes will be done automatically through migration schematics.
@ -46,5 +46,5 @@ The specific changes to each project type are listed below:
- Includes a `server` target in the `build` architect runners
- package.json
- Includes custom scripts for building the `server`
- Includes additional `dependencies` on `@nguniversal/common`, `@nguniversal/express-engine`, and `@nguniversal/module-map-ngfactory-loader`
- Includes `devDependencies` on `@angular/platform-server`, and `ts-loader`
- Includes additional `dependencies` on `@angular/platform-server`, `@nguniversal/express-engine`, and `express`
- Includes additional `devDependencies` on `@nguniversal/builders` and `@types/express`

View File

@ -122,8 +122,47 @@
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/server",
"main": "src/main.server.ts",
"main": "server.ts",
"tsConfig": "tsconfig.server.json"
},
"configurations": {
"production": {
"outputHashing": "media",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": true
}
}
},
"serve-ssr": {
"builder": "@nguniversal/builders:ssr-dev-server",
"options": {
"browserTarget": "angular.io-example:build",
"serverTarget": "angular.io-example:server"
},
"configurations": {
"production": {
"browserTarget": "angular.io-example:build:production",
"serverTarget": "angular.io-example:server:production"
}
}
},
"prerender": {
"builder": "@nguniversal/builders:prerender",
"options": {
"browserTarget": "angular.io-example:build:production",
"serverTarget": "angular.io-example:server:production",
"routes": [
"/"
]
},
"configurations": {
"production": {}
}
}
}

View File

@ -9,10 +9,10 @@
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:ssr": "node dist/server.js",
"build:client-and-server-bundles": "ng build --prod && ng run angular.io-example:server",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors"
"dev:ssr": "ng run angular.io-example:serve-ssr",
"serve:ssr": "node dist/server/main.js",
"build:ssr": "ng build --prod && ng run angular.io-example:server:production",
"prerender": "ng run angular.io-example:prerender"
},
"private": true,
"dependencies": {
@ -23,12 +23,11 @@
"@angular/forms": "~9.0.6",
"@angular/platform-browser": "~9.0.6",
"@angular/platform-browser-dynamic": "~9.0.6",
"@angular/platform-server": "~9.0.6",
"@angular/router": "~9.0.6",
"@nguniversal/common": "~9.0.1",
"@nguniversal/express-engine": "~9.0.1",
"@nguniversal/module-map-ngfactory-loader": "~9.0.0-next.9",
"angular-in-memory-web-api": "~0.9.0",
"express": "^4.17.1",
"express": "^4.15.2",
"rxjs": "~6.5.4",
"tslib": "^1.10.0",
"zone.js": "~0.10.3"
@ -38,8 +37,8 @@
"@angular/cli": "~9.0.6",
"@angular/compiler-cli": "~9.0.6",
"@angular/language-service": "~9.0.6",
"@angular/platform-server": "~9.0.6",
"@types/express": "^4.17.2",
"@nguniversal/builders": "^9.0.2",
"@types/express": "^4.17.0",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
@ -53,10 +52,8 @@
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"protractor": "~5.4.3",
"ts-loader": "^6.2.1",
"ts-node": "~8.3.0",
"tslint": "~5.18.0",
"typescript": "~3.7.5",
"webpack-cli": "^3.3.10"
"typescript": "~3.7.5"
}
}

View File

@ -28,18 +28,17 @@
"@angular/forms": "~9.0.6",
"@angular/platform-browser": "~9.0.6",
"@angular/platform-browser-dynamic": "~9.0.6",
"@angular/platform-server": "~9.0.6",
"@angular/router": "~9.0.6",
"@angular/service-worker": "~9.0.6",
"@angular/upgrade": "~9.0.6",
"@nguniversal/common": "~9.0.1",
"@nguniversal/express-engine": "~9.0.1",
"@nguniversal/module-map-ngfactory-loader": "~9.0.0-next.9",
"@webcomponents/custom-elements": "^1.4.1",
"angular": "1.7.9",
"angular-in-memory-web-api": "~0.9.0",
"angular-route": "1.7.9",
"core-js": "^2.5.4",
"express": "^4.17.1",
"express": "^4.15.2",
"rxjs": "~6.5.4",
"systemjs": "0.19.39",
"tslib": "^1.10.0",
@ -50,13 +49,13 @@
"@angular/cli": "~9.0.6",
"@angular/compiler-cli": "~9.0.6",
"@angular/language-service": "~9.0.6",
"@angular/platform-server": "~9.0.6",
"@nguniversal/builders": "^9.0.2",
"@types/angular": "1.6.47",
"@types/angular-animate": "1.5.10",
"@types/angular-mocks": "1.6.0",
"@types/angular-resource": "1.5.14",
"@types/angular-route": "1.3.5",
"@types/express": "4.0.35",
"@types/express": "^4.17.0",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/jquery": "3.3.28",
@ -83,10 +82,8 @@
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-uglify": "^1.0.1",
"source-map-explorer": "^1.3.2",
"ts-loader": "^6.2.1",
"ts-node": "~8.3.0",
"tslint": "~5.18.0",
"typescript": "~3.7.5",
"webpack-cli": "^3.3.10"
"typescript": "~3.7.5"
}
}

File diff suppressed because it is too large Load Diff