diff --git a/aio/content/guide/universal.md b/aio/content/guide/universal.md index eb85fa2861..f4653ba73d 100644 --- a/aio/content/guide/universal.md +++ b/aio/content/guide/universal.md @@ -180,7 +180,7 @@ npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-lo {@a transition} -### Modify the client app +## Modify the client app A Universal app can act as a dynamic, content-rich "splash screen" that engages the user. It gives the appearance of a near-instant application. @@ -190,7 +190,9 @@ Once loaded, Angular transitions from the static server-rendered page to the dyn You must make a few changes to your application code to support both server-side rendering and the transition to the client app. -#### The root `AppModule` +{@a root-app-module} + +### The root `AppModule` Open file `src/app/app.module.ts` and find the `BrowserModule` import in the `NgModule` metadata. Replace that import with this one: @@ -206,9 +208,29 @@ You can get runtime information about the current platform and the `appId` by in +{@a cli-output} + +### Build Destination + +A Universal app is distributed in two parts: the server-side code that serves up the initial application, and the client-side code that's loaded in dynamically. + +The Angular CLI outputs the client-side code in the `dist` directory by default, so you modify the `outputPath` for the __build__ target in the `angular.json` to keep the client-side build outputs separate from the server-side code. The client-side build output will be served by the Express server. + +``` +... +"build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/browser", + ... + } +} +... +``` + {@a http-urls} -#### Absolute HTTP URLs +### Absolute HTTP URLs The tutorial's `HeroService` and `HeroSearchService` delegate to the Angular `HttpClient` module to fetch application data. These services send requests to _relative_ URLs such as `api/heroes`. @@ -262,6 +284,19 @@ The `ModuleMapLoaderModule` is a server-side module that allows lazy-loading of This is also the place to register providers that are specific to running your app under Universal. +{@a app-server-entry-point} + +### App server entry point + +The `Angular CLI` uses the `AppServerModule` to build the server-side bundle. + +Create a `main.server.ts` file in the `src/` directory that exports the `AppServerModule`: + + + + +The `main.server.ts` will be referenced later to add a `server` target to the `Angular CLI` configuration. + {@a web-server} ### Universal web server @@ -421,6 +456,8 @@ This config extends from the root's `tsconfig.json` file. Certain settings are n * The `angularCompilerOptions` section guides the AOT compiler: * `entryModule` - the root module of the server application, expressed as `path/to/file#ClassName`. +{@a universal-webpack-configuration} + ### Universal Webpack configuration Universal applications doesn't need any extra Webpack configuration, the CLI takes care of that for you, @@ -433,13 +470,38 @@ Create a `webpack.server.config.js` file in the project root directory with the **Webpack configuration** is a rich topic beyond the scope of this guide. +{@a universal-cli-configuration} + +### Angular CLI configuration + +The CLI provides builders for different types of __targets__. Commonly known targets such as `build` and `serve` already exist in the `angular.json` configuration. To target a server-side build, add a `server` target to the `architect` configuration object. + +* The `outputPath` tells where the resulting build will be created. +* The `main` provides the main entry point to the previously created `main.server.ts` +* The `tsConfig` uses the `tsconfig.server.json` as configuration for the TypeScript and AOT compilation. + +``` +"architect": { + ... + "server": { + "builder": "@angular-devkit/build-angular:server", + "options": { + "outputPath": "dist/server", + "main": "src/main.server.ts", + "tsConfig": "src/tsconfig.server.json" + } + } + ... +} +``` + ## Build and run with universal -Now that you've created the TypeScript and Webpack config files, you can build and run the Universal application. +Now that you've created the TypeScript and Webpack config files and configured the Angular CLI, you can build and run the Universal application. First add the _build_ and _serve_ commands to the `scripts` section of the `package.json`: - +``` "scripts": { ... "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server", @@ -448,7 +510,7 @@ First add the _build_ and _serve_ commands to the `scripts` section of the `pack "webpack:server": "webpack --config webpack.server.config.js --progress --colors" ... } - +``` {@a build} diff --git a/aio/tools/examples/shared/boilerplate/cli/angular.json b/aio/tools/examples/shared/boilerplate/cli/angular.json index 6d46cf39da..5d17ddcf30 100644 --- a/aio/tools/examples/shared/boilerplate/cli/angular.json +++ b/aio/tools/examples/shared/boilerplate/cli/angular.json @@ -11,7 +11,7 @@ "build": { "builder": "@angular-devkit/build-angular:browser", "options": { - "outputPath": "dist/angular.io-example", + "outputPath": "dist", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", diff --git a/aio/tools/examples/shared/boilerplate/i18n/angular.json b/aio/tools/examples/shared/boilerplate/i18n/angular.json index 00ec0bccd1..d8bc38f374 100644 --- a/aio/tools/examples/shared/boilerplate/i18n/angular.json +++ b/aio/tools/examples/shared/boilerplate/i18n/angular.json @@ -11,7 +11,7 @@ "build": { "builder": "@angular-devkit/build-angular:browser", "options": { - "outputPath": "dist/angular.io-example", + "outputPath": "dist", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", diff --git a/aio/tools/examples/shared/boilerplate/testing/angular.json b/aio/tools/examples/shared/boilerplate/testing/angular.json index 9aaab56b56..11ed94218d 100644 --- a/aio/tools/examples/shared/boilerplate/testing/angular.json +++ b/aio/tools/examples/shared/boilerplate/testing/angular.json @@ -11,7 +11,7 @@ "build": { "builder": "@angular-devkit/build-angular:browser", "options": { - "outputPath": "dist/angular.io-example", + "outputPath": "dist", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts",