简体   繁体   English

如何在 Nest.js 中提供静态 HTML 文件?

[英]How to serve static HTML files in Nest.js?

I want to serve static HTML files which are in a /dist folder outside of the Nest project.我想提供位于 Nest 项目之外的/dist文件夹中的静态 HTML 文件。 index.html is loaded successfully but it fails to load any JS file ( 404 error). index.html已成功加载,但无法加载任何 JS 文件( 404错误)。

I have a Node/Express.js project which uses我有一个 Node/Express.js 项目,它使用

app.use('/', express.static('../client/dist'))

and it works perfectly fine.它工作得很好。

In the Nest project, however,然而,在 Nest 项目中,

app.setBaseViewsDir(join(__dirname, '../../client/dist'))

does not do the trick.不做的伎俩。

In the AppController I triedAppController我试过

import { Response } from 'express';

@Get()
  get(@Res() res: Response) {
    res.sendFile('index.html', {
      root: '../client/dist',
    });
  }

But no luck.但没有运气。

As mentioned, the index.html is loaded successfully.如前所述, index.html已成功加载。 So the problem is not a wrong path.所以问题不是走错路。 Neither is the problem wrong src-paths in the index.html because in the Express project the exact same files are used.问题也不是index.html中的 src-paths 错误,因为在 Express 项目中使用了完全相同的文件。

/dist
  |-index.html
  |-main.js
  |-etc.

In the index.html:在 index.html 中:

<script type="text/javascript" src="main.js"></script>

It does not work either when I put the dist folder into the Nest project (and adapt the path).当我将 dist 文件夹放入 Nest 项目(并调整路径)时,它也不起作用。

I found the solution:我找到了解决方案:

I use the express module now:我现在使用 express 模块:

import * as express from 'express';
...
app.use('/', express.static('../client/dist'));

For serving static files you have to use useStaticAssets() instead of setBaseViewsDir() :要提供静态文件,您必须使用useStaticAssets()而不是setBaseViewsDir()

app.useStaticAssets(join(__dirname, '../../client/dist'))

When you use useStaticAssets you don't need to set up a controller, all your files will be served automatically:当您使用useStaticAssets您不需要设置控制器,您的所有文件都将自动提供:

Let's say under client/dist you have the files index.html and pic.jpg .假设在client/dist你有文件index.htmlpic.jpg They will be served as:他们将担任:

localhost:3000 -> index.html
localhost:3000/pic.jpg -> pic.jpg

Setting the base views dir is needed when you want to use a view engine like for example hbs , see docs .当您想使用像hbs这样的视图引擎时,需要设置基本视图目录,请参阅文档

Regarding the official documentation of Nest.js one should serve static files like this:关于 Nest.js 的官方文档应该提供这样的静态文件:

Install the required package:安装所需的包:

npm install --save @nestjs/serve-static

Update app.module.ts to look like this:app.module.ts更新为如下所示:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),   // <-- path to the static files
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

If you have something like this如果你有这样的事情

/public
  |-index.html
  |-main.js
  |-etc.
/src
  |-app.controller.js
  |-app.module.js
  |-main.js

In main.ts or main.js在 main.ts 或 main.js

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setViewEngine('html');

  await app.listen(5000);
}
bootstrap();

In app.module.js在 app.module.js 中

@Module({
  imports: 
  [ 
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'public'),
      exclude: ['/api*'],
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

In app.controller.js在 app.controller.js 中

@Controller()
@Dependencies(AppService)
export class AppController {
  constructor(appService) {
    this.appService = appService;
  }

  @Get()
  @Render('index')
  root() {
  }
}

With this code, you can do the trick :) :) :)使用此代码,您可以解决问题:) :) :)

Write app.useStaticAssets(join(__dirname, '../../client/dist')) in main.tsapp.useStaticAssets(join(__dirname, '../../client/dist'))写入app.useStaticAssets(join(__dirname, '../../client/dist'))

And also you can try for fastify app this:您也可以尝试使用 fastify 应用程序:

import { resolve } from 'path';

app.useStaticAssets({
    root: resolve("./build")
});

If you decide to do it in "main.ts" or "app.module.ts" (you don't need them both), it's better for you to add "prefix" option in the "main.ts":如果您决定在“main.ts”“app.module.ts”中执行(您不需要两者都需要),最好在“main.ts”中添加“prefix”选项:

app.useStaticAssets(join(__dirname, '..', 'public'), {prefix: '/public'});

Or the "serveRoot" option in the "app.module.ts":或者“app.module.ts”中的“serveRoot”选项:

ServeStaticModule.forRoot({
   serveRoot: '/public',
   rootPath: join(__dirname, '..', 'public'),
}),

And make the link to your static files as "[your host]/public/[your dir and files]" To divide your static path than other paths.并将您的静态文件的链接设为“[您的主机]/public/[您的目录和文件]”以将您的静态路径与其他路径分开。

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

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