【发布时间】: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 模块可以是
ES或CommonJS,import处理这两种类型,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 Emulator和Firestore 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.json和tsconfig.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