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

在Node.js Firebase函数中导入JSX文件失败的问题排查

解决Firebase函数中导入React JSX文件时的模块找不到问题

问题场景

我在Node.js Firebase函数中尝试导入React JSX文件TestEmail.jsx,导入代码:

import TestEmail from "./TestEmail.jsx";

函数完整代码:

import {SendGridHelper} from "./sendgrid";
import {logError} from "../../../../../helpers/logger";
import TestEmail from "./TestEmail.jsx";
import {render} from '@react-email/render';

export async function getSendEmail(): Promise<void> {
  const sendGridHelper = new SendGridHelper(process.env.SENDGRID_API_KEY);

  const emailHtml = render(TestEmail({ username: "Bob" }));

  await sendGridHelper
      .sendEmail(
          "Test",
          {
            name: "Name",
            email: "noreply@example.com",
          },
          "bob@example.com",
          {
            html: emailHtml,
          },
      )
      .catch((e) => {
        logError(
            e,
            "Error sending email",
            `Test`,
            JSON.stringify(e?.response.body)
        );
      });
}

路由配置:

setupRoutes(
  app,
  [
    {
      path: "/v1/public/profiles/email",
      method: HttpMethod.GET,
      func: getSendEmail,
    },
  ],
  true
);

export const publicProfiles = https.onRequest(app);

React邮件组件代码:

import {
    Body,
    Container,
    Font,
    Head,
    Heading,
    Html,
    Preview,
    Tailwind,
} from '@react-email/components';

export const TestEmail = ({username = 'Bob', }) => {
    const previewText = `Join ${username}`;

    return (
        <Html>
            <Head>
                <Font
                    fontFamily="Inter"
                    fallbackFontFamily="Verdana"
                    webFont={{
                        url: 'https://fonts.googleapis.com/css?family=Inter&display=swap',
                    }}
                    fontWeight={400}
                    fontStyle="normal"
                />
            </Head>
            <Preview>{previewText}</Preview>
            <Tailwind>
                <Body className="bg-[#0f0f12] my-auto mx-auto font-sans">
                    <Container className="rounded-xl my-[40px] mx-auto p-[20px] max-w-[600px] bg-[#18181b]">
                        <Heading className="text-white text-[24px] font-normal text-center p-0 my-[30px] mx-0">
                            Join <strong>{username}</strong>
                        </Heading>
                    </Container>
                </Body>
            </Tailwind>
        </Html>
    );
};

export default TestEmail;

运行Firebase函数模拟器时出现报错:

⬢ functions: Failed to load function definition from source: FirebaseError: Failed to load function definition from source: Failed to generate manifest from function source: Error: Cannot find module './TestEmail.jsx'

IDE可正常定位文件,但模拟器报错,需解决该问题。


解决方案

1. 核对文件路径与大小写

  • 确认TestEmail.jsx与函数文件处于同一目录,注意Firebase部署环境为Linux,文件名区分大小写,需确保导入路径的大小写与实际文件名完全一致(比如testemail.jsx和TestEmail.jsx会被视为不同文件)。
  • 检查导入路径的层级是否正确,./代表当前目录,避免多写或漏写目录层级。

2. 配置Firebase函数支持JSX转译

Firebase函数默认不处理JSX语法,需添加构建工具支持:

  • TypeScript环境:在tsconfig.json中,确保include数组包含.jsx文件,同时compilerOptions设置:
    {
      "compilerOptions": {
        "jsx": "react-jsx",
        "moduleResolution": "node16"
      },
      "include": ["src/**/*.ts", "src/**/*.jsx"]
    }
    
  • JavaScript环境:使用Babel转译,在函数目录下创建babel.config.json:
    {
      "presets": ["@babel/preset-react", "@babel/preset-env"]
    }
    
    安装依赖:
    npm install @babel/core @babel/preset-react @babel/preset-env --save-dev
    
  • ESBuild配置:在firebase.json的functions节点添加ESBuild支持,指定JSX loader:
    "functions": {
      "source": "functions",
      "runtime": "nodejs18",
      "esbuild": {
        "loader": { ".jsx": "jsx" },
        "external": ["firebase-admin"]
      }
    }
    

3. 配置Node.js识别JSX扩展名

Node.js默认不支持.jsx作为模块扩展名,需在package.json中添加配置:

{
  "type": "module",
  "imports": {
    ".jsx": "./*.jsx"
  }
}

如果使用TypeScript,需在tsconfig.json的compilerOptions中设置:

"moduleResolution": "node16",
"allowJs": true,
"resolveJsonModule": true

4. 清理Firebase模拟器缓存

缓存可能导致文件检测异常,执行命令清理缓存后重启模拟器:

firebase emulators:start --clear-cache

也可手动删除函数目录下的node_modules/.cache文件夹(若存在)。

5. 确认文件被包含在构建输出中

检查函数的构建脚本,确保.jsx文件被正确转译或复制到构建输出目录。例如,若使用npm run build脚本,需确保构建工具(如ESBuild、Babel)将JSX文件处理为可执行的JavaScript文件。


内容的提问来源于stack exchange,提问作者strangeQuirks

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:05:44