如何在 Nest.js 中提供静态 HTML 文件?
Posted
技术标签:
【中文标题】如何在 Nest.js 中提供静态 HTML 文件?【英文标题】:How to serve static HTML files in Nest.js? 【发布时间】:2019-08-14 22:37:04 【问题描述】:我想提供位于 Nest 项目之外的 /dist
文件夹中的静态 html 文件。 index.html
加载成功但加载任何JS文件失败(404
错误)。
我有一个使用
的 Node/Express.js 项目app.use('/', express.static('../client/dist'))
而且效果很好。
然而,在 Nest 项目中,
app.setBaseViewsDir(join(__dirname, '../../client/dist'))
不成功。
在AppController
我试过
import Response from 'express';
@Get()
get(@Res() res: Response)
res.sendFile('index.html',
root: '../client/dist',
);
但没有运气。
如前所述,index.html
已成功加载。所以问题不是走错路。 index.html
中的 src-paths 也不是问题,因为在 Express 项目中使用了完全相同的文件。
/dist
|-index.html
|-main.js
|-etc.
在 index.html 中:
<script type="text/javascript" src="main.js"></script>
当我将 dist 文件夹放入 Nest 项目(并调整路径)时,它也不起作用。
我找到了解决办法:
我现在使用 express 模块:
import * as express from 'express';
...
app.use('/', express.static('../client/dist'));
【问题讨论】:
还有未解决的问题吗? :-) @KimKern 不,谢谢。我能够用上面提到的解决方案解决它:-) 很高兴听到您解决了它。 :-) 一般来说,考虑将您的解决方案添加为答案,而不是更新您的问题,以便其他人可以从中受益。然后您可以接受您的答案,向其他人展示您的问题已解决。在这种情况下,我建议使用 Nest API 而不是原生 express api,请参阅我的解决方案。 对于 Angular + NestJS + Cloud Functions for Firebase,请参阅答案:***.com/a/57493387/11127383 【参考方案1】:为了提供静态文件,您必须使用useStaticAssets()
而不是setBaseViewsDir()
:
app.useStaticAssets(join(__dirname, '../../client/dist'))
当您使用useStaticAssets
时,您无需设置控制器,所有文件都将自动提供:
假设在client/dist
下,您有文件index.html
和pic.jpg
。
他们将担任:
localhost:3000 -> index.html
localhost:3000/pic.jpg -> pic.jpg
当您想使用诸如hbs
之类的视图引擎时,需要设置基本视图目录,请参阅docs。
【讨论】:
这让我大失所望。谢谢! 谢谢你,你拯救了我的一天! 请注意,您需要将应用程序转换为正确的类型:const app = await NestFactory.create<NestExpressApplication>(AppModule);
才能在 typescript 中正确输入。【参考方案2】:
在 main.ts 中写入 app.useStaticAssets(join(__dirname, '../../client/dist'))
你也可以试试这个:
import resolve from 'path';
app.useStaticAssets(
root: resolve("./build")
);
【讨论】:
这是不正确的。当您使用useStaticAssets
时,您不需要任何控制器。文件将自动提供,index.html
可在根路径下访问。【参考方案3】:
关于 Nest.js 的 official documentation 应该像这样提供静态文件:
安装所需的包:
npm install --save @nestjs/serve-static
将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
【讨论】:
【参考方案4】:如果你有这样的事情
/public
|-index.html
|-main.js
|-etc.
/src
|-app.controller.js
|-app.module.js
|-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();
在 app.module.js 中
@Module(
imports:
[
ServeStaticModule.forRoot(
rootPath: join(__dirname, '..', 'public'),
exclude: ['/api*'],
),
],
controllers: [AppController],
providers: [AppService],
)
export class AppModule
在 app.controller.js 中
@Controller()
@Dependencies(AppService)
export class AppController
constructor(appService)
this.appService = appService;
@Get()
@Render('index')
root()
使用此代码,您可以解决问题 :) :) :)
【讨论】:
【参考方案5】:如果您决定在 "main.ts" 或 "app.module.ts" 中执行此操作(您不需要它们两者),最好添加“前缀”选项在“main.ts”中:
app.useStaticAssets(join(__dirname, '..', 'public'), prefix: '/public');
或者“app.module.ts”中的“serveRoot”选项:
ServeStaticModule.forRoot(
serveRoot: '/public',
rootPath: join(__dirname, '..', 'public'),
),
并将静态文件的链接设为“[your host]/public/[your dir and files]” 将您的静态路径比其他路径划分。
【讨论】:
以上是关于如何在 Nest.js 中提供静态 HTML 文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何将所有路由重定向到nest.js中的index.html(Angular)?