Birden çok dosyadan birden çok işlevi dağıtmak için Firebase için Bulut İşlevlerini nasıl yapılandırabilirim?


164

Firebase için birden fazla Bulut Fonksiyonu oluşturmak ve hepsini aynı anda bir projeden dağıtmak istiyorum. Ayrıca her işlevi ayrı bir dosyaya ayırmak istiyorum. Şu anda ikisini birden index.js içine koyarsam şu anda birden fazla işlev oluşturabilirim:

exports.foo = functions.database.ref('/foo').onWrite(event => {
    ...
});

exports.bar = functions.database.ref('/bar').onWrite(event => {
    ...
});

Ancak foo ve bar'ı ayrı dosyalara koymak istiyorum. Bunu denedim:

/functions
|--index.js (blank)
|--foo.js
|--bar.js
|--package.json

burada foo.js

exports.foo = functions.database.ref('/foo').onWrite(event => {
    ...
});

ve bar.js

exports.bar = functions.database.ref('/bar').onWrite(event => {
    ...
});

İndex.js içindeki tüm işlevleri koymadan bunu başarmanın bir yolu var mı?


1
@JPVentura. Gerçekten seni iyi anlamıyorum. Lütfen açıkla.
HuyLe

Bu sürüm v1.0 için güncellendi mi?
Sorun

2
Bilginize, bu resmi Firebase işlevleri örneği, .jsüzerinden içe aktarılan birkaç dosya içerir require: github.com/firebase/functions-samples/tree/master/…
xanderiel

Yanıtlar:


126

Ah, Firebase yük düğümü modülleri için Bulut İşlevleri normalde bu çalışır

yapısı:

/functions
|--index.js
|--foo.js
|--bar.js
|--package.json

index.js:

const functions = require('firebase-functions');
const fooModule = require('./foo');
const barModule = require('./bar');

exports.foo = functions.database.ref('/foo').onWrite(fooModule.handler);
exports.bar = functions.database.ref('/bar').onWrite(barModule.handler);

foo.js:

exports.handler = (event) => {
    ...
};

bar.js:

exports.handler = (event) => {
    ...
};

1
Örneğin foo modülünde birkaç fonksiyonum olabilir mi? Öyleyse, uygulamak nasıl daha iyi?
Alexander Khitev

1
Sanırım ve foo farklı ihraç işlevlerine farklı işleyicileri atamak: export.bar = function.database.ref ('/ foo'). OnWrite (fooModule.barHandler); export.baz = function.database.ref ('/ bar'). onWrite (fooModule.bazHandler);
jasonsirota

44
Foo.js ve bar.js bu ayrı dosyaları sahip olma noktasını yener index.js içine bilgi (yani veritabanı yolları) taşır çünkü bu çözümü sevmiyorum.
bvs

@Bvs ile hemfikirim, Ced'in iyi bir yaklaşımı olduğunu düşünüyorum. Ben index.ts süper net yapmak için her modülü açıkça ihraç ederek biraz değiştireceğim, örneğin "./authenticationFunctions" dan dışa aktarma {newUser}
Alan

2
Asıl sorum, index.js dosyasındaki işlevleri koymadan 1 proje ile birden fazla işlevi dağıtmakla ilgili olduğunu düşünüyorum, veritabanı bilgisini nereye ve nasıl aktardığınız kapsamda değil. Ben olsaydım, muhtemelen veritabanı erişimini kontrol eden ve foo.js ve bar.js'de ayrı olarak gerektiren ayrı bir modül yaratacağım, ancak bu stilistik bir karardır.
jasonsirota

75

@Jasonsirota tarafından cevap çok yardımcı oldu. Ancak, özellikle HTTP tarafından tetiklenen işlevlerde daha ayrıntılı kod görmek yararlı olabilir.

@ Jasonsirota'nın cevabı ile aynı yapıyı kullanarak, iki farklı dosyada iki ayrı HTTP tetikleme fonksiyonuna sahip olmak istediğinizi varsayalım:

dizin yapısı:

    /functions
       |--index.js
       |--foo.js
       |--bar.js
       |--package.json`

index.js:

'use strict';
const fooFunction = require('./foo');
const barFunction = require('./bar');

// Note do below initialization tasks in index.js and
// NOT in child functions:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase); 
const database = admin.database();

// Pass database to child functions so they have access to it
exports.fooFunction = functions.https.onRequest((req, res) => {
    fooFunction.handler(req, res, database);
});
exports.barFunction = functions.https.onRequest((req, res) => {
    barFunction.handler(req, res, database);
});

foo.js:

 exports.handler = function(req, res, database) {
      // Use database to declare databaseRefs:
      usersRef = database.ref('users');
          ...
      res.send('foo ran successfully'); 
   }

bar.js:

exports.handler = function(req, res, database) {
  // Use database to declare databaseRefs:
  usersRef = database.ref('users');
      ...
  res.send('bar ran successfully'); 
}

İndex.js'deki mevcut yapı benim için iyi sonuç vermedi. Yapmak zorunda olduğum şey ilk önce firebase modüllerini içe aktarmak, ardından uygulamayı başlatmak ve sonra işlevleri diğer klasörlerden almaktı. Bu şekilde uygulamam ilk önce her şeyi başlatır, doğrular ve ardından uygulamanın önceden başlatılması gereken işlevleri içe aktarır.
tonkatata

47

Güncelleme: Bu doküman yardımcı olmalı , cevabım bu dokümandan daha eski.


Şahsen daktilo ile bunu nasıl yaptım:

/functions
   |--src
      |--index.ts
      |--http-functions.ts
      |--main.js
      |--db.ts
   |--package.json
   |--tsconfig.json

Bunu yapmak için iki uyarı vererek bunu önceden yazayım:

  1. index.ts içindeki içe / dışa aktarma işlemlerinin sırası
  2. db ayrı bir dosya olmalıdır

2 numaralı nokta için neden emin değilim. Secundo dizin, ana ve db benim yapılandırmaya tam olarak saygı duymalısınız (en azından denemek için).

index.ts : ihracatla ilgilenir. Ben index.ts ihracat ile başa çıkmak için daha temiz buluyorum.

// main must be before functions
export * from './main';
export * from "./http-functions";

main.ts : Başlatma ile ilgilenir .

import { config } from 'firebase-functions';
import { initializeApp } from 'firebase-admin';

initializeApp(config().firebase);
export * from "firebase-functions";

db.ts : sadece adını db'den daha kısa olacak şekilde db'yi yeniden dışa aktarmadatabase()

import { database } from "firebase-admin";

export const db = database();

http-functions.ts

// db must be imported like this
import { db } from './db';
// you can now import everything from index. 
import { https } from './index';  
// or (both work)
// import { https } from 'firebase-functions';

export let newComment = https.onRequest(createComment);

export async function createComment(req: any, res: any){
    db.ref('comments').push(req.body.comment);
    res.send(req.body.comment);
}

tsconfig neye benziyor? dist klasörüne nasıl derleyebilirim ve gcloud işlevlerinin index.js dosyamın nerede olduğunu bilmesini sağlayabilirim? Github'da kodunuz var mı? :)
bersling

@ choopage-JekBao Üzgünüm uzun zaman oldu, artık projem yok. Doğru hatırlıyorsam, firebase yapılandırmasına bir dizin verebilirsiniz (varsayılan olarak geneldir). Bir yıldan fazla olduğu için yanılmış olabilirim
Ced

Hey @ced - neden olamaz içeriği db.tsgo iç main.ts(yönetici örnekleme sonra?). Yoksa netlik / basitlik için bu şekilde ayrıldınız mı?
dsg38

1
@ dsg38 Bu çok uzun zaman önce gönderildi, gerçekten neden cevabını bakarak ayrı bir dosyada olması gerektiğini gerçekten görmüyorum .. Ben netlik için olduğunu düşünüyorum
Ced

21

Cloud / Firebase İşlevleri ile kullanılabilen Düğüm 8 LTS ile spread operatörleriyle aşağıdakileri yapabilirsiniz:

/package.json

"engines": {
  "node": "8"
},

/index.js

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

module.exports = {
  ...require("./lib/foo.js"),
  // ...require("./lib/bar.js") // add as many as you like
};

/lib/foo.js

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

exports.fooHandler = functions.database
  .ref("/food/{id}")
  .onCreate((snap, context) => {
    let id = context.params["id"];

    return admin
      .database()
      .ref(`/bar/${id}`)
      .set(true);
  });

Artan ithalat sayısının her fonksiyonun soğuk başlangıcında yavaşladığını mı yoksa ayrı ayrı geliştirilen çok sayıda ayrılmış modülün olup olmadığını merak ediyorum.
Simon Fakir

2
unexpected token ...index.js içinde bir eslint parçalama hatası alıyorum .
thomas

Belki Düğüm 8'i kullanmıyorsunuz
Luke Pighetti

@SimonFakir güzel bir soru. Bununla ilgili bir şey buldun mu?
atereshkov

@atereshkov evet Sadece aşağıdaki cevaba benzer şekilde "process.env.FUNCTION_NAME" kullanarak bağımlılıkları da dahil olmak üzere istenen işlevi yüklemenin bir yolunu buldum. Benimle temasa geçerseniz ben de repo referans olarak paylaşabilirsiniz.
Simon Fakir

15

Basit tutmak için (ama iş yapar), kodumu böyle kişisel olarak yapılandırdık.

Yerleşim

├── /src/                      
   ├── index.ts               
   ├── foo.ts           
   ├── bar.ts
|   ├── db.ts           
└── package.json  

foo.ts

import * as functions from 'firebase-functions';
export const fooFunction = functions.database()......... {
    //do your function.
}

export const someOtherFunction = functions.database().......... {
    // do the thing.
}

bar.ts

import * as functions from 'firebase-functions';
export const barFunction = functions.database()......... {
    //do your function.
}

export const anotherFunction = functions.database().......... {
    // do the thing.
}

db.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

export const firestore = admin.firestore();
export const realtimeDb = admin.database();

index.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

admin.initializeApp(functions.config().firebase);
// above codes only needed if you use firebase admin

export * from './foo';
export * from './bar';

İç içe geçmiş seviyelerin dizinleri için çalışır. Sadece dizinlerin içindeki deseni de takip edin.

@zaidfazil cevabına kredi


1
Bu daktilo için en basit cevaplardan biri, teşekkürler. Örneğin, firebase veritabanının tek bir örneğiyle nasıl başa çıkabilirsiniz? admin.initializeApp(functions.config().firestore) const db = admin.firestore();Bunu nereye koyarsınız ve foo ve barda nasıl bahsedersiniz?
elprl

Hey - neden db.tsiçeri index.tsgiremiyor (yönetici örneğinden sonra?). Yoksa açıklık / basitlik için bu şekilde ayrıldınız mı?
dsg38

@ dsg38 hep birlikte karıştırabilirsiniz, bu açıkça gösteriyor
Reza

10

Babil / Flow durumunda bu şekilde görünecektir:

Dizin Düzeni

.
├── /build/                     # Compiled output for Node.js 6.x
├── /src/                       # Application source files
   ├── db.js                   # Cloud SQL client for Postgres
   ├── index.js                # Main export(s)
   ├── someFuncA.js            # Function A
   ├── someFuncA.test.js       # Function A unit tests
   ├── someFuncB.js            # Function B
   ├── someFuncB.test.js       # Function B unit tests
   └── store.js                # Firebase Firestore client
├── .babelrc                    # Babel configuration
├── firebase.json               # Firebase configuration
└── package.json                # List of project dependencies and NPM scripts


src/index.js - Ana ihracat)

export * from './someFuncA.js';
export * from './someFuncB.js';


src/db.js - Postgres için Cloud SQL İstemcisi

import { Pool } from 'pg';
import { config } from 'firebase-functions';

export default new Pool({
  max: 1,
  user: '<username>',
  database: '<database>',
  password: config().db.password,
  host: `/cloudsql/${process.env.GCP_PROJECT}:<region>:<instance>`,
});


src/store.js - Firebase Firestore İstemcisi

import firebase from 'firebase-admin';
import { config } from 'firebase-functions';

firebase.initializeApp(config().firebase);

export default firebase.firestore();


src/someFuncA.js - İşlev A

import { https } from 'firebase-functions';
import db from './db';

export const someFuncA = https.onRequest(async (req, res) => {
  const { rows: regions } = await db.query(`
    SELECT * FROM regions WHERE country_code = $1
  `, ['US']);
  res.send(regions);
});


src/someFuncB.js - İşlev B

import { https } from 'firebase-functions';
import store from './store';

export const someFuncB = https.onRequest(async (req, res) => {
  const { docs: regions } = await store
    .collection('regions')
    .where('countryCode', '==', 'US')
    .get();
  res.send(regions);
});


.babelrc

{
  "presets": [["env", { "targets": { "node": "6.11" } }]],
}


firebase.json

{
  "functions": {
    "source": ".",
    "ignore": [
      "**/node_modules/**"
    ]
  }
}


package.json

{
  "name": "functions",
  "verson": "0.0.0",
  "private": true,
  "main": "build/index.js",
  "dependencies": {
    "firebase-admin": "^5.9.0",
    "firebase-functions": "^0.8.1",
    "pg": "^7.4.1"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-jest": "^22.2.2",
    "babel-preset-env": "^1.6.1",
    "jest": "^22.2.2"
  },
  "scripts": {
    "test": "jest --env=node",
    "predeploy": "rm -rf ./build && babel --out-dir ./build src",
    "deploy": "firebase deploy --only functions"
  }
}


$ yarn install                  # Install project dependencies
$ yarn test                     # Run unit tests
$ yarn deploy                   # Deploy to Firebase

9

bigcodenerd.org anahattı, yöntemlerin farklı dosyalara ayrılması ve index.js içinde bir satıra aktarılması için daha basit bir mimari kalıptır. dosyasında .

Bu örnekteki projenin mimarisi aşağıdaki gibidir:

projectDirectory

  • index.js
  • podcast.js
  • profile.js

index.js

const admin = require('firebase-admin');
const podcast = require('./podcast');
const profile = require('./profile');
admin.initializeApp();

exports.getPodcast = podcast.getPodcast();
exports.removeProfile = profile.removeProfile();

podcast.js

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

exports.getPodcast = () => functions.https.onCall(async (data, context) => {
      ...
      return { ... }
  });

Profil dosyasındaki removeProfileyöntem için aynı desen kullanılır .


7

Basit tutmak için (ama iş yapar), kodumu böyle kişisel olarak yapılandırdık.

Yerleşim

├── /src/                      
   ├── index.ts               
   ├── foo.ts           
   ├── bar.ts           
└── package.json  

foo.ts

export const fooFunction = functions.database()......... {
    //do your function.
}

export const someOtherFunction = functions.database().......... {
    // do the thing.
}

bar.ts

export const barFunction = functions.database()......... {
    //do your function.
}

export const anotherFunction = functions.database().......... {
    // do the thing.
}

index.ts

import * as fooFunctions from './foo';
import * as barFunctions from './bar';

module.exports = {
    ...fooFunctions,
    ...barFunctions,
};

İç içe geçmiş seviyelerin dizinleri için çalışır. Sadece dizinlerin içindeki deseni de takip edin.


Firebase şu anda ES6 içe aktarma yönergelerini desteklemeyen Düğüm 6.11'i desteklediğinden bunun nasıl çalışabileceğini göremiyorum?
Aodh

Dizgi kullanıyorsanız, sorun asla ortaya çıkmamalıdır. Son zamanlarda benim kod çoğunu daktiloda port yaptım.
zaidfazil

2
zaidfazil, muhtemelen cevabınızdaki ön koşulları not etmelisiniz. @Aodh, Babel'i Konstantin'in yanıtında belirttiği şekilde kullanırsanız işe yarar. stackoverflow.com/questions/43486278/…
PostureOfLearning

1
teşekkür ederim. Bu daktilo ve düğüm 6 ile çalıştı :)
Ahmad Moussa

4
Aksine ithalat ve yayılma operatörleri ile yeniden ihracat yerine, sadece olamazdı export * from './fooFunctions';ve export * from './barFunctions';index.ts içinde?
whatsthatitspat

5

Bu biçim, giriş noktanızın ek işlev dosyaları bulmasını ve her dosyadaki her işlevi otomatik olarak dışa aktarmasını sağlar.

Ana Giriş Noktası Komut Dosyası

Function klasörü içindeki tüm .js dosyalarını bulur ve her dosyadan dışa aktarılan her işlevi dışa aktarır.

const fs = require('fs');
const path = require('path');

// Folder where all your individual Cloud Functions files are located.
const FUNCTIONS_FOLDER = './scFunctions';

fs.readdirSync(path.resolve(__dirname, FUNCTIONS_FOLDER)).forEach(file => { // list files in the folder.
  if(file.endsWith('.js')) {
    const fileBaseName = file.slice(0, -3); // Remove the '.js' extension
    const thisFunction = require(`${FUNCTIONS_FOLDER}/${fileBaseName}`);
    for(var i in thisFunction) {
        exports[i] = thisFunction[i];
    }
  }
});

Tek Bir Dosyadan Birden Çok İşlev Dışa Aktarma Örneği

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

const query = functions.https.onRequest((req, res) => {
    let query = req.query.q;

    res.send({
        "You Searched For": query
    });
});

const searchTest = functions.https.onRequest((req, res) => {
    res.send({
        "searchTest": "Hi There!"
    });
});

module.exports = {
    query,
    searchTest
}

http erişilebilir uç noktalar uygun şekilde adlandırılmıştır

✔ functions: query: http://localhost:5001/PROJECT-NAME/us-central1/query
✔ functions: helloWorlds: http://localhost:5001/PROJECT-NAME/us-central1/helloWorlds
✔ functions: searchTest: http://localhost:5001/PROJECT-NAME/us-central1/searchTest

Bir dosya

Yalnızca birkaç ek dosyanız varsa (örneğin, yalnızca bir tane), şunları kullanabilirsiniz:

const your_functions = require('./path_to_your_functions');

for (var i in your_functions) {
  exports[i] = your_functions[i];
}


Bunun, dönen her işlev örneği için önyükleme sırasında aşırı yüklenmesi olmaz mı?
Ayyappa

4

Yani arka plan fonksiyonları ve http fonksiyonları olan bu proje var. Birim testi için de testlerim var. CI / CD, bulut işlevlerini dağıtırken hayatınızı daha kolay hale getirecek

Klasör yapısı

|-- package.json
|-- cloudbuild.yaml
|-- functions
    |-- index.js
    |-- background
    |   |-- onCreate
    |       |-- index.js
            |-- create.js
    |
    |-- http
    |   |-- stripe
    |       |-- index.js
    |       |-- payment.js
    |-- utils
        |-- firebaseHelpers.js
    |-- test
        |-- ...
    |-- package.json

Not: utils/ klasör işlevler arasında paylaşım kodu içindir

işlevleri / index.js

Burada ihtiyacınız olan tüm fonksiyonları içe aktarabilir ve beyan edebilirsiniz. Burada mantığa gerek yok. Bence daha temiz.

require('module-alias/register');
const functions = require('firebase-functions');

const onCreate = require('@background/onCreate');
const onDelete = require('@background/onDelete');
const onUpdate = require('@background/onUpdate');

const tours  = require('@http/tours');
const stripe = require('@http/stripe');

const docPath = 'tours/{tourId}';

module.exports.onCreate = functions.firestore.document(docPath).onCreate(onCreate);
module.exports.onDelete = functions.firestore.document(docPath).onDelete(onDelete);
module.exports.onUpdate = functions.firestore.document(docPath).onUpdate(onUpdate);

module.exports.tours  = functions.https.onRequest(tours);
module.exports.stripe = functions.https.onRequest(stripe);

CI / CD

Değişikliklerinizi repoya her aktardığınızda sürekli entegrasyon ve dağıtım yapmaya ne dersiniz? Google google bulut derlemesini kullanarak buna sahip olabilirsiniz . Belli bir noktaya kadar ücretsiz :) Bu bağlantıyı kontrol edin .

./cloudbuild.yaml

steps:
  - name: "gcr.io/cloud-builders/npm"
    args: ["run", "install:functions"]
  - name: "gcr.io/cloud-builders/npm"
    args: ["test"]
  - name: "gcr.io/${PROJECT_ID}/firebase"
    args:
      [
        "deploy",
        "--only",
        "functions",
        "-P",
        "${PROJECT_ID}",
        "--token",
        "${_FIREBASE_TOKEN}"
      ]

substitutions:
    _FIREBASE_TOKEN: nothing

dediğin gibi ihraç var ama firebase konuşlandırma sonunda olanı algılar, ex: kodunuza göre sadece module.exports.stripe = function.https.onRequest (şerit) alır;
OK200

@ OK200 Firebase komut satırı ile kullandığınız komut nedir? Size yardımcı olmak için bir kod görmem gerekecek
ajorquera

3

Tüm bulut işlevlerinizi uzun vadede düzenlemenin oldukça iyi bir yolu var. Bunu son zamanlarda yaptım ve kusursuz çalışıyor.

Yaptığım şey, her bulut işlevini tetikleyici uç noktalarına göre ayrı klasörlerde düzenlemekti. Her bulut işlevi dosya adı ile biter *.f.js. Örneğin, üzerinde onCreateve onUpdatetetikleyicileriniz varsa, user/{userId}/document/{documentId}iki dosya onCreate.f.jsve onUpdate.f.jsdizinde oluşturun functions/user/document/ve işleviniz adlandırılır userDocumentOnCreateveuserDocumentOnUpdate sırasıyla . (1)

Örnek bir dizin yapısı:

functions/
|----package.json
|----index.js
/----user/
|-------onCreate.f.js
|-------onWrite.f.js
/-------document/
|------------onCreate.f.js
|------------onUpdate.f.js
/----books/
|-------onCreate.f.js
|-------onUpdate.f.js
|-------onDelete.f.js

Örnek İşlev

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const db = admin.database();
const documentsOnCreate = functions.database
    .ref('user/{userId}/document/{documentId}')
    .onCreate((snap, context) => {
        // your code goes here
    });
exports = module.exports = documentsOnCreate;

Index.js

const glob = require("glob");
const camelCase = require('camelcase');
const admin = require('firebase-admin');
const serviceAccount = require('./path/to/ServiceAccountKey.json');
try {
    admin.initializeApp({ credential: admin.credential.cert(serviceAccount),
    databaseURL: "Your database URL" });
} catch (e) {
    console.log(e);
}

const files = glob.sync('./**/*.f.js', { cwd: __dirname });
for (let f = 0, fl = files.length; f < fl; f++) {
    const file = files[f];
    const functionName = camelCase(file.slice(0, -5).split('/')); 
    if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === functionName) {
        exports[functionName] = require(file);
      }
}

(1): İstediğiniz herhangi bir ismi kullanabilirsiniz. Bana göre onCreate.f.js, onUpdate.f.js vb. Oldukları tetikleyicilerle daha alakalı görünüyorlar.


1
Bu yaklaşım gerçekten çok hoş. İşlev adlarında eğik çizgilere izin vermek için ayarlanmanın mümkün olup olmadığını merak ediyordum, böylece farklı api sürümlerini ayırabilirsiniz, örneğin (api v1, api v2, vb.)
Alex Sorokoletov

Neden bir bulut işlevinin farklı sürümlerini aynı proje altında tutmak istersiniz? Bunu dizin yapısını biraz değiştirerek yapabilmenize rağmen, varsayılan olarak index.js, seçici olarak dağıtmadığınız veya sonunda index.js'nizde kodunuzu karmaşıklaştıracak if-koşullarını kullanmadığınız sürece tüm bulut işlevlerini dağıtacaktır
krhitesh

1
Her şeyi konuşlandırmayla ilgili sorun yok, sadece koyduğum işlevleri versiyonlamak istiyorum (http ile tetiklenenler)
Alex Sorokoletov

Her http tetikleyicinin kendi *.f.jsdosyasında olmasını bekliyorum . Hiç olmazsa bir şey gibi yapmak ekini ekleyerek bu her versiyonu için dosyayı yeniden adlandırma olan *.v1.f.jsveya *.v2.f.jsvb (sizin http tetik tüm tüm sürümlerini varsayarsak yayında olduğundan). Daha iyi bir çözümünüz varsa lütfen bize bildirin.
krhitesh

1

Kullanmak istediğim tüm işlevleri otomatik olarak dahil etmek için bir vanilya JS önyükleyici kullanıyorum.

├── /functions
   ├── /test/
      ├── testA.js
      └── testB.js
   ├── index.js
   └── package.json

index.js (önyükleyici)

/**
 * The bootloader reads all directories (single level, NOT recursively)
 * to include all known functions.
 */
const functions = require('firebase-functions');
const fs = require('fs')
const path = require('path')

fs.readdirSync(process.cwd()).forEach(location => {
  if (!location.startsWith('.')) {
    location = path.resolve(location)

    if (fs.statSync(location).isDirectory() && path.dirname(location).toLowerCase() !== 'node_modules') {
      fs.readdirSync(location).forEach(filepath => {
        filepath = path.join(location, filepath)

        if (fs.statSync(filepath).isFile() && path.extname(filepath).toLowerCase() === '.js') {
          Object.assign(exports, require(filepath))
        }
      })
    }
  }
})

Bu örnek index.js dosyası yalnızca kök içindeki dizinleri otomatik olarak içerir. Dizinler yürümek, .gitignore, vb onur için genişletilebilir. Ama bu benim için yeterliydi.

Dizin dosyası hazır olduğunda, yeni işlevler eklemek önemsizdir.

/test/testA.js

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

exports.helloWorld = functions.https.onRequest((request, response) => {
 response.send("Hello from Firebase!");
});

/test/testB.js

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

exports.helloWorld2 = functions.https.onRequest((request, response) => {
 response.send("Hello again, from Firebase!");
});

npm run serve verim:

λ ~/Workspace/Ventures/Author.io/Firebase/functions/ npm run serve

> functions@ serve /Users/cbutler/Workspace/Ventures/Author.io/Firebase/functions
> firebase serve --only functions


=== Serving from '/Users/cbutler/Workspace/Ventures/Author.io/Firebase'...

i  functions: Preparing to emulate functions.
Warning: You're using Node.js v9.3.0 but Google Cloud Functions only supports v6.11.5.
✔  functions: helloWorld: http://localhost:5000/authorio-ecorventures/us-central1/helloWorld
✔  functions: helloWorld2: http://localhost:5000/authorio-ecorventures/us-central1/helloWorld2

Yeni bir işlev / dosya eklendiğinde / değiştirildiğinde / kaldırıldığında index.js dosyasını değiştirmek zorunda kalmadan bu iş akışı hemen hemen "yaz ve çalıştır" dır.


Bu soğuk başlangıçta olmayacak mı?
Ayyappa

1

İşte daktilo ile bulut fonksiyonları oluşturuyorsanız basit bir cevap.

/functions
|--index.ts
|--foo.ts

En üstteki tüm düzenli ithalatlarınızın yakınındaki tüm fonksiyonları dışa aktarın foo.ts.

export * from './foo';


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.