使用TypeScript开发Firebase Functions时,如何正确组织导出以避免Linter错误并保证部署路径符合预期?
作为TypeScript新手,你遇到的这个问题其实是ES模块语法与Firebase Functions部署规则的适配问题,不用禁用Linter也能完美解决。下面是具体的正确实践:
核心思路
Firebase Functions部署时,会根据你在入口文件(index.ts)中导出的函数名称来生成URL路径。只要保证导出的函数名是你预期的foo/bar,就能得到正确的/foo//bar路径。同时用标准ES模块的import/export语法,就能满足Linter的要求。
步骤1:编写模块文件(foo.ts/bar.ts)
在每个功能模块中,用命名导出定义你的Firebase函数:
// foo.ts import * as functions from "firebase-functions"; // 直接命名导出函数,名称就是你想要的URL路径名 export const foo = functions.https.onRequest((req, res) => { res.status(200).send("Hello from foo function!"); });
// bar.ts import * as functions from "firebase-functions"; export const bar = functions.https.onCall((data, context) => { return { message: "Hello from bar callable function!" }; });
步骤2:入口文件(index.ts)重导出函数
在入口文件中使用ES模块的重导出语法,把各个模块的函数直接导出,这样既简洁又符合Linter规则:
// index.ts // 直接从模块中导出指定函数,无需额外变量声明 export { foo } from './foo'; export { bar } from './bar';
步骤3:确认tsconfig.json配置
确保你的TypeScript配置文件(tsconfig.json)包含以下关键设置,让ES模块语法正确转译为Firebase支持的CommonJS格式:
{ "compilerOptions": { "module": "CommonJS", "target": "ES2018", "outDir": "lib", "esModuleInterop": true, "strict": true }, "include": ["src/**/*"] }
为什么之前的写法会出问题?
你尝试的import * as foo from './foo'然后exports.foo = foo.foo,其实本质是把模块对象里的函数属性赋值给导出对象,但如果不小心写成export { foo }(导出整个模块对象而非函数),Firebase会无法识别这是一个可部署的函数,甚至可能错误地拼接模块名和属性名生成/foo-foo路径。而用重导出语法,直接导出的是具体的函数,Firebase能准确识别函数名称,生成预期的URL。
部署时运行firebase deploy --only functions,就能得到你想要的https://<region>-<project-id>.cloudfunctions.net/foo和https://<region>-<project-id>.cloudfunctions.net/bar路径了。
内容的提问来源于stack exchange,提问作者Shackleford

