Рендеринг на стороне сервера в Angular

  • 10 апреля, 13:59
  • 6071
  • 0

Технология, которая позволяет нам запускать наши приложения Angular на сервере, описывается в документации Angular как Angular Universal. Angular Universal  генерирует  статические  страницы приложений на сервере с помощью процесса, называемого  серверным рендерингом (SSR).

Он может генерировать и обслуживать страницы в ответ на запросы браузеров. Он также может предварительно сгенерировать шаблон Angular в виде HTML-файлов, которые вы обслуживаете позже.

Рендеринг на стороне сервера в Angular

Стандартное Angular приложение выполняется в  браузере, отображая страницы в DOM в ответ на действия пользователя.

Чтобы улучшить взаимодействие с пользователем, мы хотим отображать страницы на стороне сервера и отправлять сгенерированный статический контент на сторону клиента, это будет гарантировать, что наш контент будет сканироваться поисковыми системами, а также позволит пользователям использовать наш контент.

В этой статье вы узнаете, как добавить поддержку Angular Universal в любое существующее приложение Angular. Давайте начнем с установки зависимостей

Рендеринг на стороне сервера - установка зависимостей

Чтобы реализовать рендеринг на стороне сервера, нам нужно установить некоторые дополнительные зависимости.

Откройте терминал и введите следующие команды:

$ npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine

Корневой AppModule

Откройте файл src/app/app.module.ts и найдите BrowserModule импорт в NgModule.

Замените этот импорт следующим:

BrowserModule.withServerTransition({ appId: 'your App-ID' }),

Создайте app.server.module.ts файл в src/app/ каталоге со следующим кодом AppServerModule:

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'; @NgModule({   imports: [     AppModule,     ServerModule,     ModuleMapLoaderModule   ],   providers: [     // Add universal-only providers here   ],   bootstrap: [ AppComponent ], }) export class AppServerModule {}

Создайте main.server.ts файл в каталоге src со следующим кодом:

// These are important and needed before anything else import 'zone.js/dist/zone-node'; import 'reflect-metadata'; import { enableProdMode } from '@angular/core'; import * as express from 'express'; import { join } from 'path'; // Faster server renders w/ Prod mode (dev mode never needed) enableProdMode(); // Express server const app = express(); const PORT = process.env.PORT || 4000; const DIST_FOLDER = join(process.cwd(), 'dist'); // * NOTE :: leave this as require() since this file is built Dynamically from webpack const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle'); // Express Engine import { ngExpressEngine } from '@nguniversal/express-engine'; // Import module map for lazy loading import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; app.engine('html', ngExpressEngine({   bootstrap: AppServerModuleNgFactory,   providers: [     provideModuleMap(LAZY_MODULE_MAP)   ] })); app.set('view engine', 'html'); app.set('views', join(DIST_FOLDER, 'browser')); // TODO: implement data requests securely app.get('/api/*', (req, res) => {   res.status(404).send('data requests are not supported'); }); // Server static files from /browser app.get('*.*', express.static(join(DIST_FOLDER, 'browser'))); // All regular routes use the Universal engine app.get('*', (req, res) => {   res.render(join(DIST_FOLDER, 'browser', 'index.html'), { req }); }); // Start up the Node server app.listen(PORT, () => {   console.log(`Node server listening on http://localhost:${PORT}`); });

Создайте tsconfig.server.json файл в /src каталоге для настройки TypeScript и AOT-компиляции универсального приложения.

{   "extends": "../tsconfig.json",   "compilerOptions": {     "outDir": "../out-tsc/app",     "baseUrl": "./",     "module": "commonjs",     "types": []   },   "exclude": [     "test.ts",     "**/*.spec.ts"   ],   "angularCompilerOptions": {     "entryModule": "app/app.server.module#AppServerModule"   } }

Создайте webpack.server.config.js файл в корневом каталоге проекта со следующим кодом:

const path = require('path'); const webpack = require('webpack'); module.exports = {   entry: { server: './server.ts' },   resolve: { extensions: ['.js', '.ts'] },   target: 'node',   // this makes sure we include node_modules and other 3rd party libraries   externals: [/(node_modules|main\..*\.js)/],   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'),       {}     )   ] };

Обновите раздел приложений .angular-cli.json 

"apps": [{  "root": "src",  "outDir": "dist/browser",  "assets": ["assets", "favicon.ico"],  "index": "index.html",  "main": "main.ts",  "polyfills": "polyfills.ts",  "test": "test.ts",  "tsconfig": "tsconfig.app.json",  "testTsconfig": "tsconfig.spec.json",  "prefix": "app",  "styles": ["styles.css"],  "scripts": [],  "environmentSource": "environments/environment.ts",  "environments": {  "dev": "environments/environment.ts",  "prod": "environments/environment.prod.ts"  }  },  {  "platform": "server",  "root": "src",  "outDir": "dist/server",  "assets": ["assets", "favicon.ico"],  "index": "index.html",  "main": "main.server.ts",  "test": "test.ts",  "tsconfig": "tsconfig.server.json",  "testTsconfig": "tsconfig.spec.json",  "prefix": "app",  "styles": ["styles.css"],  "scripts": [],  "environmentSource": "environments/environment.ts",  "environments": {  "dev": "environments/environment.ts",  "prod": "environments/environment.prod.ts"  }  } ],

Сборка и запуск с Universal

Теперь, когда вы создали файлы конфигурации TypeScript и Webpack, вы можете создать и запустить приложение Angular Universal.

Сначала добавьте build и обслуживающие  команды в разделе сценариев package.json:

"scripts": {     ...     "build:universal": "npm run build:client-and-server-bundles && npm run webpack:server",     "serve:universal": "node dist/server.js",     "build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",     "webpack:server": "webpack --config webpack.server.config.js --progress --colors",     ... }

Из терминала введите:

npm run build:universal

После сборки приложения запустите сервер.

npm run serve:universal

В заключение. Откройте окно браузера http://localhost:4000/, чтобы получить доступ к приложению Angular на стороне сервера.

Вывод

С помощью рендеринга на стороне сервера мы можем гарантировать, что поисковые системы, браузеры с  отключенным Javascript или браузеры без Javascript по-прежнему смогут получать доступ к содержимому нашего сайта.

Источник перевода


0 комментариев
Сортировка:
Добавить комментарий

IT Новости

Смотреть все