如何在NestJS框架及NestExpressApplication中正确使用Nunjucks模板?
Hey there! I've helped a lot of folks set up Nunjucks with NestJS, so let's walk through both your questions step by step—starting with the general setup, then diving into the specific tweaks needed for NestExpressApplication.
First, let's cover the basic setup that works for most NestJS projects using the Express platform (the default):
Install dependencies: You'll need
nunjucks(the template engine) and ensure you have@nestjs/platform-express(included by default in new projects, but install it if missing):npm install nunjucks @nestjs/platform-expressConfigure your AppModule: Use
ViewModuleto register Nunjucks as your view engine, and set up your template directory and static assets (if needed):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'; import { ViewModule } from '@nestjs/core'; @Module({ imports: [ // Serve static files (CSS/JS) from the "public" folder ServeStaticModule.forRoot({ rootPath: join(__dirname, '..', 'public'), serveRoot: '/static', }), // Register Nunjucks as the view engine ViewModule.forRoot({ engine: { ext: 'njk', // File extension for your templates use: require('nunjucks'), }, viewsDir: join(__dirname, '..', 'views'), // Path to your template files }), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}Render templates in your controller: Use the
@Render()decorator to specify which template to use, and pass data to it via the controller method's return value:import { Controller, Get, Render } from '@nestjs/common'; import { AppService } from './app.service'; @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get() @Render('index') // Matches views/index.njk getHello() { // Data passed to the template return { message: 'Hello from Nunjucks in NestJS!' }; } }Create your first template: Make a
viewsfolder in your project root, addindex.njk:<h1>{{ message }}</h1> <p>This is a basic Nunjucks template!</p>
If you're explicitly working with NestExpressApplication (to access Express-specific features), manually configure the Nunjucks environment for more control—this avoids conflicts and lets you add custom filters, globals, or tweak template behavior.
Here's how to do it right:
Bootstrap your app with NestExpressApplication: In
main.ts, create the app instance asNestExpressApplicationand configure Nunjucks directly:import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { NestExpressApplication } from '@nestjs/platform-express'; import { join } from 'path'; import * as nunjucks from 'nunjucks'; async function bootstrap() { // Create the NestExpressApplication instance const app = await NestFactory.create<NestExpressApplication>(AppModule); // Configure Nunjucks environment with Express integration const nunjucksEnv = nunjucks.configure( join(__dirname, '..', 'views'), // Template directory { express: app.getHttpAdapter().getInstance(), // Link to Nest's underlying Express app autoescape: true, // Enable auto-escaping to prevent XSS (recommended) watch: process.env.NODE_ENV !== 'production', // Auto-reload templates in development noCache: process.env.NODE_ENV !== 'production', // Disable cache in development } ); // Add custom globals (available in all templates) nunjucksEnv.addGlobal('appName', 'My Awesome NestJS App'); // Add custom filters (transform data in templates) nunjucksEnv.addFilter('uppercase', (str: string) => str.toUpperCase()); // Set the view engine to use .njk files app.setViewEngine('njk'); await app.listen(3000); } bootstrap();Use template inheritance (a key Nunjucks feature): Leverage Nunjucks' powerful inheritance by creating a layout template
views/layout.njk:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ appName }}</title> <link rel="stylesheet" href="/static/styles.css"> </head> <body> <header> <h1>{{ appName }}</h1> </header> {% block content %}{% endblock %} <!-- Content from child templates goes here --> </body> </html>Update your
index.njkto extend this layout:{% extends "layout.njk" %} {% block content %} <h2>{{ message | uppercase }}</h2> <p>This content is injected into the layout template!</p> {% endblock %}Key Notes for NestExpressApplication:
- Skip the
engineconfiguration inViewModule.forRoot()when manually setting up Nunjucks—they can conflict if both try to register the engine. - The
watchandnoCacheoptions are crucial for development, but disable them in production to improve performance. - Using
app.getHttpAdapter().getInstance()ensures you're linking Nunjucks to the exact Express instance Nest is using, avoiding unexpected behavior.
- Skip the
内容的提问来源于stack exchange,提问作者avilang

