You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Nest.js中用Puppeteer渲染EJS模板实现本地热重载可行吗?

解决Nest.js中Puppeteer+EJS的模板渲染与PDF生成问题

问题1:无法加载本地EJS模板文件

你的代码中直接使用file.buffer但未定义file变量,也没有正确读取本地EJS文件。需要通过文件系统模块定位并读取模板内容:

解决方案

  • 导入fs和path模块,处理文件路径与读取操作
  • 使用path.resolve拼接模板文件的绝对路径,避免相对路径定位错误
  • 用fs.readFileSync读取EJS文件的文本内容

问题2:Puppeteer的Buffer获取错误

const buffer: Buffer = await page;这行代码逻辑错误,page是Puppeteer的Page实例,不能直接转为Buffer。要生成PDF格式的Buffer,需要调用page.pdf()方法。

解决方案

替换错误代码为const buffer: Buffer = await page.pdf();,可按需配置PDF参数(如纸张格式、边距、背景渲染等)

修改后的完整服务代码

import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import * as data from './json/index.json';
import * as ejs from 'ejs';
import puppeteer, { Browser, Page } from 'puppeteer';

@Injectable()
export class RenderPayloadToBrowserService {

  async renderPayload(): Promise<Buffer> {
    try {
      // 定位并读取EJS模板文件(替换为你的实际文件路径)
      const templatePath = path.resolve(__dirname, './templates/index.ejs');
      const templateContent = fs.readFileSync(templatePath, 'utf-8');

      // 渲染EJS模板,传入JSON数据
      const content: string = ejs.render(templateContent, { data });

      // 启动Puppeteer浏览器
      const browser: Browser = await puppeteer.launch({ 
        headless: 'new', // 使用新版无头模式
        ignoreDefaultArgs: ['--disable-extensions'],
        args: ['--no-sandbox'] 
      });
      const page: Page = await browser.newPage();
      // 等待页面资源加载完成后再生成PDF
      await page.setContent(content, { waitUntil: 'networkidle0' });

      // 生成PDF Buffer
      const buffer: Buffer = await page.pdf({
        format: 'A4',
        printBackground: true,
        margin: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' }
      });

      await browser.close();
      return buffer;
    } catch (error) {
      console.error('渲染或PDF生成失败:', error);
      throw error;
    }
  }

  // 新增方法:返回渲染后的HTML用于浏览器预览(支持热重载)
  async renderHtml(): Promise<string> {
    const templatePath = path.resolve(__dirname, './templates/index.ejs');
    const templateContent = fs.readFileSync(templatePath, 'utf-8');
    return ejs.render(templateContent, { data });
  }
}

实现EJS编辑热重载

  1. 配置Nest热重载:修改nest-cli.json,开启静态文件监听:
{
  "compilerOptions": {
    "watchAssets": true,
    "assets": ["**/*.ejs"]
  }
}
  1. 新增预览路由:在控制器中添加路由返回渲染后的HTML,浏览器访问时修改EJS文件后刷新即可看到更新:
import { Controller, Get, Res } from '@nestjs/common';
import { Response } from 'express';
import { RenderPayloadToBrowserService } from './render-payload-to-browser.service';

@Controller()
export class AppController {
  constructor(private readonly renderService: RenderPayloadToBrowserService) {}

  // PDF生成路由(原Postman调用路由)
  @Get('generatePdf')
  async generatePdf(@Res() res: Response) {
    const buffer = await this.renderService.renderPayload();
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename="template.pdf"');
    res.send(buffer);
  }

  // 模板预览路由(支持热重载)
  @Get('renderTemplate')
  async renderTemplate(@Res() res: Response) {
    const html = await this.renderService.renderHtml();
    res.setHeader('Content-Type', 'text/html');
    res.send(html);
  }
}
  1. 启动热重载模式:使用nest start --watch命令启动应用,修改EJS文件后,Nest会自动重新编译,刷新浏览器的localhost:8016/renderTemplate即可看到最新模板效果。

内容的提问来源于stack exchange,提问作者Antonio Pavicevac-Ortiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:44:54