0

I get an error when I try to render a simple static html file (no template). I don't understand why I'm getting this error. I tried a bunch of things but without success.

src/modules/app.module.ts

import { Module } from '@nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { AuthModule } from './auth/auth.module'
import { ServeStaticModule } from '@nestjs/serve-static'
import { join } from 'path'
import { DiscordModule } from './bot/discord.module'
import { UserModule } from './database/user/user.module'
import { TypeOrmModule } from '@nestjs/typeorm'
import { ConnectionOptions, getConnectionOptions } from 'typeorm'
import { RoleModule } from './database/role/role.module'
import { AppConfigModule } from './config/config.module'
import { PassportModule } from '@nestjs/passport'

@Module({
  imports: [
    AppConfigModule.forRoot({
      isGlobal: true,
      cache: true,
      envFilePath: [ '.env.local', '.env' ],
      expandVariables: true,
    }),
    TypeOrmModule.forRootAsync({
      useFactory: async () =>
        Object.assign(await getConnectionOptions(), <Partial<ConnectionOptions>>{
          autoLoadEntities: true,
          cache: true,
        }),
    }),
    UserModule,
    RoleModule,
    DiscordModule,
    AuthModule,
    PassportModule.register({
      session: true
    }),
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', '..', 'public'),
      exclude: [ '/api*' ],
    }),
  ],
  controllers: [ AppController ],
  providers: [ AppService ],
})
export class AppModule {}

src/modules/app.controller.ts

import { Controller, Get, Render } from '@nestjs/common'
import { AppService } from './app.service'

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
  
  @Get('/hello')
  getHello(): string {
    return this.appService.getHello()
  }
  
  @Get()
  @Render('index.html')
  root() {}
}

src/main.ts

import { NestFactory, Reflector } from '@nestjs/core'
import { ValidationPipe } from '@nestjs/common'
import { AppModule } from './modules/app.module'
import { NestExpressApplication } from '@nestjs/platform-express'
import { AppConfigService } from './modules/config/config.service'
import { AuthenticatedGuard } from './modules/auth/auth.guard'
import session from 'express-session'
import { TypeormStore } from 'connect-typeorm'
import { getRepository } from 'typeorm'
import { SessionEntity } from './database/entities/session.entity'
import { SESSION_SECRET } from './modules/config/config.constants'
import passport from 'passport'

async function bootstrap() {
  const app    = await NestFactory.create<NestExpressApplication>(AppModule)
  const config = app.get(AppConfigService)
  app.useGlobalPipes(new ValidationPipe())
  app.useGlobalGuards(new AuthenticatedGuard(app.get(Reflector)))
  app.use(session({
    cookie: { maxAge: 24 * 60 * 60 * 1000 },
    secret: 'djsnjfjknskjfnanfkdfalsndjfndsj',
    resave: false,
    saveUninitialized: false,
    store: new TypeormStore().connect(getRepository(SessionEntity)),
  }))
  app.use(passport.initialize())
  app.use(passport.session())
  app.enableCors({
    origin: [ config.baseUrl ],
    credentials: true,
  })
  app.setViewEngine('html')
  await app.listen(config.port)
}

bootstrap()

Stacktrace

[Nest] 192424   - 2021-05-23, 6:07:20 p.m.   [ExceptionsHandler] Cannot find module 'html'
Require stack:
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/view.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/application.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/express.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/platform-express/adapters/express-adapter.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/platform-express/adapters/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/platform-express/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/core/nest-factory.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/core/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/dist/main.js +3532ms
Error: Cannot find module 'html'
Require stack:
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/view.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/application.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/express.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/platform-express/adapters/express-adapter.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/platform-express/adapters/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/platform-express/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/core/nest-factory.js
- /home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/core/index.js
- /home/drunkenponey/projects/the-4-horsemen/api/dist/main.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:941:15)
    at Function.Module._load (node:internal/modules/cjs/loader:774:27)
    at Module.require (node:internal/modules/cjs/loader:1013:19)
    at require (node:internal/modules/cjs/helpers:93:18)
    at new View (/home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/view.js:81:14)
    at Function.render (/home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/application.js:570:12)
    at ServerResponse.render (/home/drunkenponey/projects/the-4-horsemen/api/node_modules/express/lib/response.js:1012:7)
    at ExpressAdapter.render (/home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/platform-express/adapters/express-adapter.js:30:25)
    at RouterResponseController.render (/home/drunkenponey/projects/the-4-horsemen/api/node_modules/@nestjs/core/router/router-response-controller.js:27:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
Elie G.
  • 1,514
  • 1
  • 22
  • 38

2 Answers2

1

If you're just serving regular HTML, not using template engines, you don't need to call app.setVewEngine(). Just set up your static directory and you'll be good to go. You can read more about this in this answer

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • The thing is that I don't want the user to be able to see/download these static files without being authenticated and the only way I found to ensure the user is authenticated is to *render* it from a controller's endpoint (in this case the `root()` function of *app.controller.ts*). However, if I do not specify a render engine I get a `no default engine specified` error. – Elie G. May 23 '21 at 22:59
  • 1
    `render` isn't supposed to be used if you aren't using a rendering engine. You should use `sendFile` instead to send back a static file. – Jay McDoniel May 23 '21 at 23:03
0

Try to use @Render('index') instead of @Render('index.html')

Centaur
  • 87
  • 1