【问题标题】:Angular Universal 12 ( Server side ) not loading modules on lazy loadAngular Universal 12(服务器端)在延迟加载时不加载模块
【发布时间】:2021-11-29 02:06:17
【问题描述】:

我有一个只有一个模块的小型应用程序,该应用程序工作正常,但它没有在页面源上呈现组件。
问题是当我使用 npm run dev:ssr 启动应用程序时,一切都很好(在页面源代码上,您有在标签之后加载的组件(在我的情况下为主页组件),您可以看到元标签,所以一切看起来工作正常),在 npm run serve:ssr 上仍然是一样的,一切看起来都很好,似乎一切正常。
但问题是当我发布应用程序时,在服务器上,标签后缺少 home-component。

这是 npm run dev:ssr 页面源的图片:

这是已发布版本的页面来源图片:

这里是 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"
  }
}

这是我的 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 {}

这里是 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 {}

这里是 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 { }

这是我的 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 { }

编辑: 我目前找到的解决方案是在 tsconfig.server.json 文件中添加 module: commonjs,该应用程序比平时慢了一点,但它正在完成它的工作。如果有人有更好的解决方案,请随时留下答案。

【问题讨论】:

  • 你在使用 angular service-worker/pwa 吗?
  • @Pieterjan 不,我没有使用任何东西,我只是创建了新的应用程序,添加了@nguniversal/express-engine,添加了一个模块并使其延迟加载,我在组件中添加了元标记在那个延迟加载的模块中,就是这样,我没有做任何其他事情或将任何其他包添加到应用程序中。
  • 您找到解决方案了吗?我这边也有同样的问题。
  • 解决方案在我发布的帖子的末尾(在编辑部分)。我在 tsconfig.server.json 文件中添加了模块:commonjs,应用程序比平时慢,但它正在完成它的工作。 @Shakir
  • 可以分享tsconfig.server.json的代码

标签: angular server-side-rendering angular-universal universal angular12


【解决方案1】:

您缺少 Angular Universal 所需的 initialNavigation 属性。

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

【讨论】:

  • 如果我添加 initialNavigation: 'enabled' 它根本不会打开我部署的应用程序,它只是在加载应用程序的选项卡上有微调器,但它根本没有打开。
  • 还有@LukaszGawrys,initialNavigation: 'enabled' 在 Angular v11 link987654321@ 之后可以 1:1 替换为 enabledBlocking
猜你喜欢
  • 2018-06-19
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
相关资源
最近更新 更多