简体   繁体   English

Angular Universal 12(服务器端)在延迟加载时不加载模块

[英]Angular Universal 12 ( Server side ) not loading modules on lazy load

I have small application that have only one module, the application is working fine but it's not rendering the component on page source.我有一个只有一个模块的小应用程序,该应用程序工作正常,但它没有在页面源代码上呈现组件。
The issue is when I'm starting the application with npm run dev:ssr everything is fine ( on page source you have the component that is loaded after the tag (home-component in my situation) you can see the meta tags so everything seems to works fine), on npm run serve:ssr is still the same, everything looks fine, seems like everything works.问题是,当我使用 npm run dev:ssr 启动应用程序时,一切都很好(在页面源上,您有在标记之后加载的组件(在我的情况下为 home 组件),您可以看到元标记,因此一切似乎工作正常),在 npm run serve:ssr 上仍然相同,一切看起来都很好,似乎一切正常。
But the problem is when I publish the application, on the server the home-component is missing after the tag.但问题是当我发布应用程序时,在服务器上,标记后缺少 home 组件。

Here is an image of npm run dev:ssr page source:这是 npm run dev:ssr 页面源的图像: 在此处输入图片说明

Here is an image of the page source of published version:这是已发布版本的页面源的图像: 在此处输入图片说明

Here is the tsconfig.server.json这是 tsconfig.server.json

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "outDir": "./out-tsc/server",
    "target": "es2019",
    "types": [
      "node"
    ]
  },
  "files": [
    "src/main.server.ts",
    "server.ts"
  ],
  "angularCompilerOptions": {
    "entryModule": "./src/app/app.server.module#AppServerModule"
  }
}

Here is my server.ts file:这是我的 server.ts 文件:

    import 'zone.js/dist/zone-node';

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

    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/browser');
      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: express.Request, res: express.Response) => {
        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';


<!-- end snippet -->

**Here is main.serve.ts file:**


  
 
  
  
  
    import '@angular/platform-server/init';

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

    import { environment } from './environments/environment';

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

    export { AppServerModule } from './app/app.server.module';
    export { renderModule, renderModuleFactory } from '@angular/platform-server';

    export { AppServerModule } from './app/app.server.module';
    export { renderModule, renderModuleFactory } from '@angular/platform-server';
**Here is app.server.module.ts file:** <!-- begin snippet: js hide: false console: true babel: false --> <!-- language: lang-js --> import { NgModule } from '@angular/core'; import { ServerModule } from '@angular/platform-server'; import { AppModule } from './app.module'; import { AppComponent } from './app.component'; @NgModule({ imports: [ AppModule, ServerModule, ], bootstrap: [AppComponent], }) export class AppServerModule {}

And here is app.server.module.ts file:这是 app.server.module.ts 文件:

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    AppModule,
    ServerModule,
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

Here is app.module.ts file:这是 app.module.ts 文件:

import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    HttpClientModule,
    RouterModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Here is my app-routing.module.ts file:这是我的 app-routing.module.ts 文件:

 import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';

    const routes: Routes = [
      {
        path        : '',
        redirectTo  : 'home',
        pathMatch   : 'full',
      },
      {
        path         : 'home',
        loadChildren : () => import('./home/home.module').then(m => m.HomeModule)  
      },
      {
        path        : '**',
        redirectTo  : '',
        pathMatch   : 'full',
      },
    ];

    @NgModule({
      imports: [
        RouterModule.forRoot(routes)
      ],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }

EDIT: The solution I currently found is to add module: commonjs in tsconfig.server.json file, the application is kinda slower than usual but it's doing it's job.编辑:我目前找到的解决方案是在tsconfig.server.json文件中添加模块:commonjs ,该应用程序比平时慢一点,但它正在做它的工作。 If someone has better solution feel free to leave an answer.如果有人有更好的解决方案,请随时留下答案。

You are missing the initialNavigation property which is required by Angular Universal.您缺少 Angular Universal 所需的initialNavigation属性。

@NgModule({
  imports: [RouterModule.forRoot(routes, {
    initialNavigation: 'enabled'
})],
  exports: [RouterModule],
})
export class AppRoutingModule {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM