gpt4 book ai didi

javascript - Angular 9 - 您必须传入 NgModule 或 NgModuleFactory 才能引导

转载 作者:行者123 更新时间:2023-12-01 00:06:29 25 4
gpt4 key购买 nike

我将 Angular 应用程序从 v6 更新到了 v9,测试时确实没问题,但是当我将其部署到临时服务器时,出现此错误:

You must pass in a NgModule or NgModuleFactory to be bootstrapped

我搜索了很多相关内容,但我不知道在这里可以做什么。

./server.ts:


const environment = process.env.NODE_ENV || 'local';
const docker = process.env.DOCKER || false;

// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import { enableProdMode } from '@angular/core';

// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
import { MODULE_MAP } from '@nguniversal/module-map-ngfactory-loader';

import * as express from 'express';
import * as forceSSL from 'express-force-ssl';
import * as morgan from 'morgan';
import * as bodyParser from 'body-parser';
import { join } from 'path';
import * as fs from 'fs';
import * as compression from 'compression';
import * as Redis from 'redis';

// Import http and https servers
import * as http from 'http';
import * as https from 'https';

// Routes
import XRouter from './backend/routes/x.router';
//This is not the real route name, I'm omitting it.

// MOTD
import motd from './motd';

// Import cache config
const CACHE_CONFIG = require('./cache.conf');

// Faster server renders w/ Prod mode (dev mode never needed)
if(environment !== 'local') enableProdMode();

// Express server
const app = express();
let appRedirect;
if(!docker) appRedirect = express();

const PORT = process.env.PORT || 4000;
let PORT_SSL;
if(!docker) PORT_SSL = process.env.PORT || 443;
const URL_REDIS = process.env.URL_REDIS || 'redis://127.0.0.1:6379';
const DIST_FOLDER = join(process.cwd(), 'dist');

const template = fs.readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString();
const domino = require('domino');
const win = domino.createWindow(template);

global['window'] = win;
global['document'] = win.document;
global['DOMTokenList'] = win.DOMTokenList;
global['Node'] = win.Node;
global['Text'] = win.Text;
global['HTMLElement'] = win.HTMLElement;
global['navigator'] = win.navigator;
global['MutationObserver'] = getMockMutationObserver();
global['Event'] = win.Event;

function getMockMutationObserver() {
return class {
observe(node, options) {
}
disconnect() {
}
takeRecords() {
return [];
}
};
}

// Create a cache instance
const redisCache = Redis.createClient(URL_REDIS);

// Init routers
const xRouter = XRouter(redisCache);

/*******************************************************
************** Function to handle cache ****************
********************************************************/
function canBeCached(req) {
let output = false;
if(req.method != 'GET') return false;

output = CACHE_CONFIG.availableCache.some(url => {
return (req.originalUrl.indexOf(url) >= 0)
});

return output;
}

/******************************************************
************** Enable GZIP Compression ****************
*******************************************************/
app.use(compression({
level: 9
}));

/******************************************************
*********** Add morgan on DEV environment *************
*******************************************************/
if(environment === 'local')
app.use(morgan('dev'));

/******************************************************
************** Enable CORS in DEV mode ****************
*******************************************************/
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

/******************************************************
***************** Config SSR Angular ******************
*******************************************************/
if(environment !== 'local') {
try {
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');
const { MODULE_MAP } = require('@nguniversal/module-map-ngfactory-loader');

app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
{
provide: MODULE_MAP,
useValue: 'lazy'
}
]
}));

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
} catch(err) {
console.log(err);
}
}

server.on('listening', () => {
console.log(`Server listening...`);
});

./webpack.server.config.js

/**
* Package dist/server on server.ts script to render on server-side
*/
const path = require('path');
const webpack = require('webpack');

module.exports = {
mode: 'development', // # Temporary fix: https://github.com/angular/angular-cli/issues/8616
entry: { server: './server.ts' },
resolve: {
extensions: ['.js', '.ts'],
alias: {
'hiredis': path.join(__dirname, 'aliases/hiredis.js')
}
},
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'),
{}
)
]
}

./src/tsconfig.server.json

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

./src/main.server.ts:

export { AppServerModule } from './app/app.server.module';

./src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { registerLocaleData, isPlatformBrowser } from '@angular/common';
import { NgModule, PLATFORM_ID, Inject, APP_ID, } from '@angular/core';
import { NgxMaskModule } from 'ngx-mask';

// configure language
import ptBr from '@angular/common/locales/pt';
registerLocaleData(ptBr);

import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
import { LayoutModule } from './layout/layout.module';
import { PagesModule } from './pages/pages.module';
import { SharedModule } from './shared/shared.module';
import { AgmCoreModule } from '@agm/core';

import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import moment = require('moment');

moment.locale('pt-BR');

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule.withServerTransition({appId: 'site'}),
BrowserAnimationsModule,
CoreModule,
LayoutModule,
PagesModule,
SharedModule,
NgxMaskModule.forRoot(),
AgmCoreModule.forRoot({
apiKey: ''
}),
ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(
@Inject(PLATFORM_ID) private platformId: Object,
@Inject(APP_ID) private appId: string) {
const platform = isPlatformBrowser(platformId) ?
'in the browser' : 'on the server';
console.log(`Running ${platform} with appId=${appId}`);
}
}

./src/app/app.server.module.ts:

/**
This is the App loaded for the server render
express-js will load this file instead of AppModule directly.
**/
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
// We get the zone properties passed from express application
// @see server.ts
export function getRequest() {
return Zone.current.get('req') || {};
}
export function getResponse() {
return Zone.current.get('res') || {};
}

@NgModule({
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule,
],
bootstrap: [AppComponent],
providers: [
{ provide: 'req', useFactory: getRequest },
{ provide: 'res', useFactory: getResponse }
]
})
export class AppServerModule { }

Angular.json

{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"site": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets",
"src/manifest.json"
],
"styles": [
"node_modules/ngx-owl-carousel-o/lib/styles/prebuilt-themes/owl.carousel.min.css",
"node_modules/ngx-owl-carousel-o/lib/styles/prebuilt-themes/owl.theme.default.min.css",
"src/styles.scss"
],
"scripts": [
"src/assets/scripts/modernizr/modernizr.js",
"src/assets/scripts/g.js"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"serviceWorker": true
},
"development": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.dev.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": true,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"serviceWorker": true
},
"site-dev": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.site-dev.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"serviceWorker": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "site:build"
},
"configurations": {
"production": {
"browserTarget": "site:build:production"
}
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/server",
"main": "src/main.server.ts",
"tsConfig": "src/tsconfig.server.json"
},
"configurations": {
"site-dev": {
"fileReplacements": [{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.site-dev.ts"
}]
},
"development": {
"fileReplacements": [{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.dev.ts"
}]
},
"production": {
"fileReplacements": [{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}]
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "site: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/_variables.scss",
"src/_shared.scss",
"src/styles.scss"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets",
"src/manifest.json"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"site-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "site:serve"
},
"configurations": {
"production": {
"devServerTarget": "site:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "site"
}

最佳答案

使用 Ivy,您需要更改 server.ts 执行引导的方式。

您似乎尚未迁移 Angular ssr 文件。我们遇到了同样的问题(但我们当时没有使用express-engine),因此我们最终删除了与 ssr 相关的文件(server.tsmain.server.ts ,...) 并运行以下命令让 Angular 修改/创建所有必需的文件

ng add @nguniversal/express-engine

然后,我们修改了 server.ts 以在需要时添加我们的自定义代码。

如果您想手动执行所有操作而不运行命令,请查看 there

关于javascript - Angular 9 - 您必须传入 NgModule 或 NgModuleFactory 才能引导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60340119/

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