diff --git a/aio-ja/content/guide/universal.en.md b/aio-ja/content/guide/universal.en.md deleted file mode 100644 index 29cd2b943..000000000 --- a/aio-ja/content/guide/universal.en.md +++ /dev/null @@ -1,369 +0,0 @@ -# Server-side rendering (SSR) with Angular Universal - -This guide describes **Angular Universal**, a technology that allows Angular to render applications on the server. - -By default, Angular renders applications only in a *browser*. Angular Universal allows Angular to render an application on the *server*, generating *static* HTML content, which represents an application state. Once the HTML content is rendered in a browser, Angular bootstraps an application and reuses the information available in the server-generated HTML. - -With server-side rendering an application generally renders in a browser faster, giving users a chance to view the application UI before it becomes fully interactive. See the ["Why use Server-Side Rendering?"](#why-do-it) section below for additional information. - -Also for a more detailed look at different techniques and concepts surrounding SSR, check out this [article](https://developers.google.com/web/updates/2019/02/rendering-on-the-web). - -You can enable server-side rendering in your Angular application using the `@nguniversal/express-engine` package as described below. - -
- -Angular Universal requires an [active LTS or maintenance LTS](https://nodejs.org/about/releases) version of Node.js. -For information see the [version compatibility](guide/versions) guide to learn about the currently supported versions. - -
- - - -## Universal tutorial - -The [Tour of Heroes tutorial](tutorial/tour-of-heroes) is the foundation for this walkthrough. - -In this example, the Angular CLI compiles and bundles the Universal version of the application with the [Ahead-of-Time (AOT) compiler](guide/aot-compiler). -A Node.js Express web server compiles HTML pages with Universal based on client requests. - -
- -Download the finished sample code, which runs in a [Node.js® Express](https://expressjs.com) server. - -
- -### Step 1. Enable Server-Side Rendering - -Run the following command to add SSR support into your application: - - - -ng add @nguniversal/express-engine - - - -The command updates the application code to enable SSR and adds extra files to the project structure (files that are marked with the `*` symbol). - -
-
- src -
-
-
- index.html                             // <-- app web page -
-
- main.ts                                  // <-- bootstrapper for client app -
-
- main.server.ts                       // <-- * bootstrapper for server app -
-
- style.css                                // <-- styles for the app -
-
- app/  …                                   // <-- application code -
-
-
- app.config.ts                   // <-- client-side application configuration (standalone app only) -
-
- app.module.ts                 // <-- client-side application module (NgModule app only) -
-
-
-
- app.config.server.ts       // <-- * server-side application configuration (standalone app only) -
-
- app.module.server.ts     // <-- * server-side application module (NgModule app only) -
-
-
- server.ts                                // <-- * express web server -
-
- tsconfig.json                        // <-- TypeScript base configuration -
-
- tsconfig.app.json                // <-- TypeScript browser application configuration -
-
- tsconfig.server.json            // <-- TypeScript server application configuration -
-
- tsconfig.spec.json              // <-- TypeScript tests configuration -
-
-
- -### Step 2. Enable Client Hydration - -
- -The hydration feature is available for [developer preview](/guide/releases#developer-preview). It's ready for you to try, but it might change before it is stable. - -
- -Hydration is the process that restores the server side rendered application on the client. This includes things like reusing the server rendered DOM structures, persisting the application state, transferring application data that was retrieved already by the server, and other processes. Learn more about hydration in [this guide](guide/hydration). - -You can enable hydration by updating the `app.module.ts` file. Import the `provideClientHydration` function from `@angular/platform-browser` and add the function call to the `providers` section of the `AppModule` as shown below. - -```typescript -import {provideClientHydration} from '@angular/platform-browser'; -// ... - -@NgModule({ - // ... - providers: [ provideClientHydration() ], // add this line - bootstrap: [ AppComponent ] -}) -export class AppModule { - // ... -} -``` - -### Step 3. Start the server - -To start rendering your application with Universal on your local system, use the following command. - - - -npm run dev:ssr - - - -### Step 4. Run your application in a browser - -Once the web server starts, open a browser and navigate to `http://localhost:4200`. -You should see the familiar Tour of Heroes dashboard page. - -Navigation using `routerLinks` works correctly because they use the built-in anchor \(``\) elements. -You can go from the Dashboard to the Heroes page and back. -Click a hero on the Dashboard page to display its Details page. - -If you throttle your network speed so that the client-side scripts take longer to download \(instructions following\), you'll notice: - -* You can't add or delete a hero -* The search box on the Dashboard page is ignored -* The *Back* and *Save* buttons on the Details page don't work - -The transition from the server-rendered application to the client application happens quickly on a development machine, but you should always test your applications in real-world scenarios. - -You can simulate a slower network to see the transition more clearly as follows: - -1. Open the Chrome Dev Tools and go to the Network tab. -1. Find the [Network Throttling](https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#throttling) dropdown on the far right of the menu bar. -1. Try one of the "3G" speeds. - -The server-rendered application still launches quickly but the full client application might take seconds to load. - - - -## Why use Server-Side Rendering? - -There are three main reasons to create a Universal version of your application. - -* Facilitate web crawlers through [search engine optimization (SEO)](https://static.googleusercontent.com/media/www.google.com/en//webmasters/docs/search-engine-optimization-starter-guide.pdf) -* Improve performance on mobile and low-powered devices -* Show the first page quickly with a [first-contentful paint (FCP)](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint) - - - - -### Facilitate web crawlers (SEO) - -Google, Bing, Facebook, Twitter, and other social media sites rely on web crawlers to index your application content and make that content searchable on the web. -These web crawlers might be unable to navigate and index your highly interactive Angular application as a human user could do. - -Angular Universal can generate a static version of your application that is easily searchable, linkable, and navigable without JavaScript. -Universal also makes a site preview available because each URL returns a fully rendered page. - - - -### Improve performance on mobile and low-powered devices - -Some devices don't support JavaScript or execute JavaScript so poorly that the user experience is unacceptable. -For these cases, you might require a server-rendered, no-JavaScript version of the application. -This version, however limited, might be the only practical alternative for people who otherwise couldn't use the application at all. - - - -### Show the first page quickly - -Displaying the first page quickly can be critical for user engagement. -Pages that load faster perform better, [even with changes as small as 100ms](https://web.dev/shopping-for-speed-on-ebay). -Your application might have to launch faster to engage these users before they decide to do something else. - -With Angular Universal, you can generate landing pages for the application that look like the complete application. -The pages are pure HTML, and can display even if JavaScript is disabled. -The pages don't handle browser events, but they *do* support navigation through the site using [`routerLink`](guide/router-reference#router-link). - -In practice, you'll serve a static version of the landing page to hold the user's attention. -At the same time, you'll load the full Angular application behind it. -The user perceives near-instant performance from the landing page and gets the full interactive experience after the full application loads. - - - -## Universal web servers - -A Universal web server responds to application page requests with static HTML rendered by the [Universal template engine](#universal-engine). -The server receives and responds to HTTP requests from clients \(usually browsers\), and serves static assets such as scripts, CSS, and images. -It might respond to data requests, either directly or as a proxy to a separate data server. - -The sample web server for this guide is based on the popular [Express](https://expressjs.com) framework. - -
- -**NOTE**:
-*Any* web server technology can serve a Universal application as long as it can call Angular `platform-server` package [`renderModule`](api/platform-server/renderModule) or [`renderApplication`](api/platform-server/renderApplication) functions. -The principles and decision points discussed here apply to any web server technology. - -
- -Universal applications use the Angular `platform-server` package \(as opposed to `platform-browser`\), which provides -server implementations of the DOM, `XMLHttpRequest`, and other low-level features that don't rely on a browser. - -The server \([Node.js Express](https://expressjs.com) in this guide's example\) passes client requests for application pages to the NgUniversal `ngExpressEngine`. -Under the hood, the engine renders the app, while also providing caching and other helpful utilities. - -The render function takes as inputs a *template* HTML page \(usually `index.html`\), and an Angular *module* containing components. Alternatively, it can take a function that when invoked returns a `Promise` that resolves to an `ApplicationRef`, and a *route* that determines which components to display. The route comes from the client's request to the server. - -Each request results in the appropriate view for the requested route. -The render function renders the view within the `` tag of the template, creating a finished HTML page for the client. - -Finally, the server returns the rendered page to the client. - -### Working around the browser APIs - -Because a Universal application doesn't execute in the browser, some of the browser APIs and capabilities might be missing on the server. - -For example, server-side applications can't reference browser-only global objects such as `window`, `document`, `navigator`, or `location`. - -Angular provides some injectable abstractions over these objects, such as [`Location`](api/common/Location) or [`DOCUMENT`](api/common/DOCUMENT); it might substitute adequately for these APIs. -If Angular doesn't provide it, it's possible to write new abstractions that delegate to the browser APIs while in the browser and to an alternative implementation while on the server \(also known as shimming\). - -Similarly, without mouse or keyboard events, a server-side application can't rely on a user clicking a button to show a component. -The application must determine what to render based solely on the incoming client request. -This is a good argument for making the application [routable](guide/router). - - -### Universal and the Angular Service Worker - -If you are using Universal in conjunction with the Angular service worker, the behavior is different than the normal server side rendering behavior. The initial server request will be rendered on the server as expected. However, after that initial request, subsequent requests are handled by the service worker. For subsequent requests, the `index.html` file is served statically and bypasses server side rendering. - - - -### Universal template engine - -The important bit in the `server.ts` file is the `ngExpressEngine()` function. - - - -The `ngExpressEngine()` function is a wrapper around the Angular `platform-server` package [`renderModule`](api/platform-server/renderModule) and [`renderApplication`](api/platform-server/renderApplication) functions which turns a client's requests into server-rendered HTML pages. - -It accepts an object with the following properties: - -| Properties | Details | -|:--- |:--- | -| `bootstrap` | The root `NgModule` or function that when invoked returns a `Promise` that resolves to an `ApplicationRef` of the application when rendering on the server. For the example application, it is `AppServerModule`. It's the bridge between the Universal server-side renderer and the Angular application. | -| `extraProviders` | This property is optional and lets you specify dependency providers that apply only when rendering the application on the server. Do this when your application needs information that can only be determined by the currently running server instance. | - -The `ngExpressEngine()` function returns a `Promise` callback that resolves to the rendered page. -It's up to the engine to decide what to do with that page. -This engine's `Promise` callback returns the rendered page to the web server, which then forwards it to the client in the HTTP response. - -### Filtering request URLs - -
- -**NOTE**:
-The basic behavior described below is handled automatically when using the NgUniversal Express package. -This is helpful when trying to understand the underlying behavior or replicate it without using the package. - -
- -The web server must distinguish *app page requests* from other kinds of requests. - -It's not as simple as intercepting a request to the root address `/`. -The browser could ask for one of the application routes such as `/dashboard`, `/heroes`, or `/detail:12`. -In fact, if the application were only rendered by the server, *every* application link clicked would arrive at the server as a navigation URL intended for the router. - -Fortunately, application routes have something in common: their URLs lack file extensions. -\(Data requests also lack extensions but they can be recognized because they always begin with `/api`.\) -All static asset requests have a file extension \(such as `main.js` or `/node_modules/zone.js/bundles/zone.umd.js`\). - -Because you use routing, you can recognize the three types of requests and handle them differently. - -| Routing request types | Details | -|:--- |:--- | -| Data request | Request URL that begins `/api` | -| App navigation | Request URL with no file extension | -| Static asset | All other requests | - -A Node.js Express server is a pipeline of middleware that filters and processes requests one after the other. -You configure the Node.js Express server pipeline with calls to `server.get()` like this one for data requests: - - - -
- -**NOTE**:
-This sample server doesn't handle data requests. - -The tutorial's "in-memory web API" module, a demo and development tool, intercepts all HTTP calls and simulates the behavior of a remote data server. -In practice, you would remove that module and register your web API middleware on the server here. - -
- -The following code filters for request URLs with no extensions and treats them as navigation requests: - - - -### Serving static files safely - -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 the `/dist` folder and only honor requests for files from the `/dist` folder. - -The following Node.js Express code routes all remaining requests to `/dist`, and returns a `404 - NOT FOUND` error if the -file isn't found. - - - -### Using absolute URLs for HTTP (data) requests on the server - -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`. -In a server-side rendered app, HTTP URLs must be *absolute* \(for example, `https://my-server.com/api/heroes`\). -This means that the URLs must be somehow converted to absolute when running on the server and be left relative when running in the browser. - -If you are using one of the `@nguniversal/*-engine` packages \(such as `@nguniversal/express-engine`\), this is taken care for you automatically. -You don't need to do anything to make relative URLs work on the server. - -If, for some reason, you are not using an `@nguniversal/*-engine` package, you might need to handle it yourself. - -The recommended solution is to pass the full request URL to the `options` argument of [renderModule](api/platform-server/renderModule). -This option is the least intrusive as it does not require any changes to the application. -Here, "request URL" refers to the URL of the request as a response to which the application is being rendered on the server. -For example, if the client requested `https://my-server.com/dashboard` and you are rendering the application on the server to respond to that request, `options.url` should be set to `https://my-server.com/dashboard`. - -Now, on every HTTP request made as part of rendering the application on the server, Angular can correctly resolve the request URL to an absolute URL, using the provided `options.url`. - -### Useful scripts - -| Scripts | Details | -|:--- |:--- | -| npm run dev:ssr | Similar to [`ng serve`](cli/serve), which offers live reload during development, but uses server-side rendering. The application runs in watch mode and refreshes the browser after every change. This command is slower than the actual `ng serve` command. | -| ng build && ng run app-name:server | Builds both the server script and the application in production mode. Use this command when you want to build the project for deployment. | -| npm run serve:ssr | Starts the server script for serving the application locally with server-side rendering. It uses the build artifacts created by `npm run build:ssr`, so make sure you have run that command as well.
**NOTE**:
`serve:ssr` is not intended to be used to serve your application in production, but only for testing the server-side rendered application locally.
| -| npm run prerender | Used to prerender an application's pages. Read more about prerendering [here](guide/prerendering). | - - - - - - - -@reviewed 2023-06-21 diff --git a/aio-ja/content/guide/universal.md b/aio-ja/content/guide/universal.md deleted file mode 100644 index 1a4232815..000000000 --- a/aio-ja/content/guide/universal.md +++ /dev/null @@ -1,372 +0,0 @@ -# Angular Universal を使ったサーバーサイドレンダリング (SSR) - -このガイドでは、Angular アプリケーションをサーバー上でレンダリングするテクノロジーである **Angular Universal** について説明します。 - -デフォルトでは、Angularはアプリケーションを*ブラウザー*でのみレンダリングします。Angular Universalでは、Angularが*サーバー*上でアプリケーションをレンダリングし、アプリケーションの状態を表す*静的な*HTMLコンテンツを生成します。HTMLコンテンツがブラウザでレンダリングされると、Angularはアプリケーションをブートストラップし、サーバーで生成されたHTMLにある情報を再利用します。 - -サーバーサイドレンダリングでは、一般にアプリケーションはブラウザでより速く描画され、ユーザーはアプリケーションのUIを完全にインタラクティブになる前に確認することができます。詳しくは、次の [サーバーサイドレンダリングを使用する理由](#why-do-it) をご覧ください。 - -また、SSRをめぐるさまざまなテクニックやコンセプトについては、こちらの[記事](https://developers.google.com/web/updates/2019/02/rendering-on-the-web)をご覧ください。 - -次のように、`@nguniversal/express-engine` パッケージを使用して、Angularアプリケーションでサーバーサイドレンダリングを有効にすることができます。 - -
- - Angular Universal requires an [active LTS or maintenance LTS](https://nodejs.org/about/releases) version of Node.js. - For information see the [version compatibility](guide/versions) guide to learn about the currently supported versions. - -
- - - -## Universal チュートリアル - -[Tour of Heroes チュートリアル](tutorial/tour-of-heroes) は、このチュートリアルの基礎です。 - -この例では、Angular CLI は [Ahead-of-Time (AOT) コンパイラー](guide/aot-compiler)を使用してアプリケーションの Universal バージョンをコンパイルおよびバンドルします。 -Node.js Express Web サーバーは、クライアント要求に基づいて、Universal で HTML ページをコンパイルします。 - -
- -Download the finished sample code, which runs in a [Node.js® Express](https://expressjs.com) server. - -
- -### Step 1. Enable Server-Side Rendering - -Run the following command to add SSR support into your application: - - - -ng add @nguniversal/express-engine - - - -The command updates the application code to enable SSR and adds extra files to the project structure (files that are marked with the `*` symbol). - -
-
- src -
-
-
- index.html                             // <-- app web page -
-
- main.ts                                  // <-- bootstrapper for client app -
-
- main.server.ts                       // <-- * bootstrapper for server app -
-
- style.css                                // <-- styles for the app -
-
- app/  …                                   // <-- application code -
-
-
- app.config.ts                   // <-- client-side application configuration (standalone app only) -
-
- app.module.ts                 // <-- client-side application module (NgModule app only) -
-
-
-
- app.config.server.ts       // <-- * server-side application configuration (standalone app only) -
-
- app.module.server.ts     // <-- * server-side application module (NgModule app only) -
-
-
- server.ts                                // <-- * express web server -
-
- tsconfig.json                        // <-- TypeScript base configuration -
-
- tsconfig.app.json                // <-- TypeScript browser application configuration -
-
- tsconfig.server.json            // <-- TypeScript server application configuration -
-
- tsconfig.spec.json              // <-- TypeScript tests configuration -
-
-
- -### Step 2. Enable Client Hydration - -
- -The hydration feature is available for [developer preview](/guide/releases#developer-preview). It's ready for you to try, but it might change before it is stable. - -
- -Hydration is the process that restores the server side rendered application on the client. This includes things like reusing the server rendered DOM structures, persisting the application state, transferring application data that was retrieved already by the server, and other processes. Learn more about hydration in [this guide](guide/hydration). - -You can enable hydration by updating the `app.module.ts` file. Import the `provideClientHydration` function from `@angular/platform-browser` and add the function call to the `providers` section of the `AppModule` as shown below. - -```typescript -import {provideClientHydration} from '@angular/platform-browser'; -// ... - -@NgModule({ - // ... - providers: [ provideClientHydration() ], // add this line - bootstrap: [ AppComponent ] -}) -export class AppModule { - // ... -} -``` - -### Step 3. Start the server - -ローカルシステムで Universal を使用してアプリケーションのレンダリングを開始するには、次のコマンドを使用します。 - - - -npm run dev:ssr - - - -### Step 4. Run your application in a browser - -Webサーバーが起動したら、ブラウザを開いて`http://localhost:4200`に移動します。 -おなじみの Tour of Heroes ダッシュボードページが表示されます。 - -`routerLinks` を介したナビゲーションは組み込みのアンカー (``) タグを使用するため、正常に機能します。 -ダッシュボードからヒーローページに遷移して戻ることができます。 -ダッシュボードページでヒーローをクリックすると、その詳細ページが表示されます。 - -クライアント側のスクリプトのダウンロードに時間がかかるように (次の手順) ネットワーク速度を調整する場合、 -次のことに気づくでしょう: -* ヒーローを追加または削除することはできません。 -* ダッシュボードページの検索ボックスは無視されます。 -* 詳細ページの *戻る* ボタンと *保存* ボタンは機能しません。 - -サーバーレンダリングされたアプリケーションからクライアントアプリケーションへの移行は開発マシンで迅速に行われますが、 -実際のシナリオでは常にアプリケーションをテストする必要があります。 - -遅いネットワークをシミュレートして、次のように移行をより明確に確認できます: - -1. Chrome Dev Tools を開き、ネットワークタブに移動します。 -1. メニューバーの右端にある [Network Throttling](https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#throttling) -ドロップダウンを見つけます。 -1. "3G" 速度のいずれかを試します。 - -サーバーレンダリングされたアプリケーションは引き続き迅速に起動しますが、完全なクライアントアプリケーションの読み込みには数秒かかる場合があります。 - - - -## サーバーサイドレンダリングを使用する理由 - -アプリケーションの Universal バージョンを作成する主な理由は3つあります。 - -1. [検索エンジン最適化 (SEO)](https://support.google.com/webmasters/answer/7451184?hl=ja)による Web クローラーの促進 -1. モバイルおよび非力なデバイスのパフォーマンスを改善する -1. [first-contentful paint (FCP)](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint) で最初のページをすばやく表示します - -{@a seo} -{@a web-crawlers} -### Web クローラーを促進する (SEO) - -Google、Bing、Facebook、Twitter、およびその他のソーシャルメディアサイトは、Web クローラーに依存してアプリケーションコンテンツのインデックスを作成し、 -そのコンテンツを Web 上で検索可能にします。 -これらの Web クローラーは、人間のユーザーのように、高度にインタラクティブな Angular アプリケーションをナビゲートおよびインデックス化できない場合があります。 - -Angular Universal は、JavaScript なしで簡単に検索、リンク、ナビゲートできるアプリケーションの静的バージョンを生成できます。また、Universal は、各 URL が完全にレンダリングされたページを返すため、サイトプレビューを利用可能にします。 - -{@a no-javascript} -### モバイルおよび非力なデバイスのパフォーマンスを改善する - -一部のデバイスはJavaScriptをサポートしていないか、JavaScriptの実行が不十分であるため、 -そのユーザー体験は受け入れがたいものです。 -このような場合、サーバーレンダリングされたJavaScriptなしのアプリケーションが必要になる場合があります。 -このバージョンは、制限はありますが、アプリケーションをまったく使用できなかった場合の唯一の実用的な代替手段になる可能性があります。 - -{@a startup-performance} -### 最初のページをすばやく表示する - -最初のページをすばやく表示することは、ユーザーエンゲージメントにとって重要です。 -読み込みが高速なページは、[100ミリ秒の小さな変更でも](https://web.dev/shopping-for-speed-on-ebay/)パフォーマンスが向上します。 -これらのユーザーが何か他のことをする前にエンゲージするには、アプリケーションの起動を高速化する必要があります。 - -Angular Universal を使用すると、完全なアプリケーションのように見えるアプリケーションのランディングページを生成できます。 -ページは純粋な HTML であり、JavaScript が無効になっていても表示できます。 -ページはブラウザイベントを処理しませんが、[`routerLink`](guide/router-reference#router-link) を使用してサイト内のナビゲーションをサポート _します_ 。 - -実際には、静的バージョンのランディングページを提供して、ユーザーの注意を引き付けます。 -同時に、その背後にある完全な Angular アプリケーションをロードします。 -ユーザーは、ランディングページからほぼ瞬時のパフォーマンスを認識し、 -アプリケーションが完全に読み込まれた後、完全なインタラクティブエクスペリエンスを取得します。 - -{@a how-does-it-work} -## Universal Web サーバー - -Universal Web サーバーは、[Universal テンプレートエンジン](#universal-engine)によってレンダリングされた静的 HTML でアプリケーションページリクエストに応答します。 -サーバーは、クライアント (通常はブラウザ) から HTTP リクエストを受信して応答し、スクリプト、CSS、画像などの静的アセットを提供します。 -データリクエストに、直接または別のデータサーバーへのプロキシとして応答する場合があります。 - -このガイドのサンプル Web サーバーは、一般的な [Express](https://expressjs.com/) フレームワークに基づいています。 - -
- -**NOTE**:
-*Any* web server technology can serve a Universal application as long as it can call Angular `platform-server` package [`renderModule`](api/platform-server/renderModule) or [`renderApplication`](api/platform-server/renderApplication) functions. -ここで説明する原則と決定事項は、すべての Web サーバーテクノロジーに適用されます。 - -
- -ユニバーサルアプリケーションは、Angular `platform-server` パッケージ (`platform-browser` ではなく) を使用します。 -これは、DOM、`XMLHttpRequest`、およびブラウザに依存しないその他の低レベル機能のサーバー実装を提供します。 - -サーバー (このガイドの例では [Node.js Express](https://expressjs.com/)) は、アプリケーションページのクライアントリクエストを NgUniversal の `ngExpressEngine` に渡します。 -裏側では、このエンジンがアプリケーションをレンダリングし、キャッシュやその他の便利なユーティリティも提供します。 - -render関数は、*テンプレート*となるHTMLページ(通常は`index.html`)と、コンポーネントを含むAngularの*モジュール*を入力として受け取ります。あるいは、呼び出されたときに `ApplicationRef` に解決される`Promise`を返す関数と、どのコンポーネントを表示するかを決定する*ルート*を受け取ることもできます。ルートはクライアントからサーバーへのリクエストに基づきます。 - -各リクエストの結果、リクエストされたルートの適切なビューが表示されます。 -render 関数は、テンプレートの `` タグ内でビューをレンダリングし、 -クライアント用の完成した HTML ページを作成します。 - -最後に、サーバーはレンダリングされたページをクライアントに返します。 - -### ブラウザ API の回避 - -ユニバーサルアプリケーションはブラウザで実行されないため、ブラウザ API と機能の一部がサーバー上にない場合があります。 - -たとえば、サーバー側のアプリケーションは、`window`、`document`、`navigator`、`location` などのブラウザのみのグローバルオブジェクトを参照できません。 - -Angular は、[`Location`](api/common/Location) や [`DOCUMENT`](api/common/DOCUMENT) など、 -これらのオブジェクトに対して注入可能な抽象化を提供します。 -これらの API を適切に置き換えることができます。 -Angular がそれを提供しない場合、ブラウザ内ではブラウザ API に委任し、サーバー上では別名実装 (別名シミング) に委任する新しい抽象化を記述することができます。 - -同様に、マウスまたはキーボードイベントがない場合、サーバーサイドアプリケーションは、ユーザーがボタンをクリックしてコンポーネントを表示することに依存できません。 -アプリケーションは、受信するクライアントリクエストのみに基づいてレンダリングするものを決定する必要があります。 -これは、アプリケーションを[ルーティング可能](guide/router)にするためのよい議論です。 - - -### Universal and the Angular Service Worker - -If you are using Universal in conjunction with the Angular service worker, the behavior is different than the normal server side rendering behavior. The initial server request will be rendered on the server as expected. However, after that initial request, subsequent requests are handled by the service worker. For subsequent requests, the `index.html` file is served statically and bypasses server side rendering. - - - -### Universal テンプレートエンジン - -`server.ts` ファイルの重要な部分は `ngExpressEngine()` 関数です。 - - - - -The `ngExpressEngine()` function is a wrapper around the Angular `platform-server` package [`renderModule`](api/platform-server/renderModule) and [`renderApplication`](api/platform-server/renderApplication) functions which turns a client's requests into server-rendered HTML pages. - -| Properties | Details | -|:--- |:--- | -| `bootstrap` | The root `NgModule` or function that when invoked returns a `Promise` that resolves to an `ApplicationRef` of the application when rendering on the server. For the example application, it is `AppServerModule`. It's the bridge between the Universal server-side renderer and the Angular application. | -| `extraProviders` | This property is optional and lets you specify dependency providers that apply only when rendering the application on the server. Do this when your application needs information that can only be determined by the currently running server instance. | - -`ngExpressEngine()` 関数は、レンダリングされたページに解決される `Promise` コールバックを返します。 -そのページをどう処理するかはエンジン次第です。 -このエンジンの `Promise` コールバックは、レンダリングされたページを Web サーバーに返し、Web サーバーはそれを HTTP レスポンスでクライアントに転送します。 - -### リクエスト URL のフィルタリング - -
- -**NOTE**:
-メモ: NgUniversal Expressパッケージを使用すると、次に説明する基本的な動作が自動的に処理されます。 -これは、基本的な動作を理解したり、パッケージを使用せずに複製したりするときに役立ちます。 - -
- -Web サーバーは、_アプリのページのリクエスト_ を他の種類のリクエストと区別する必要があります。 - -ルートアドレス `/` へのリクエストをインターセプトするほど簡単ではありません。 -ブラウザは、`/dashboard`、`/heroes`、`/detail:12` などのアプリケーションルートのいずれかをリクエストできます。 -実際、アプリケーションがサーバーによってのみレンダリングされた場合、 -クリックされた _すべての_ アプリケーションリンクは、ルーター向けのナビゲーション URL としてサーバーに到達します。 - -幸いなことに、アプリケーションルートには共通点があります。URL にはファイル拡張子がありません。 -(データリクエストにも拡張子はありませんが、常に `/api` で始まるため、簡単に認識できます。) -すべての静的アセットリクエストには (`main.js` や `/node_modules/zone.js/bundles/zone.umd.js` など) ファイル拡張子があります。 - -ルーティングを使用するため、3種類のリクエストを簡単に認識して、異なる方法で処理できます。 - -1. **データリクエスト**: `/api` で始まるリクエスト URL -1. **アプリケーションのナビゲーション**: ファイル拡張子のないリクエスト URL -1. **静的アセット**: 他のすべてのリクエスト - -Node.js Express サーバーは、リクエストを次々にフィルタリングして処理するミドルウェアのパイプラインです。 -Node.js Express サーバーパイプラインは、データリクエスト用にこのような `app.get()` の呼び出しで構成します。 - - - -
- - **メモ:** このサンプルサーバーはデータリクエストを処理しません。 - - チュートリアルの「インメモリ Web API」モジュールであるデモおよび開発ツールは、 - すべての HTTP 呼び出しをインターセプトし、リモートデータサーバーの動作をシミュレートします。 - 実際には、このモジュールを削除して、Web API ミドルウェアをサーバーに登録します。 - -
- -次のコードは、拡張子のないリクエスト URL をフィルタリングし、それらをナビゲーションリクエストとして扱います。 - - - -### 静的ファイルを安全に提供する - -単一の `server.use()` は、他のすべての URL を -JavaScript、画像、スタイルファイルなどの静的アセットのリクエストとして扱います。 - -クライアントが表示が許可されているファイルのみをダウンロードできるようにするには、すべてのクライアント向けアセットファイルを `/dist` フォルダーに入れ、 -`/dist` フォルダーからのファイルのリクエストのみを受け入れます。 - -次の Node.js Express コードは、残りのすべてのリクエストを `/dist` にルーティングし、 -ファイルが見つからない場合は `404 - NOT FOUND` エラーを返します。 - - - -### Using absolute URLs for HTTP (data) requests on the server - -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`. -In a server-side rendered app, HTTP URLs must be _absolute_ (for example, `https://my-server.com/api/heroes`). -This means that the URLs must be somehow converted to absolute when running on the server and be left relative when running in the browser. - -If you are using one of the `@nguniversal/*-engine` packages (such as `@nguniversal/express-engine`), this is taken care for you automatically. -You don't need to do anything to make relative URLs work on the server. - -If, for some reason, you are not using an `@nguniversal/*-engine` package, you may need to handle it yourself. - -The recommended solution is to pass the full request URL to the `options` argument of [renderModule](api/platform-server/renderModule). -This option is the least intrusive as it does not require any changes to the app. -Here, "request URL" refers to the URL of the request as a response to which the app is being rendered on the server. -For example, if the client requested `https://my-server.com/dashboard` and you are rendering the app on the server to respond to that request, `options.url` should be set to `https://my-server.com/dashboard`. - -Now, on every HTTP request made as part of rendering the app on the server, Angular can correctly resolve the request URL to an absolute URL, using the provided `options.url`. - -### Useful scripts - -| Scripts | Details | -|:--- |:--- | -| npm run dev:ssr | Similar to [`ng serve`](cli/serve), which offers live reload during development, but uses server-side rendering. The application runs in watch mode and refreshes the browser after every change. This command is slower than the actual `ng serve` command. | -| ng build && ng run app-name:server | Builds both the server script and the application in production mode. Use this command when you want to build the project for deployment. | -| npm run serve:ssr | Starts the server script for serving the application locally with server-side rendering. It uses the build artifacts created by `npm run build:ssr`, so make sure you have run that command as well.
**NOTE**:
`serve:ssr` is not intended to be used to serve your application in production, but only for testing the server-side rendered application locally.
| -| npm run prerender | Used to prerender an application's pages. Read more about prerendering [here](guide/prerendering). | - - - - - - - -@reviewed 2023-06-21 \ No newline at end of file diff --git a/aio-ja/content/guide/universal.md.old b/aio-ja/content/guide/universal.md.old deleted file mode 100644 index 5f5a0d0b9..000000000 --- a/aio-ja/content/guide/universal.md.old +++ /dev/null @@ -1,532 +0,0 @@ -# Angular Universal: サーバーサイドレンダリング - -このガイドでは、サーバー上でAngularアプリケーションを実行する技術である**Angular Universal**について説明します。 - -通常のAngularアプリケーションは、_ブラウザー_ 上で実行され、ユーザーアクションに応じてDOM内のページをレンダリングします。 - -**Angular Universal**は**server-side rendering(SSR)**と呼ばれるプロセスを通じて、_サーバー_ 上に _静的な_ アプリケーションページを生成します。 - -ブラウザからのリクエストに応じて、これらのページを生成し配信することができます。また後に配信するHTMLファイルとして、ページを事前に生成することもできます。 - -このガイドでは、サーバーレンダリングされたページとしてすぐに起動するUniversalアプリケーションのサンプルについて説明します。その過程において、ブラウザは完全なクライアントバージョンをダウンロードし、コードがロードされた後自動でそれに切り替わります。 - -
- -[Node.js® express](https://expressjs.com/)サーバーで動作する[サンプルコードの完成形をダウンロード](generated/zips/universal/universal.zip)してください。 - -
- -{@a why-do-it} - -### なぜUniversalが必要なのか - -アプリケーションのUniversalバージョンを作成する主な理由は3つあります。 - -1. Webクローラーを支援する(SEO) -1. モバイルおよび低スペックデバイスのパフォーマンスを向上させる -1. 最初のページを素早く表示する - -{@a seo} -{@a web-crawlers} - -#### Webクローラーを支援する - -Google、Bing、Facebook、Twitterなどのソーシャルメディアサイトは、Webクローラーに依存してアプリケーションコンテンツのインデックスを作成し、そのコンテンツをWeb上で検索可能にします。 - -これらのWebクローラーは、高度にインタラクティブなAngularアプリケーションをユーザーと同様に操作してインデックス化できないかもしれません。 - -Angular Universalは、JavaScriptなしで簡単に検索、リンク、ナビゲートできる静的バージョンのアプリケーションを生成できます。また、各URLは完全にレンダリングされたページを返すため、サイトのプレビューも利用可能となります。 - -Webクローラーの有効化は、よく[Search Engine Optimization(SEO)](https://static.googleusercontent.com/media/www.google.com/en//webmasters/docs/search-engine-optimization-starter-guide.pdf)と呼ばれます。 - -{@a no-javascript} - -### モバイルおよび低スペックデバイスのパフォーマンス - -一部の端末ではJavaScriptをサポートしていないか、ユーザー体験が容認できないほどにJavaScriptの実行が不完全です。 - -このような場合、サーバー側でレンダリングされたJavaScript未使用バージョンのアプリケーションが必要になることがあります。そのバージョンを使用するケースはそう多くありませんが、このアプリケーションをまったく利用できない人々のための唯一の実用的な代替手段になるかもしれません。 - -{@a startup-performance} - -### 最初のページを素早く表示する - -最初のページを素早く表示することは、ユーザーエンゲージメントの面で非常に重要です。 - -ページの表示に3秒以上かかる場合、[モバイルサイト訪問者の53%が離脱しました](https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/)。あなたのアプリケーションは、ユーザーの気が散る前に引き止めるため、より早く立ち上げる必要があります。 - -Angular Universalを使用すると、完全なアプリケーションのようなランディングページを生成できます。このページは純粋なHTMLであり、JavaScriptが無効になっていても表示できます。このページはブラウザイベントを処理しませんが、[routerLink](guide/router#router-link)を使用して、サイトを介したナビゲーションをサポートします。 - -実際には、ランディングページの静的バージョンを配信し、ユーザーの注意を引きつけます。同時に[以下に説明する方法](#transition)で、バックグラウンドに完全なAngularアプリケーションを読み込みます。ユーザーはこのランディングページから即時的なパフォーマンスを体験し、アプリケーションが完全に読み込まれた後、インタラクティブな体験を得ることができます。 - -{@a how-does-it-work} - -### 動作の仕組み - -Universalアプリケーションを作成するには、`platform-server`パッケージをインストールします。 -`platform-server`パッケージには、DOMや`XMLHttpRequest`のサーバー実装、そしてブラウザに依存しないその他の低レイヤー機能が含まれています。 - -クライアントアプリケーションを`platform-browser`モジュールの代わりに`platform-server`モジュールでコンパイルします。結果として得られるUniversalアプリケーションをWebサーバーで実行します。 - -サーバー(_この_ ガイドの例では[Node Express](https://expressjs.com/))は、アプリケーションページからのクライアントリクエストをUniversalの`renderModuleFactory`関数に渡します。 - -`renderModuleFactory`関数は、*template* HTMLページ(通常は`index.html`)、コンポーネントを含むAngular *module*、そしてどのコンポーネントを表示するか決定する*ルート*を入力として受け取ります。 - -そのルートは、クライアントのサーバーへのリクエストから発生します。各リクエストは、要求されたルートの適切なビューをもたらします。 - -`renderModuleFactory`はテンプレートの``タグ内でそのビューをレンダリングし、クライアント用の最終的なHTMLページを作成します。 - -最後に、サーバーはレンダリングされたページをクライアントに返します。 - -### ブラウザAPIの回避策 - -Universalな`platform-server`アプリケーションはブラウザ上で実行されないため、サーバー上に存在しないいくつかのブラウザAPIと機能を回避する必要があります。 - -`window`、`document`、`navigator`や`location`のようなブラウザ専用のネイティブオブジェクトは参照できません。サーバーレンダリングされたページでそれらを必要としない場合は、条件付きロジックで回避します。 - -あるいは、`Location`や`Document`など必要なオブジェクトに対して注入可能なAngularの抽象を探します。あなたが使用している特定のAPIを適切に置き換えることができるかもしれません。 -Angularがそれを提供していない場合、ブラウザ上でブラウザAPIに委譲し、サーバー上では十分な代替機能を提供するための独自抽象処理を書くことができるかもしれません。 - -マウスやキーボードのイベントがなければ、Universalアプリケーションはコンポーネントを表示するためにユーザーのボタンクリックを頼ることはできません。Universalアプリケーションは、受信したクライアントリクエストのみに基づき、何をレンダリングするか決定する必要があります。これは、アプリケーションを[ルーティング可能](guide/router)とするために十分な情報です。 - -サーバーレンダリングされたページのユーザーはリンクをクリックする以上のことはできないため、本来のインタラクティブな体験を得るためにできるだけ早く[実際のクライアントアプリへ移行](#transition)する必要があります。 - -{@a the-example} - -## 例 - -_Tour of Heroes_チュートリアルは、このガイドで説明しているUniversalサンプルのベースです。 - -コアとなるアプリケーションファイルはほとんど変更されていませんが、次に説明するいくつかの例外があります。 -Universalを使用してビルドおよび配信をサポートするファイルを追加しましょう。 - -この例では、Angular CLIが、アプリケーションのUniversalバージョンを[AOT(Ahead-of-Time)コンパイラー](guide/aot-compiler)でコンパイルして一纏めにします。 -Node.js® Express Webサーバーは、クライアントリクエストをUniversalによってレンダリングされたHTMLページへ変換します。 - -次のファイルを生成しましょう: - -* サーバーサイドのアプリケーションモジュール、`app.server.module.ts` -* サーバー側のエントリーポイント、`main.server.ts` -* リクエストを処理するためのexpress webサーバー、`server.ts` -* TypeScriptの設定ファイル、`tsconfig.server.json` -* サーバー用のWebpack設定ファイル、`webpack.server.config.js` - -完了後、フォルダー構造は次のようになります: - - -src/ - index.html アプリケーションのwebページ - main.ts クライアント用の初期化処理 - main.server.ts * サーバー用の初期化処理 - tsconfig.app.json クライアント用のTypeScript設定 - tsconfig.server.json * サーバー用のTypeScript設定 - tsconfig.spec.json テスト用のTypeScript設定 - style.css アプリケーションのスタイル - app/ ... アプリケーションコード - app.server.module.ts * サーバー用のアプリケーションモジュール -server.ts * express webサーバー -tsconfig.json クライアント用のTypeScript設定 -package.json npmの設定 -webpack.server.config.js * サーバー用のWebpack設定 - - -`*`マークがついているファイルは新規に作成するもので、元のチュートリアルサンプルには含まれていません。このガイドでは、それらを次のセクションで説明します。 - -{@a preparation} - -## 準備 - -[Tour of Heroes](generated/zips/toh-pt6/toh-pt6.zip)プロジェクトをダウンロードし、そこから依存パッケージをインストールしてください。 - -{@a install-the-tools} - -### ツールのインストール - -はじめに、これらのパッケージをインストールします。 - -* `@angular/platform-server` - Universalサーバーサイドコンポーネント -* `@nguniversal/module-map-ngfactory-loader` - サーバーレンダリング環境下で遅延読み込みを処理するため -* `@nguniversal/express-engine` - Universalアプリケーション用のexpressエンジン -* `ts-loader` - サーバーアプリケーションをトランスパイルするため - -下記コマンドでそれらをインストールしましょう: - - -npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine - - -{@a transition} - -## クライアントアプリケーションの編集 - -Universalアプリケーションは、動的でユーザーを引き付けるコンテンツ満載の"スプラッシュ画面"として機能します。それは、ほぼ瞬間的にアプリケーションの外観を提供します。 - -その間、ブラウザはバックグラウンドでクライアントアプリケーションのスクリプトをダウンロードします。ロードが終わると、Angularはサーバー側でレンダリングされた静的なページから、動的にレンダリングされたインタラクティブなクライアントアプリケーションのビューに移行します。 - -サーバー側のレンダリングとクライアントアプリケーションへの移行を共にサポートするためには、アプリケーションのコードを少し変更する必要があります。 - -{@a root-app-module} - -### ルート`AppModule` - -`src/app/app.module.ts`を開き、`NgModule`のメタデータ内で`BrowserModule`インポートを探します。そのインポートを次の内容へ置き換えます: - - - - -Angularは、サーバーでレンダリングされたページのスタイル名に`appId`値(_何らかの_ 文字列)を追加するため、クライアントアプリケーションの起動時にそれらを識別して削除することができます。 - -現在のプラットホームと`appId`についての実行情報は注入によって取得することができます。 - - - - -{@a cli-output} - -### ビルド出力先 - -ユニバーサルアプリケーションは、最初のアプリケーションを処理するサーバー側のコードと、動的にロードされるクライアント側のコードの2つの部分に分かれています。 - -Angular CLIは、デフォルトでは`dist`ディレクトリにクライアント側のコードを出力するので、クライアント側のビルド出力をサーバー側のコードとは別に保存するために、`angular.json`内の __build__ ターゲットの `outputPath`を変更してください。クライアント側ビルド出力は、Expressサーバーによって提供されます。 - -``` -... -"build": { - "builder": "@angular-devkit/build-angular:browser", - "options": { - "outputPath": "dist/browser", - ... - } -} -... -``` - -{@a http-urls} - -### HTTPリクエストの絶対URL - -このチュートリアルの`HeroService`と`HeroSearchService`は、アプリケーションデータの取得をAngularの`HttpClient`モジュールに委譲します。これらのサービスは、`api/heroes`などの _相対_ URLにリクエストを送信します。 - -UniversalアプリケーションにおいてHTTPのURLは、Universal webサーバーがこれらのリクエストを扱える場合でも、たとえば`https://my-server.com/api/heroes`のような _絶対_ パスでなければなりません。 - -サーバーで実行している際は絶対URLで、ブラウザで実行している場合は相対URLをリクエストするように、それらのサービスを変更する必要があります。 - -解決策の1つは、Angularの[`APP_BASE_HREF`トークン](api/common/APP_BASE_HREF)を介してサーバー実行時のオリジンを提供してそれをサービスに注入し、リクエストURLにオリジンを付与することです。 - -まず、`APP_BASE_HREF`トークンを介してオプションで注入された第2引数である`origin`パラメーターを取得するように、`HeroService`のコンストラクターを変更します。 - - - - -コンストラクターが`heroesUrl`に対して、(もし存在すれば)オリジンをどのように付与するかに注目してください。 - -ブラウザバージョンでは`APP_BASE_HREF`を提供しないので、`heroesUrl`は相対的なままです。 - -
- -チュートリアルのサンプルで行うように、`index.html`でルーターのベースアドレスを決定するため``を指定している場合、ブラウザで`APP_BASE_HREF`を無視することができます。 - -
- -{@a server-code} - -## サーバー側のコード - -Angular Universalアプリケーションを実行するためには、クライアントリクエストを受け、レンダリングされたページを返すサーバーが必要です。 - -{@a app-server-module} - -### アプリケーションサーバーのモジュール - -アプリケーションサーバーのモジュールクラス(慣例的に`AppServerModule`と呼ばれています)は、Universalがアプリケーションとサーバーを仲介できるようにするために、アプリケーションのルートモジュール(`AppModule`)をラップしているAngularモジュールです。 -`AppServerModule`は、Universalアプリケーションとして動作している際にアプリケーションを初期化する方法をAngularに伝えます。 - -次の`AppServerModule`コードを使用し、`src/app/`ディレクトリーに`app.server.module.ts`ファイルを作成しましょう: - - - - -最初にクライアントアプリケーションの`AppModule`、Angular Universalの`ServerModule`そして`ModuleMapLoaderModule`をインポートしていることに注目してください。 - -`ModuleMapLoaderModule`は、ルートの遅延ロードを可能にするサーバー側のモジュールです。 - -これは、Universal環境下でアプリケーションを実行するために特定のプロバイダーを登録する場所でもあります。 - -{@a app-server-entry-point} - -### アプリケーションサーバーのエントリポイント - -`Angular CLI`は` AppServerModule`を使用してサーバー側のバンドルを構築します。 - -`src/`ディレクトリに`AppServerModule`をエクスポートする`main.server.ts`ファイルを作成します: - - - - -`main.server.ts`は後で`Angular CLI`の設定に `server`ターゲットを追加するために参照されます。 - -{@a web-server} - -### Universal webサーバー - -_Universal_ webサーバーは、[Universalテンプレートエンジン](#universal-engine)によってレンダリングされた静的HTMLを使用して、アプリケーションの _ページ_ リクエストに応答します。 - -クライアント(通常はブラウザ)からのHTTPリクエストを受信して応答します。それは、スクリプト、CSS、画像などの静的リソースを配信します。おそらく、直接または別のデータサーバーのプロキシとして、データのリクエストに応答するでしょう。 - -_この_ ガイドのサンプルwebサーバーは、一般的な[Express](https://expressjs.com/)フレームワークに基づいています。 - -
- -_何らかの_ webサーバー技術はUniversalの`renderModuleFactory`を呼び出せばUniversalアプリケーションを提供することができます。以下で説明する原則と意思決定のポイントは、選択したすべてのwebサーバー技術に当てはまります。 - -
- -ルートディレクトリーに`server.ts`ファイルを作成し、次のコードを追加しましょう: - - - - -
- -**このサンプルサーバーは安全ではありません!** -ミドルウェアを追加して、通常のAngularアプリケーションサーバーと同様に、認証およびユーザー認可を行ってください。 - -
- -{@a universal-engine} - -#### Universalテンプレートエンジン - -このファイルで重要なポイントは、`ngExpressEngine`関数です: - - - - -`ngExpressEngine`は、Universalにおける`renderModuleFactory`関数のラッパーで、クライアントのリクエストをサーバーレンダリングされたHTMLページへ変換します。 -_テンプレートエンジン_ 内では、サーバー処理に適した関数を呼び出します。 - -最初のパラメーターは、[先程](#app-server-module)書いた`AppServerModule`です。これは、Universalサーバー側のレンダリング処理とアプリケーション間を仲介します。 - -2番目のパラメーターは`extraProviders`です。これは任意で指定するAngularにおける依存性の注入を行うプロバイダーであり、サーバー側で実行する際に適用されます。 - -{@a provide-origin} - -アプリケーションが現在実行中のサーバーインスタンスによってのみ決定できる情報を必要とする際に`extraProviders`を指定します。 - -この場合に必要な情報は`APP_BASE_HREF`トークンの下で提供されている実行中サーバーのオリジンなので、アプリケーションは[HTTPリクエストの絶対URLを判断](#http-urls)することができます。 - -`ngExpressEngine`関数はレンダリングされたページを解決する _promise_ を返します。 - -そのページで何をするかはエンジン次第です。 -_このエンジンの_ promiseコールバックは、レンダリングされたページを[webサーバー](#web-server)へ返し、HTTPレスポンスとしてクライアントに転送します。 - -
- -このラッパーは`renderModuleFactory`の複雑さを隠蔽するという点で非常に有用です。この他にも、[Universalリポジトリー](https://github.com/angular/universal)には異なるバックエンド技術のためのラッパーが用意されています。 - -
- -#### リクエストURLのフィルター - -webサーバーは _アプリケーションページのリクエスト_ と他の種類のリクエストを区別する必要があります。 - -それは、ルートアドレス`/`に対するリクエストの傍受ほど簡単ではありません。ブラウザは、`/dashboard`、`/heroes`、`/detail:12`といったアプリケーションルートの1つを要求できます。実際に、アプリケーションがサーバーによって _のみ_ レンダリングされた場合、クリックされた _すべての_ アプリケーションリンクはルーター用のナビゲーションURLとしてサーバーに到達します。 - -幸いアプリケーションルートのURLには、ファイル拡張子が存在しないといった共通点があります。 - -データリクエストも拡張子がないですが、常に`/api`で始まるので簡単に認識できます。 - -すべての静的アセットリクエストにはファイル拡張子が存在します。(たとえば、`main.js`または`/node_modules/zone.js/dist/zone.js`) - -したがって、3タイプのリクエストを簡単に識別し、それらを別々に処理することができます。 - -1. データリクエスト - `/api`から始まるリクエストURL -2. アプリケーションのナビゲーション - ファイル拡張子のないリクエストURL -3. 静的アセット - 他すべてのリクエスト - -Expressサーバーは、URLリクエストを順次フィルタリングして処理するミドルウェアのパイプラインです。 - -データリクエストを行うため、このように`app.get()`を呼び出してExpressサーバーのパイプラインを設定しましょう。 - - - - -
- -このサンプルサーバーはデータのリクエストを処理しません。 - -このチュートリアルのデモおよび開発ツールである"in-memory web api"モジュールは、すべてのHTTPリクエストに割り込み、リモートデータサーバーの動作をシミュレートします。実際にはそのモジュールを削除し、サーバーのweb APIミドルウェアをここに登録します。 - -
- -
- -**Universal HTTPリクエストには異なるセキュリティー要件が存在します** - -ブラウザアプリケーションから生じたHTTPリクエストは、サーバー上のUniversalアプリケーションから生じたHTTPリクエストと同じではありません。 - -ブラウザがHTTPリクエストを行う際、サーバーはCookie、XSRFヘッダーなどが付与されていることを前提としています。 - -たとえば、ブラウザは現在のユーザー認証Cookieを自動的に送信します。 -Angular Universalはこれらの認証情報を別のデータサーバーに転送することはできません。サーバーがHTTPリクエストを処理する際、個々のセキュリティーに対する処理を追加する必要があります。 - -
- -次のコードは、拡張子のないリクエストのURLをフィルタリングし、ナビゲーションリクエストとして扱います。 - - - - -#### 静的ファイルを安全に配信する - -1つの`app.use()`を、他すべてのJavaScript、画像、およびstyleファイルの静的アセット用リクエストURLとして扱います。 - -クライアントに閲覧 _許可_ があるファイルのみをダウンロードさせるには、[すべてのクライアントアセットファイルを`/dist`フォルダーに配置](#universal-webpack-configuration)し、`/dist`フォルダーへのリクエストのみを許可してください。 - -次のexpressコードは、残りすべてのリクエストを`/dist`にルーティングし、ファイルが見つからない場合は`404 - NOT FOUND`を返します。 - - - - -{@a universal-configuration} - -## Universalの設定 - -サーバーアプリケーションには独自のビルド設定が必要です。 - -{@a universal-typescript-configuration} - -### UniversalのTypeScript設定 - -TypeScriptとUniversalアプリケーションのAOTコンパイルを設定するため、プロジェクトのルートディレクトリーに`tsconfig.server.json`ファイルを作成しましょう。 - - - - -この設定は、ルートディレクトリーの`tsconfig.json`ファイルから拡張されます。いくつかの設定の違いについて注目しましょう。 - -* `module`プロパティは、サーバーアプリケーションでrequire()することができる**commonjs**でなければなりません。 - -* `angularCompilerOptions`セクションはAOTコンパイラーをガイドします: - * `entryModule` - サーバーアプリケーションのルートモジュールであり、`path/to/file#ClassName`で表されます。 - -{@a universal-webpack-configuration} - -### UniversalのWebpack設定 - -Universalアプリケーションは、追加のWebpackの設定を一切必要とせず、Angular CLIがそういった設定を代行します。しかし、サーバーはtypescriptアプリケーションであるため、Webpackを使用してそれをトランスパイルします。 - -次のコードを使用して、プロジェクトのルートディレクトリーに`webpack.server.config.js`ファイルを作成します。 - - - - -**Webpackの設定**は、このガイドで扱う範囲を超えた情報量のトピックです。 - -{@a universal-cli-configuration} - -### Angular CLI設定 - -CLIは、さまざまなタイプの __ターゲット__ 用のビルダーを提供します。 `build`や`serve`のような一般的に知られているターゲットは `angular.json`設定ですでに存在しています。サーバーサイドビルドをターゲットにするには、 `server`ターゲットを`architect`設定オブジェクトに追加します。 - -* `outputPath`は、結果のビルドがどこで作成されるかを示します。 -* `main`は、前に作成した`main.server.ts`ファイルのメインエントリポイントを提供します。 -* `tsConfig`はTypeScriptとAOTのコンパイルのための設定として`tsconfig.server.json`を使います。 - -``` -"architect": { - ... - "server": { - "builder": "@angular-devkit/build-angular:server", - "options": { - "outputPath": "dist/server", - "main": "src/main.server.ts", - "tsConfig": "src/tsconfig.server.json" - } - } - ... -} -``` - -## Universalでビルドし実行する - -TypeScriptとWebpackの設定ファイルを作成し、Angular CLIを設定したので、Universalアプリケーションをビルドして実行できます。 - -まず、_build_ と _serve_ コマンドを`package.json`の`scripts`セクションに追加してください: - -``` -"scripts": { - ... - "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server", - "serve:ssr": "node dist/server", - "build:client-and-server-bundles": "ng build --prod && ng run angular.io-example:server", - "webpack:server": "webpack --config webpack.server.config.js --progress --colors" - ... -} -``` - -{@a build} - -#### ビルド - -コマンドプロンプトで下記コマンドを入力しましょう。 - - -npm run build:ssr - - -Angular CLIは、Universalアプリケーションを2つの異なるフォルダー、`browser`と`server`にコンパイルとバンドルを行います。 -Webpackは`server.ts`ファイルをJavaScriptにトランスパイルします。 - -{@a serve} - -#### 配信 - -アプリケーションをビルドしたら、サーバーを立ち上げましょう。 - - -npm run serve:ssr - - -コンソールウィンドウには、このように表示されるはずです。 - - -Node server listening on http://localhost:4000 - - -## Universalの挙動 - -http://localhost:4000/ でブラウザを開きましょう。お馴染みのTour of Heroesダッシュボードページが表示されるはずです。 - -`routerLinks`経由のナビゲーションは正しく動作します。ダッシュボードからヒーローリストのページに遷移し、戻ってくることができます。ダッシュボードページのヒーローをクリックすると、詳細ページが表示されます。 - -しかし、クリック、マウスの移動、そしてキーボード入力に対しては反応しません。 - -* ヒーローリストページのヒーローをクリックしても何も起こりません。 -* ヒーローを追加、または削除することはできません。 -* ダッシュボードページの検索ボックスは無反応です。 -* 詳細ページの _戻る_ および _保存_ ボタンは機能しません。 - -`routerLink`のクリック以外のユーザーイベントはサポートされていません。ユーザーは、完全なクライアントアプリケーションが使用可能となるまで待機する必要があります。 - -それはクライアントアプリケーションをコンパイルし、出力を`dist/`フォルダーに移動するまで使用可能となりません。 - -## スロットリング - -サーバーレンダリングされたアプリケーションからクライアントアプリケーションへの移行は、開発マシン上では迅速に行われます。遅いネットワークをシミュレートすると、移行をより明確に確認することができ、低スペックで接続が芳しくないデバイスで動作するUniversalアプリケーションの起動速度に対する優位性をより正しく評価できます。 - -Chrome Dev Toolsを開き、ネットワークタブに移動します。メニューバーの右端にある[Network Throttling](https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#throttling)ドロップダウンリストを探します。 - -"3G"速度の1つを試してみてください。サーバーレンダリングされたアプリケーションは依然として高速で起動しますが、完全なクライアントアプリケーションでは読み込みに数秒かかることがあります。 - -{@a summary} - -## まとめ - -このガイドでは、既存のAngularアプリケーションを使用して、それをサーバーサイドレンダリングを行うUniversalアプリケーションにする方法を説明しました。また、そうするべき主な理由のいくつかについても説明しました。 - -- webクローラーを支援する(SEO) -- 低帯域幅または低スペックデバイスのサポート -- 最初のページの高速読み込み - -Angular Universalは、アプリケーション起動時のパフォーマンスを大幅に向上させることができます。ネットワークが遅いほど、Universalが最初のページをユーザーに表示するという点で、より優れた効果が発揮されます。