如何将所有路由重定向到nest.js中的index.html(Angular)?

问题描述 投票:1回答:1

我正在制作Angular + NestJS应用程序,我想为所有路由发送index.html文件。

main.ts

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useStaticAssets(join(__dirname, '..', 'frontend', 'dist', 'my-app'));
  app.setBaseViewsDir(join(__dirname, '..', 'frontend', 'dist', 'my-app'));
  await app.listen(port);
}

app.controller.ts

@Controller('*')
export class AppController {

  @Get()
  @Render('index.html')
  root() {
    return {};
  }
}

当我打开localhost:3000/时它工作正常,但如果我打开localhost:3000/some_route服务器落在500 internal error并说Can not find html module。我正在寻找为什么我得到这个错误,每个人都说set default view engine like ejs or pug,但我不想使用一些引擎,我只想发送由角度构建的普通html而不像res.sendFile('path_to_file')那样黑客攻击。请帮忙

javascript node.js typescript express nestjs
1个回答
3
投票

您只能将setBaseViewsDir@Render()与车把(hbs)等视图引擎一起使用;但是,对于提供静态文件(Angular),您只能使用useStaticAssetsresponse.sendFile

要从所有其他路线服务index.html,您有几种可能性:

A)中间件

您可以创建一个执行重定向的中间件,请参阅此article

@Middleware()
export class FrontendMiddleware implements NestMiddleware {
  resolve(...args: any[]): ExpressMiddleware {
    return (req, res, next) => {
      res.sendFile(path.resolve('../frontend/dist/my-app/index.html')));
    };
  }
}

然后为所有路由注册中间件:

export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewaresConsumer): void {
    consumer.apply(FrontendMiddleware).forRoutes(
      {
        path: '/**', // For all routes
        method: RequestMethod.ALL, // For all methods
      },
    );
  }
}

B)全局错误过滤器

你可以将所有NotFoundExceptions重定向到你的index.html

@Catch(NotFoundException)
export class NotFoundExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    response.sendFile(path.resolve('../frontend/dist/my-app/index.html')));
  }
}

然后在main.ts中将其注册为全局过滤器:

app.useGlobalFilters(new NotFoundExceptionFilter());

0
投票

您还可以将Cloud Functions for Firebase与Firebase Hosting一起使用。你在main.ts中拥有的东西非常好,通过这种方法你甚至不需要控制器。你应该如下:

  1. index.html重命名为index2.html。这对于渲染路径路径很重要,否则您将在所有路径上正常工作,不包括根/
  2. 更新angular.json以获得以下"index": "apps/myapp/src/index2.html",(只需将index.html更改为index2.html)。注意:index.html的路径可能与您不同,我使用的是Nx工作区。
  3. templatePath: join(BROWSER_DIR, 'index2.html'),添加到NestJS的ApplicationModule,很可能您将该文件命名为服务器目录中的app.module.ts。

像这样:

@Module({
  imports: [
    AngularUniversalModule.forRoot({
      bundle: require('./path/to/server/main'), // Bundle is created dynamically during build process.
      liveReload: true,
      templatePath: join(BROWSER_DIR, 'index2.html'),
      viewsPath: BROWSER_DIR
    })
  ]
})
  1. 初始化Firebase云功能和Firebase托管,有关如何设置此信息,您可以检查https://hackernoon.com/deploying-angular-universal-v6-with-firebase-c86381ddd445https://blog.angularindepth.com/angular-5-universal-firebase-4c85a7d00862
  2. 编辑你的firebase.json。

它看起来应该是这样,或者至少是hosting部分。

{
  "hosting": {
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "public": "functions/dist/apps/path/to/browser",
    "rewrites": [
      {
        "function": "angularUniversalFunction",
        "source": "**"
      }
    ]
  }
} 
  1. 在main.ts中,您需要在服务器上设置云功能。

在极简主义的情况下,它会像这样:

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

admin.initializeApp(); // Initialize Firebase SDK.
const expressApp: Express = express(); // Create Express instance.

// Create and init NestJS application based on Express instance.
(async () => {
  const nestApp = await NestFactory.create<NestExpressApplication>(
    ApplicationModule,
    new ExpressAdapter(expressApp)
  );
  nestApp.init();
})().catch(err => console.error(err));

// Firebase Cloud Function for Server Side Rendering (SSR).
exports.angularUniversalFunction = functions.https.onRequest(expressApp);

使用这种方法,您不必关心NestJS端的路由。您可以在Angular端设置所有内容,这就是全部。 Angular负责路由。您可能已经注意到这是服务器端呈现(SSR),但是所有路由重定向到index.html(或者更确切地说是index2.html)都可以使用NestJS + Fire Functions for Firebase完成。另外你有一个SSR“免费”:)

展示的项目:

1)角色+角度通用(SSR)+ Firebase的云函数:https://github.com/Ismaestro/angular8-example-app(缺少NestJS)。

2)Angular + NestJS:https://github.com/kamilmysliwiec/universal-nest(缺少Firebase的Cloud Functions)。

© www.soinside.com 2019 - 2024. All rights reserved.