NestJS博客实战06-模版引擎

1,778 阅读5分钟
by 雪隐 from https://juejin.cn/user/1433418895994094
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可联系授权

这一章,主要介绍一下模版引擎NestJS中的运用。

NestJS 模版引擎介绍

在 NestJS 中,模板引擎可以通过视图模块进行配置和使用。NestJS 支持多种模板引擎,包括 Handlebars、Pug、EJS、Nunjucks 等。

以下是一个使用 Handlebars 模板引擎的示例:

  1. 安装 Handlebars 和 Handlebars Adapter:
pnpm i install handlebars @nestjs/plus
  1. app.module.ts 中导入 HandlebarsAdapter 和 HandlebarsModule,并将其添加到 imports 数组中:
import { Module } from '@nestjs/common';
import { HandlebarsAdapter, HandlebarsModule } from '@nestjs/plus';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    HandlebarsModule.forRoot({
      adapter: new HandlebarsAdapter(),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
  1. 创建一个 Handlebars 模板文件,比如 hello.hbs
<html>
  <head>
    <title>Hello</title>
  </head>
  <body>
    <h1>Hello, {{name}}!</h1>
  </body>
</html>
  1. 在控制器中返回视图:
import { Controller, Get, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('hello') // 渲染 hello.hbs 模板
  getHello() {
    return { name: 'NestJS' }; // 向模板传递数据
  }
}

在这个例子中,当访问根路由时,会渲染 hello.hbs 模板,并将 { name: 'NestJS' } 对象传递给模板。在模板中可以通过 {{name}} 获取传递的数据。

类似地,使用其他模板引擎也很类似,只需要替换相应的适配器和模块即可。

art-template 模版引擎

我使用的模版引擎是Art-template,它使用起来也非常方便,大家可以根据自己的情况来选择。

Art-template是一种简单、高效的JavaScript模板引擎,支持Node.js和浏览器环境。它采用简洁的语法、高速的执行效率和强大的功能,能够满足大多数Web开发需求。

使用art-template可以方便地将数据渲染到HTML模板中,生成最终的页面内容。它支持标准的HTML语法、嵌套模板、模板继承、条件判断、循环遍历等功能,并且具有较高的执行效率和稳定性。

Art-template支持预编译,在应用启动时将模板编译为JavaScript函数,提高渲染效率。它还支持自定义过滤器、助手函数和模板缓存等功能,可以根据具体的业务需求进行灵活配置。

Art-template的安装和使用非常简单,可以通过npm安装,也可以直接在浏览器中使用。它的文档详尽,提供了丰富的示例和API参考,非常适合初学者和有经验的开发人员使用。

art-template的基本使用请大家参照官方文档,个人认为模版引擎的学习成本并不是很高。所以就不多做介绍了。

在NestJS中使用 art-template

还记得之前的章节提到的,Nest底层我用的是fastify

要在 NestJS 中使用 Fastify 并使用 art-template 模版引擎, 在NestJS中并不是十分友好。这也是fastify相比于express这种老的框架而言的一个小缺点。解决方案比较少。

在查了一遍以后 Nest + fastify + 模版引擎这种没有可以参考的资料(至少本人没有特别好的解决方案,哪位大佬有好的方法也可以指点一下)。所以只能转换方向。调查源生fastify能否支持模版引擎,答案是肯定的。

  1. 首先,安装所需的模块:
pnpm install @nestjs/platform-fastify @fastify/static @fastify/view art-template
  1. 然后,在你的 NestJS 应用程序中,引入 FastifyAdapter 模块,并将其传递给 NestFactory.create() 方法:
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  
  // 配置模版引擎
  // 配置静态文件的路径(要用到许多js css image等等的静态文件)
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/',
  });
  // 原生支持模版引擎的方法。
  app.setViewEngine({
    engine: {
      'art-template': require('art-template'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  
  
  await app.listen(3000);
}
bootstrap();

这样,你的 NestJS 应用程序就会使用 Fastify 作为 Web 服务器。并且使用fastify的模版引擎

  1. 然后在根目录创建一个views文件夹, 新建一个text.art文件。里面的内容:
<div>{{ testVal }}</div>
  1. 最后,在路由控制器中渲染 art-template 视图。在这里由于没有很好的支持,只能参照 fastify官网, 为了要使用源生 fastify的能力,必须使用@Res() 来取到,fastify的Response对象。
import { Controller, Get, Req, Res } from '@nestjs/common';
import { TestService } from './test.service';

@Controller('test')
export class TestController {
  constructor(private readonly testService: TestService) {}

  @Get('index')
  getArticle(@Req() req, @Res() res) {
    res.view('text.art', {
      testVal: '这就是一个测是',
    });
  }
}
注意: 使用@Res()会导致 NestJS的拦截器失效,因为他用的是原生返回,所以NestJS中的钩子并不会被触发。在这里因为不需要拦截做统一的返回。所以问题不大。但是其他场景请大家谨慎使用。参考:https://docs.nestjs.com/interceptors#response-mapping

现在,你已经可以在 NestJS 中使用 Fastify 并使用 art-template 模板引擎了。

justtest.jpg

选择显示网页源代码,查看是否正确的被服务端渲染,这个很重要!用模版引擎就是为了SEO

resource.jpg

结论

这一章简单的讨论了下,NestJS的模版引擎。在需要SEO和服务端渲染的情况下,大家可以使用这种NestJS的方式来制作画面,本人最近也学习了下最新 Nuxt3,感觉上并不是特别的好用,遇到了许多奇怪的问题。原因可能是对这个框架不太熟悉。但是如果使用NestJS模版渲染的方式,除了这些基本的配置其他的都是在写 html + js这种基础的语言,上手的门槛是比较低的。灵活度也很高,想要服务端渲染就写路由调用 art 文件,想要客户端渲染,就写 ajax调用NestJS中的RestAPI,这些完全都能自己掌控的。

后面一个章节 会比较简单,把基本博客画面全部用模版引擎的方式导入进来。

最后,如果大家觉得这篇文章对您有帮助,别忘了点赞/评论。谢谢大家!

本章代码

代码