Je souhaite servir des fichiers HTML statiques qui sont dans un /dist
dossier en dehors du projet Nest. index.html
est chargé avec succès mais il ne parvient à charger aucun fichier JS (404
Erreur).
J'ai un projet Node/Express.js qui utilise
app.use('/', express.static('../client/dist'))
et cela fonctionne parfaitement bien.
Dans le projet Nest, cependant,
app.setBaseViewsDir(join(__dirname, '../../client/dist'))
ne fait pas l'affaire.
Dans le AppController
j'ai essayé
import { Response } from 'express';
@Get()
get(@Res() res: Response) {
res.sendFile('index.html', {
root: '../client/dist',
});
}
Mais pas de chance.
Comme mentionné, le index.html
est chargé avec succès. Le problème n'est donc pas un mauvais chemin. Le problème n'est pas non plus le mauvais chemin src dans le index.html
car dans le projet Express, les mêmes fichiers sont utilisés.
/dist
|-index.html
|-main.js
|-etc.
Dans l'index.html:
<script type="text/javascript" src="main.js"></script>
Cela ne fonctionne pas non plus lorsque je place le dossier dist dans le projet Nest (et que j'adapte le chemin d'accès).
J'utilise maintenant le module express:
import * as express from 'express';
...
app.use('/', express.static('../client/dist'));
En ce qui concerne documentation officielle de Nest.js, il faut servir des fichiers statiques comme celui-ci:
Installez le package requis:
npm install --save @nestjs/serve-static
Mettre à jour app.module.ts pour ressembler à ceci:
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 {}
Pour servir des fichiers statiques, vous devez utiliser useStaticAssets()
au lieu de setBaseViewsDir()
:
app.useStaticAssets(join(__dirname, '../../client/dist'))
Lorsque vous utilisez useStaticAssets
vous n'avez pas besoin de configurer un contrôleur, tous vos fichiers seront servis automatiquement:
Disons sous client/dist
vous avez les fichiers index.html
et pic.jpg
. Ils seront servis comme:
localhost:3000 -> index.html
localhost:3000/pic.jpg -> pic.jpg
La définition du répertoire des vues de base est nécessaire lorsque vous souhaitez utiliser un moteur de vue comme par exemple hbs
, voir docs .
Écrire app.useStaticAssets(join(__dirname, '../../client/dist'))
dans main.ts
Et vous pouvez également essayer l'application Fastify:
import { resolve } from 'path';
app.useStaticAssets({
root: resolve("./build")
});
Si vous avez quelque chose comme ça
/public
|-index.html
|-main.js
|-etc.
/src
|-app.controller.js
|-app.module.js
|-main.js
Dans main.ts ou main.js
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'));
app.setViewEngine('html');
await app.listen(5000);
}
bootstrap();
Dans app.module.js
@Module({
imports:
[
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
exclude: ['/api*'],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Dans app.controller.js
@Controller()
@Dependencies(AppService)
export class AppController {
constructor(appService) {
this.appService = appService;
}
@Get()
@Render('index')
root() {
}
}
Avec ce code, vous pouvez faire l'affaire :) :) :)