【问题标题】:How do I use `import` for npm modules in Firebase Cloud Functions?如何在 Firebase Cloud Functions 中对 npm 模块使用 `import`?
【发布时间】:2022-12-13 10:23:00
【问题描述】:

我的 JavaScript Firebase Cloud Functions 正在使用通过 require 导入的 npm 模块运行。现在我想使用通过import而不是require安装的 npm 模块。 Firebase 模拟器抛出此错误:

 SyntaxError: Cannot use import statement outside a module

Node.js documentation 说:

import声明

import 语句可以引用 ES 模块或 CommonJS 模块。 import语句只允许在 ES 模块中使用, 但是 CommonJS 支持动态的 import() 表达式来加载 ES模块。

导入 CommonJS 模块时,提供了 module.exports 对象 作为默认导出。命名导出可能可用,由 静态分析为更好的生态系统兼容性提供了便利。

要求

CommonJS 模块require 总是处理它的文件 引用为 CommonJS。

不支持使用 require 加载 ES 模块,因为 ES 模块 有异步执行。相反,使用 import() 来加载一个 ES 来自 CommonJS 模块的模块。

如果我理解正确,Node 模块可以是ESCommonJSimport 处理这两种类型,require 只处理CommonJS

该文档还建议我的 Cloud Function 也需要是一个 ES 模块才能使用 import。错误信息应该说:

SyntaxError: 不能在外部使用 import 语句ES模块

这似乎是问题所在:我的 Cloud Functions 不在 ES 模块中。如何为我的 Cloud Functions 制作 ES 模块?

重现错误

以下是重现错误的方法。创建一个新目录并安装 Firebase,遵循 official documentation

npm install -g firebase-tools
firebase init

选择Emulators

选择Create a new project

选择Functions EmulatorFirestore Emulator

仿真器设置

接受默认端口。下载模拟器。

功能设置

选择TypeScript。不要使用 ESLint。安装依赖项。

模拟函数的执行

firebase emulators:start

这是默认的index.ts

import * as functions from "firebase-functions";

// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript
//
export const helloWorld = functions.https.onRequest((request, response) => {
  functions.logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});

我还尝试了模块上 TypeScript documentation 中提供的模块:

import * as functions from "firebase-functions";

export default function helloWorld() {
    console.log("Hello, world!");
  }

修复 index.ts 的路径

functions/package.json 中的第一个错误是:

functions/lib/index.js does not exist, can't deploy Cloud Functions

通过打开functions/package.json 并更改来修复此问题

"main": "lib/index.js",

"main": "src/index.ts",

模块错误

下一个错误是

Cannot use import statement outside a module

这就是我被困的地方。这似乎是说我的 Firebase Cloud Functions 不在 ES 模块中。

包.json

This question说把"type": "module",放到functions/package.json中:

{
    "name": "functions",
    "type": "module",
    "scripts": {
        "build": "tsc",
        "build:watch": "tsc --watch",
        "serve": "npm run build && firebase emulators:start --only functions",
        "shell": "npm run build && firebase functions:shell",
        "start": "npm run shell",
        "deploy": "firebase deploy --only functions",
        "logs": "firebase functions:log"
    },
    "engines": {
        "node": "16"
    },
    "main": "src/index.ts",
    "dependencies": {
        "firebase-admin": "^11.2.0",
        "firebase-functions": "^4.0.1",
        "got": "^12.5.2"
    },
    "devDependencies": {
        "typescript": "^4.7.4"
    },
    "private": true
}

这并不能解决错误。

tsconfig.json文件

我打开tsconfig.json并将"module": "CommonJS",更改为"module": "ESNext",,并将"target": "es2017"更改为"target": "ESNext"This question 解释了ESNext 是什么。

模拟器继续抛出错误。这是我的tsconfig.json 文件:

{
  "compilerOptions": {
    "module": "ESNext",
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "outDir": "lib",
    "sourceMap": true,
    "strict": true,
    "target": "ESNext"
  },
  "compileOnSave": true,
  "include": [
    "src"
  ]
}

推荐 tsconfig.json

TypeScript Handbook推荐这个tsconfig.json

{
  "compilerOptions": {
    "target": "ES2015",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Recommended"
}

这会引发相同的错误。

配置错误

在默认的package.jsontsconfig.json 中显然存在不止一个错误配置。如果有人能告诉我如何正确配置这些,我会向firebase-tools 发出拉取请求。

我正在使用节点 18.1.0。 Firebase 推荐 Node 16。

handling dependencies 上的 Firebase Cloud Functions 文档说使用 require 和 JavaScript 云函数,import 和 TypeScript 云函数。

使用 Node.js require() 函数加载任何你需要的 Node.js 模块 已安装。也可以使用require()函数导入 您与函数一起部署的本地文件。

如果您使用 TypeScript 编写函数,请使用 import 语句 以相同的方式加载您已安装的任何 Node.js 模块。

如果 Node.js 文档是正确的,那没有意义。 require() 无法加载任何 Node 模块,它只处理 CommonJS 模块。关于 TypeScript 的段落似乎说您不能将 import 与 JavaScript Cloud Functions 一起使用。

ts节点

ts-node 会有帮助吗?

【问题讨论】:

  • 初始化 Cloud Functions 时,是否选择了 Typescript? Firebase 仅支持将 ES6 语法与 TS 结合使用。

标签: typescript firebase npm google-cloud-functions


【解决方案1】:

我对Configuring TypeScript tsconfig.json for ES modules? 的回答也回答了这个问题。

【讨论】:

    猜你喜欢
    • 2020-02-01
    • 2017-08-02
    • 1970-01-01
    • 2021-10-25
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多