Как добавить поддержку ssr для проекта angular cli, используя ядро ​​dotnet в качестве бэкэнда? - PullRequest
0 голосов
/ 22 мая 2018

Что я делал до сих пор?


Я начал добавлять поддержку ssr с выражением узла как бэкэнд-реферингом Angular Doc , и он работал как ожидалось.

Затем, чтобы он поддерживал ядро ​​dotnet вместо Node Express, я использовал @nguniversal/aspnetcore-engine, ссылаясь на universal doc .И соответственно изменил файл server.ts в корневой угловой папке и HomeController в основном проекте dotnet. Команда

"scripts": { ... "build:ssr": "ng build --prod && ng run web:server && npm run webpack:server", "webpack:server": "webpack --config webpack.server.config.js", } build:ssr сгенерирует необходимые файлы в папке dist без ошибок.

И в моем HomeController я добавил путь к скомпилированному файлу server.js, как показано ниже.

        // Prerender / Serialize application (with Universal)
        var prerenderResult = await Prerenderer.RenderToString(
            "/", // baseURL
            nodeServices,
            cancelToken,
            new JavaScriptModuleExport(applicationBasePath + "../../../frontend/dist/server/server.js"),
            unencodedAbsoluteUrl,
            unencodedPathAndQuery,
            // Our Transfer data here will be passed down to Angular (within the main.server file)
            // Available there via `params.data.yourData`
            transferData,
            30000, // timeout duration
            Request.PathBase.ToString()
        );

И мой файл webpack.config.js для компиляции файла server.ts показан ниже.

const path = require('path');
const webpack = require('webpack');

const SERVER = 'server';

module.exports = {
  entry: {  server: './server.ts' },
  resolve: { extensions: ['.js', '.ts'] },
  mode: 'development',
  target: 'node',
  externals: [/(node_modules|main\..*\.js)/],
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, `dist/${SERVER}`),
    filename: '[name].js'
  },
  module: {
    rules: [
      { test: /\.ts$/, loader: 'ts-loader' }
    ]
  },
  plugins: [
    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'),
      {}
    )
  ]
}

Мой server.ts файл

// Polyfills
import 'es6-promise';
import 'es6-shim';
import 'reflect-metadata';
import 'zone.js';

import { enableProdMode } from '@angular/core';
import { INITIAL_CONFIG } from '@angular/platform-server';
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
// Grab the (Node) server-specific NgModule
import { AppServerModule } from './src/app/app.server.module';
// ***** The ASPNETCore Angular Engine *****
import { ngAspnetCoreEngine, IEngineOptions, createTransferScript } from '@nguniversal/aspnetcore-engine';
import { DOCUMENT } from '@angular/common';

enableProdMode(); // for faster server rendered builds

export default createServerRenderer(params => {

    /*
     * How can we access data we passed from .NET ?
     * you'd access it directly from `params.data` under the name you passed it
     * ie: params.data.WHATEVER_YOU_PASSED
     * -------
     * We'll show in the next section WHERE you pass this Data in on the .NET side
     */

    // Platform-server provider configuration
    const setupOptions: IEngineOptions = {
      appSelector: '<app-root></app-root>',
      ngModule: AppServerModule,
      request: params,
      providers: [
        /* Other providers you want to pass into the App would go here
        *    { provide: CookieService, useClass: ServerCookieService }

        * ie: Just an example of Dependency injecting a Class for providing Cookies (that you passed down from the server)
          (Where on the browser you'd have a different class handling cookies normally)
        */
      ]
    };

    // ***** Pass in those Providers & your Server NgModule, and that's it!
    return ngAspnetCoreEngine(setupOptions).then(response => {

      // Want to transfer data from Server -> Client?

      // Add transferData to the response.globals Object, and call createTransferScript({}) passing in the Object key/values of data
      // createTransferScript() will JSON Stringify it and return it as a <script> window.TRANSFER_CACHE={}</script>
      // That your browser can pluck and grab the data from
      response.globals.transferData = createTransferScript({
        someData: 'Transfer this to the client on the window.TRANSFER_CACHE {} object',
        fromDotnet: params.data.thisCameFromDotNET // example of data coming from dotnet, in HomeController
      });

      return ({
        html: response.html,
        globals: response.globals
      });

    });
});

Что мне здесь еще не хватает?Разве невозможно использовать angular cli, чтобы собрать все необходимые файлы и использовать его в createServerRenderer?

Поскольку я являюсь нубом в области ssr в angular & dotnetcore, я незнать, как main.js работает вместе с файлом server.js и всем, любая помощь очень ценится.Спасибо.

1 Ответ

0 голосов
/ 14 сентября 2018

Новый шаблон Microsoft не работает должным образом с Angular6, если вы используете сторонние модули.Используйте Express вместо aspnetcore-engine

...