Что я делал до сих пор?
Я начал добавлять поддержку 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 и всем, любая помощь очень ценится.Спасибо.