如何使用dotnet core作为后端为angular cli项目添加ssr支持?

时间:2018-05-22 19:10:29

标签: angular webpack .net-core angular-cli serverside-rendering

到目前为止我做了什么?

<小时/> 我开始添加对带有node express的ssr的支持作为后端引用Angular Doc,并且它按预期工作。

然后为了使其支持dotnet核心而不是Node express,我使用@nguniversal/aspnetcore-engine引用universal doc。 并相应更改了角网根文件夹中的server.ts文件和dotnet核心项目中的HomeController

"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中使用它?

因为Iam是角度和角度ssr区域的菜鸟dotnetcore,我不知道main.js如何与server.js文件一起工作,所有,非常感谢任何帮助。感谢。

1 个答案:

答案 0 :(得分:0)

如果您使用第三方模块,则新的Microsoft模板不能与Angular6一起正常使用。使用Express代替aspnetcore-engine