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

Firebase Functions部署报错:ES模块与CommonJS语法冲突求助

问题:Firebase Functions部署Twilio+OpenAI WhatsApp应用时的模块语法冲突

问题描述

基于教程开发结合Twilio与OpenAI的WhatsApp聊天应用,核心功能通过Firebase Functions实现,部署时遭遇模块语法冲突:

  • 保留package.json中"type":"module"配置时,报错:

Error: Failed to load function definition from source: Failed to generate manifest from function source: ReferenceError: require is not defined in ES module scope, you can use import instead

  • 移除"type":"module"配置后,报错:

Error: Failed to load function definition from source: Failed to generate manifest from function source: SyntaxError: Cannot use import statement outside a module

尝试将OpenAI模块移至node_modules目录,问题未解决。

相关代码

const functions = require("firebase-functions");

import {
  Configuration,
  OpenAIApi
  } from "openai";

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});

const openAI = new OpenAIApi(configuration);

export default async function handler(req, res) {
    const MessagingResponse = require('twilio').twiml.MessagingResponse;
    var messageResponse = new MessagingResponse();
    const sentMessage = req.body.Body || '';
    
    let replyToBeSent = "";
    
    if (sentMessage.trim().length === 0) {
        replyToBeSent = "We could not get your message. Please try again";
    } else {
        try {
            const completion = await openAI.createCompletion({
                model: "text-davinci-003", // required
                prompt: req.body.Body, // completion based on this
                temperature: 0.6,
                n: 1,
                max_tokens: 50,
                // stop: "."
            });
        
            replyToBeSent = removeIncompleteText(completion.data.choices[0].text)

        } catch (error) {
            if (error.response) {
                replyToBeSent = "There was an issue with the server"
            } else { // error getting response
                replyToBeSent = "An error occurred during your request.";
            }
        }
    }

    messageResponse.message(replyToBeSent);
    // send response
    res.writeHead(200, {
        'Content-Type': 'text/xml'
    });
    res.end(messageResponse.toString());
}

// trims out the words/char that may be left hanging by chatgpt because the character(token) limit is reached for a response
function removeIncompleteText(inputString) {
    const match = inputString.match(/\b\.\s\d+/g);
    const removeAfter = match ? inputString.slice(0, inputString.lastIndexOf(match[match.length - 1])) : inputString;
    return removeAfter
}

package.json配置

{
  "name": "appName",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "scripts": {
     "lint": "eslint .",
     "serve": "firebase emulators:start --only functions",
     "shell": "firebase functions:shell",
     "start": "npm run shell",
     "deploy": "firebase deploy --only functions",
     "logs": "firebase functions:log",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
  "engines": {
    "node": "16"
  },
  "main": "index.js",
  "dependencies": {
    "firebase-admin": "^11.5.0",
    "firebase-functions": "^4.2.0",
    "next": "^13.2.4",
    "openai": "^3.2.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "twilio": "^4.9.0"
  },
  "devDependencies": {
    "eslint": "^8.15.0",
    "eslint-config-google": "^0.14.0",
    "firebase-functions-test": "^3.0.0"
  },
 "private": true,
 "keywords": [],
 "author": "",
 "license": "ISC"
}

解决方案

问题根源是代码混合使用了CommonJS(require)和ES模块(import/export)语法,Firebase Functions要求统一模块规范,以下是两种可行方案:

方案1:统一使用ES模块(保留"type":"module")

将所有require替换为import,并调整Firebase函数导出方式:

  1. 替换const functions = require("firebase-functions");为:
import functions from "firebase-functions";
  1. 替换const MessagingResponse = require('twilio').twiml.MessagingResponse;为:
import { twiml } from 'twilio';
const MessagingResponse = twiml.MessagingResponse;
  1. 将export default async function handler(...)改为命名导出:
export const handler = functions.https.onRequest(async (req, res) => { ... })

修改后的完整代码:

import functions from "firebase-functions";
import { Configuration, OpenAIApi } from "openai";
import { twiml } from 'twilio';

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});

const openAI = new OpenAIApi(configuration);
const MessagingResponse = twiml.MessagingResponse;

export const handler = functions.https.onRequest(async (req, res) => {
    var messageResponse = new MessagingResponse();
    const sentMessage = req.body.Body || '';
    
    let replyToBeSent = "";
    
    if (sentMessage.trim().length === 0) {
        replyToBeSent = "We could not get your message. Please try again";
    } else {
        try {
            const completion = await openAI.createCompletion({
                model: "text-davinci-003",
                prompt: req.body.Body,
                temperature: 0.6,
                n: 1,
                max_tokens: 50,
            });
        
            replyToBeSent = removeIncompleteText(completion.data.choices[0].text)

        } catch (error) {
            if (error.response) {
                replyToBeSent = "There was an issue with the server"
            } else {
                replyToBeSent = "An error occurred during your request.";
            }
        }
    }

    messageResponse.message(replyToBeSent);
    res.writeHead(200, {
        'Content-Type': 'text/xml'
    });
    res.end(messageResponse.toString());
});

function removeIncompleteText(inputString) {
    const match = inputString.match(/\b\.\s\d+/g);
    const removeAfter = match ? inputString.slice(0, inputString.lastIndexOf(match[match.length - 1])) : inputString;
    return removeAfter;
}

方案2:统一使用CommonJS(移除"type":"module")

将所有import/export替换为require和module.exports:

  1. 替换import { Configuration, OpenAIApi } from "openai";为:
const { Configuration, OpenAIApi } = require("openai");
  1. 将export default async function handler(...)改为:
exports.handler = functions.https.onRequest(async (req, res) => { ... });

额外注意事项

  • 确保package.json的main字段指向正确的入口文件(此处为index.js)。
  • Firebase Functions Node.js 16支持两种模块规范,但必须统一,禁止混合使用。
  • 无需手动移动node_modules中的模块,npm install会自动处理依赖位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:34:57