多仓库部署Firebase Functions不删已有函数及自动提取函数名方案
解决方案:多仓库Firebase Functions自动化部署不删除已有函数
一、自动提取当前仓库的函数名生成部署命令
如果不想手动维护函数列表,可以写一个脚本自动扫描src目录下所有导出的Firebase Functions,生成部署所需的目标列表。
1. 编写提取脚本
创建extract-functions.js文件,放在项目根目录:
const fs = require('fs'); const path = require('path'); const srcDir = './src'; const functionNames = new Set(); // 用Set避免重复函数名 function scanFiles(dir) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { scanFiles(fullPath); } else if (/\.(js|ts)$/.test(entry.name) && !entry.name.includes('.test.')) { const content = fs.readFileSync(fullPath, 'utf8'); // 匹配两种导出语法:exports.func = ... 或 export const func = ... const regex = /(exports\.|export\s+const\s+)([a-zA-Z0-9_]+)\s*=\s*functions\./g; let match; while ((match = regex.exec(content)) !== null) { functionNames.add(match[2]); } } } } scanFiles(srcDir); // 转换成deploy命令需要的格式 const deployTargets = Array.from(functionNames).map(name => `functions:${name}`).join(','); console.log(deployTargets);
2. 在GitHub Actions中集成
在你的GitHub Actions workflow文件(比如.github/workflows/deploy-functions.yml)中加入以下步骤:
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 - name: Install dependencies run: npm install - name: Extract function names id: get-functions run: echo "targets=$(node extract-functions.js)" >> $GITHUB_ENV - name: Deploy to Firebase run: npx firebase deploy --only ${{ env.targets }} env: FIREBASE_TOKEN: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_TOKEN }}
注意:提前在GitHub仓库的Secrets中配置
FIREBASE_SERVICE_ACCOUNT_TOKEN,可以通过firebase login:ci命令生成该token。
二、更优架构方案:彻底避免函数名维护
如果长期维护20+函数,自动提取脚本还是有适配成本(比如函数导出语法变化时需要更新正则),可以考虑以下两种更省心的方案:
1. 为每个服务的函数添加统一前缀
给当前仓库所有函数加上唯一前缀(比如user_、payment_),这样部署时可以用通配符批量指定,不用逐个列函数名:
// 示例:统一前缀封装 const functions = require('firebase-functions'); const SERVICE_PREFIX = 'user_'; // 导出带前缀的函数 exports[`${SERVICE_PREFIX}createProfile`] = functions.https.onRequest((req, res) => { // 业务逻辑 }); exports[`${SERVICE_PREFIX}deleteProfile`] = functions.firestore.document('users/{uid}').onDelete((snap) => { // 业务逻辑 });
部署命令简化为:
firebase deploy --only functions:user_*
这种方式完全不用维护函数列表,只要前缀唯一,就不会影响其他仓库的函数。
2. 使用独立Firebase项目隔离服务
将不同服务的函数部署到各自独立的Firebase项目中,这样直接运行firebase deploy --only functions即可,完全不会干扰其他项目的函数。这种方案隔离性最强,适合服务之间依赖弱、需要独立权限控制的场景。
内容的提问来源于stack exchange,提问作者Nino Matos
相关产品推荐
相关产品推荐

