gpt4 book ai didi

javascript - Angular Universal 不会接管客户端的渲染

转载 作者:行者123 更新时间:2023-12-01 17:13:58 25 4
gpt4 key购买 nike

我目前正在尝试按照官方 Angular guide for angular universal 将服务器端渲染 (SSR) 添加到我的 Angular 应用程序中.我能够设置快速服务器并且我从服务器获得的响应包含我的应用程序,虽然看起来有点古怪,好像缺少一些 CSS 导致 FontAwesome图标被渲染太大等。
但是由于某种原因,客户端/浏览器永远不会接管(重新)渲染,并且网站与来自服务器的响应保持不变。它不是交互式的,完全是静态的。单击控件(链接除外)或交互元素时,没有任何 react 。
在这里您可以看到 的部分内容App Shell / HTML .
这里是 Network Traffic .
包.json :

    {
"name": "my-app",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"dev:ssr": "ng run my-app:serve-ssr",
"serve:ssr": "node dist/my-app/server/main.js",
"build:ssr": "ng build --prod && ng run my-app:server:production",
"prerender": "ng run my-app:prerender"
},
"private": true,
"dependencies": {
"@agm/core": "^1.1.0",
"@angular/animations": "^10.0.14",
"@angular/common": "^10.0.14",
"@angular/compiler": "^10.0.14",
"@angular/core": "^10.0.14",
"@angular/elements": "^10.0.14",
"@angular/forms": "^10.0.14",
"@angular/localize": "~10.0.14",
"@angular/platform-browser": "^10.0.14",
"@angular/platform-browser-dynamic": "^10.0.14",
"@angular/platform-server": "^10.0.14",
"@angular/router": "^10.0.14",
"@angular/service-worker": "^10.0.14",
"@fortawesome/angular-fontawesome": "^0.7.0",
"@fortawesome/fontawesome-svg-core": "^1.2.30",
"@fortawesome/free-brands-svg-icons": "^5.14.0",
"@fortawesome/free-regular-svg-icons": "^5.14.0",
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
"@ng-select/ng-select": "^4.0.4",
"@nguniversal/express-engine": "^10.0.2",
"@webcomponents/webcomponentsjs": "^2.2.10",
"bootstrap": "^4.3.1",
"bufferutil": "^4.0.1",
"core-js": "^2.5.4",
"document-register-element": "^1.13.2",
"domino": "^2.1.6",
"express": "^4.15.2",
"html-webpack-plugin": "^2.30.1",
"intersection-observer": "^0.7.0",
"jquery": "^3.5.1",
"ng-lazyload-image": "^5.1.2",
"ng5-slider": "^1.1.14",
"ngx-cookie-service": "^2.2.0",
"ngx-infinite-scroll": "^7.1.0",
"popper.js": "^1.14.7",
"rxjs": "^6.6.2",
"tslib": "^2.0.0",
"utf-8-validate": "^5.0.2",
"webpack": "^4.44.1",
"xmlhttprequest": "^1.8.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1000.8",
"@angular/cli": "^10.0.8",
"@angular/compiler-cli": "^10.0.14",
"@angular/language-service": "^10.0.14",
"@nguniversal/builders": "^10.0.2",
"@types/express": "^4.17.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~3.3.0",
"karma-jasmine-html-reporter": "^1.5.0",
"ngx-perfect-scrollbar": "^7.2.1",
"node-sass": "^4.14.1",
"protractor": "~7.0.0",
"ts-node": "~7.0.0",
"tslint": "~6.1.0",
"typescript": "^3.9.7"
}
}
Angular .json :
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"my-app": {
"i18n": {
"locales": {
"de-AT": {
"translation": "src/locale/messages.de-AT.xlf",
"baseHref": ""
}
}
},
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"watch": false,
"index": "src/index.html",
"outputPath": "dist/my-app/browser",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/apple-touch-icon.png",
"src/apple-touch-icon-precomposed.png",
"src/robots.txt",
"src/sitemap.xml",
"src/assets",
"src/manifest.json"
],
"styles": [
"src/styles.scss"
],
"scripts": [
{
"input": "node_modules/document-register-element/build/document-register-element.js"
}
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"i18nMissingTranslation": "error",
"localize": [
"de-AT"
],
"optimization": true,
"outputHashing": "bundles",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "3mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "20kb"
}
],
"serviceWorker": true,
"ngswConfigPath": "src/ngsw-config.json"
},
"dev": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.dev.ts"
}
],
"aot": false,
"i18nMissingTranslation": "error",
"localize": [
"de-AT"
],
"optimization": false,
"outputHashing": "none",
"extractCss": true,
"namedChunks": true,
"extractLicenses": true,
"vendorChunk": false,
"budgets": [
{
"type": "initial",
"maximumWarning": "10mb",
"maximumError": "12mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "20kb"
}
],
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "my-app:build"
},
"configurations": {
"production": {
"browserTarget": "my-app:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "my-app:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.scss"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/robots.txt",
"src/sitemap.xml",
"src/assets",
"src/manifest.json"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json",
"src/tsconfig.server.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/my-app/server",
"main": "server.ts",
"tsConfig": "src/tsconfig.server.json"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": true
}
}
},
"serve-ssr": {
"builder": "@nguniversal/builders:ssr-dev-server",
"options": {
"browserTarget": "my-app:build",
"serverTarget": "my-app:server"
},
"configurations": {
"production": {
"browserTarget": "my-app:build:production",
"serverTarget": "my-app:server:production"
}
}
},
"prerender": {
"builder": "@nguniversal/builders:prerender",
"options": {
"browserTarget": "my-app:build:production",
"serverTarget": "my-app:server:production",
"routes": [
"/"
]
},
"configurations": {
"production": {}
}
}
}
},
"my-app-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "my-app:serve"
},
"configurations": {
"production": {
"devServerTarget": "my-app:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "my-app"
}

server.ts :
import 'zone.js/dist/zone-node';

import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';

const domino = require('domino');
const fs = require('fs');
const path = require('path');

const template = fs
.readFileSync(path.join('dist/my-app/browser/de-AT', 'index.html'))
.toString();
const window = domino.createWindow(template);

// Ignite UI browser objects abstractions
(global as any).window = window;
(global as any).document = window.document;
(global as any).Event = window.Event;
(global as any).KeyboardEvent = window.KeyboardEvent;
(global as any).MouseEvent = window.MouseEvent;
(global as any).FocusEvent = window.FocusEvent;
(global as any).PointerEvent = window.PointerEvent;
(global as any).HTMLElement = window.HTMLElement;
(global as any).HTMLElement.prototype.getBoundingClientRect = () => {
return {
left: '',
right: '',
top: '',
bottom: ''
};
};

(global as any).XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;

// Other optional depending on your application configuration
(global as any).object = window.object;
(global as any).navigator = window.navigator;
(global as any).localStorage = window.localStorage;
(global as any).DOMTokenList = window.DOMTokenList;

Object.defineProperty(window.document.body.style, 'transform', {
value: () => {
return {
enumerable: true,
configurable: true,
};
},
});
(global as any).CSS = null;
(global as any).Prism = null;

import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/my-app/browser/de-AT');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));

server.set('view engine', 'html');
server.set('views', distFolder);

// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));

// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});

return server;
}

function run(): void {
const port = process.env.PORT || 4000;

// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}

export * from './src/main.server';
tsconfig.base.json :
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "es2020",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"downlevelIteration": true,
"typeRoots": [
"node_modules/@types",
"typings.d.ts"
],
"lib": [
"es2018",
"dom"
]
}
}
tsconfig.server.json :
{
"extends": "./tsconfig.app.json",
"compilerOptions": {
"outDir": "../out-tsc/server",
"target": "es2016",
"types": [
"node"
]
},
"files": [
"main.server.ts",
"../server.ts"
],
"angularCompilerOptions": {
"entryModule": "./app/app.server.module#AppServerModule"
}
}
app.server.module.ts :
    import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { UniversalInterceptor } from './universal-interceptor';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
imports: [
AppModule,
ServerModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: UniversalInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppServerModule {}
我真的不知道我做错了什么。有任何想法吗?

最佳答案

经过长时间的调查,我找到了罪魁祸首。似乎在添加 Angular Universal 时,CLI 包装了 DOMContentLoaded事件监听器围绕另一个 DOMContentLoaded 引导应用程序 中的事件监听器main.ts 文件。这就是它的样子:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
enableProdMode();
}

document.addEventListener('DOMContentLoaded', () => { // Remove this
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
});
}); // Remove this
因此,删除第二个事件监听器使应用程序再次启动。

关于javascript - Angular Universal 不会接管客户端的渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63781342/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com