Firebase 용 Cloud Functions를 구성하여 여러 파일에서 여러 기능을 배포하려면 어떻게해야하나요?


164

Firebase 용 Cloud 기능을 여러 개 만들고 한 프로젝트에서 동시에 모두 배포하고 싶습니다. 또한 각 기능을 별도의 파일로 분리하고 싶습니다. 현재 index.js에 둘 다 넣으면 여러 함수를 만들 수 있습니다.

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

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

그러나 foo와 bar를 별도의 파일에 넣고 싶습니다. 나는 이것을 시도했다 :

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

foo.js는

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

bar.js는

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

index.js에 모든 기능을 넣지 않고이를 수행 할 수있는 방법이 있습니까?


1
@JPVentura. 당신을 잘 이해하지 못합니다. 설명 해주십시오.
HuyLe

v1.0 용으로 업데이트 되었습니까? 문제가 있습니다 : stackoverflow.com/questions/50089807/…
tccpg288

2
참고로,이 공식 중포 기지 기능의 예를 몇 가지 들어 있습니다 .js통해 가져온 파일 require: github.com/firebase/functions-samples/tree/master/...
xanderiel

도움이 될 것입니다 : stackoverflow.com/questions/43486278/…
Ramesh-X

답변:


126

Ah, Firebase로드 노드 모듈 용 Cloud Functions는 정상적으로 작동하므로

구조:

/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
예를 들어 foo 모듈에 여러 기능을 가질 수 있습니까? 그렇다면 어떻게 구현하는 것이 더 낫습니까?
Alexander Khitev

1
foo에서 다른 내 보낸 함수에 다른 핸들러를 할당 할 수 있다고 가정합니다. exports.bar = functions.database.ref ( '/ foo'). onWrite (fooModule.barHandler); exports.baz = 함수 .database.ref ( '/ bar'). onWrite (fooModule.bazHandler);
jasonsirota

44
이 솔루션은 정보 (즉, 데이터베이스 경로)를 foo.js 및 bar.js에서 index.js로 옮기기 때문에이 파일이 마음에 들지 않습니다.
bvs

@bvs에 동의합니다. Ced가 좋은 접근 방식이라고 생각합니다. index.ts를 명확하게하기 위해 각 모듈을 명시 적으로 내 보내서 약간 수정하겠습니다. 예 : "./authenticationFunctions"에서 {newUser} 내보내기
Alan

2
필자의 원래 질문은 단순히 index.js 파일에 함수를 넣지 않고 하나의 프로젝트로 여러 함수를 배포하는 것에 관한 것이라고 생각합니다. 데이터베이스 정보를 전달하는 위치와 방법은 범위가 아닙니다. 나는 데이터베이스 액세스를 제어하고 foo.js와 bar.js에서 별도로 요구하는 별도의 모듈을 만들지 만 스타일 결정입니다.
jasonsirota

75

@jasonsirota의 답변은 매우 도움이되었습니다. 그러나 특히 HTTP 트리거 함수의 경우 더 자세한 코드를 보는 것이 유용 할 수 있습니다.

@jasonsirota의 답변과 동일한 구조를 사용하여 두 개의 서로 다른 파일에 두 개의 별도 HTTP 트리거 기능을 원한다고 가정 해보십시오.

디렉토리 구조 :

    /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'); 
}

index.js의 현재 구조가 나에게 잘 작동하지 않았습니다. 내가해야 할 일은 먼저 firebase 모듈을 가져온 다음 앱을 초기화 한 다음 다른 폴더에서 기능을 가져 오는 것입니다. 이렇게하면 내 앱이 먼저 초기화, 인증 및 앱을 미리 초기화 해야하는 기능을 가져옵니다.
tonkatata

47

업데이트 : 이 문서는 도움이되어야합니다 . 제 답변은이 문서보다 낫습니다.


다음은 타이프 스크립트로 개인적으로 수행 한 방법입니다.

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

이 작업을 수행하기 위해 두 가지 경고를 제공하여이 서문을 시작하겠습니다.

  1. index.ts 의 가져 오기 / 내보내기 순서
  2. db는 별도의 파일이어야합니다

포인트 2의 경우 왜 그런지 잘 모르겠습니다. Secundo 당신은 index, main 및 db의 구성을 정확히 존중해야 합니다 (적어도 시도해보십시오).

index.ts : 내보내기를 처리합니다. index.ts가 내보내기를 처리하는 것이 더 깨끗하다는 것을 알았습니다.

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

main.ts : 초기화를 다룹니다.

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

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

db.ts : db를 다시 내 보내면 이름이 짧아집니다.database()

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는 어떻게 생겼습니까? dist 폴더로 컴파일하고 gcloud 함수에 index.js가 어디에 있는지 알 수 있습니까? github에 코드가 있습니까? :)
bersling

@ choopage-JekBao 오랜만에 죄송합니다. 더 이상 프로젝트가 없습니다. 올바르게 기억한다면 firebase 설정에 디렉토리를 제공 할 수 있습니다 (기본적으로 공개되어 있음). 1 년 이상 지났지 만 잘못되었을 수도 있습니다
Ced

안녕하세요 @ ced-왜 내용이 db.ts들어갈 수 없습니다 main.ts(관리자 인스턴스화 후)? 또는 명확성 / 간단 성을 위해이 방법으로 분리 했습니까?
dsg38

1
@ dsg38이 지금 대답을 찾고 별도의 파일에 있어야하는 이유 정말 볼 수없는, 너무 오래 전에 게시했습니다 .. 나는 그것이 명확하게 생각
CED

21

Cloud / Firebase 기능과 함께 노드 8 LTS를 사용할 수있게되면 스프레드 연산자를 사용하여 다음을 수행 할 수 있습니다.

/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);
  });

수입이 점점 증가하는 것이 각 기능의 콜드 스타트를 늦추 었는지 또는 완전히 분리 된 많은 모듈이 별도로 개발되어야하는지 궁금합니다.
Simon Fakir

2
unexpected token ...index.js 내부 에서 eslint parting 오류가 발생 합니다.
토마스

아마도 당신은 Node 8을 사용하고 있지 않습니다
Luke Pighetti

@SimonFakir 좋은 질문입니다. 그것에 대해 뭔가 찾았습니까?
atereshkov

@atereshkov 예 아래 답변과 비슷한 "process.env.FUNCTION_NAME"을 사용하여 종속성을 포함하여 요청 된 함수 만로드하는 방법을 찾았습니다. 당신이 저에게 연락하는 경우에 참조로 내 레포를 공유 할 수 있습니다.
Simon Fakir

15

간단하게 유지하기 위해 (하지만 작업을 수행) 개인적으로 코드를 다음과 같이 구성했습니다.

나열한 것

├── /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';

중첩 레벨의 디렉토리에서 작동합니다. 디렉토리 내부의 패턴도 따르십시오.

@zaidfazil 답변에 신용


1
이것은 Typescript에 대한 가장 간단한 답변 중 하나입니다. 감사합니다. 예를 들어 firebase 데이터베이스의 단일 인스턴스화에 어떻게 대처합니까? admin.initializeApp(functions.config().firestore) const db = admin.firestore();이것을 어디에 두어야하며 foo and bar에서 어떻게 참조합니까?
elprl

이봐-왜 내용이 db.ts들어 가지 못하는가 index.ts(관리자 인스턴스화 후?). 또는 명확성 / 간단 성을 위해이 방법으로 분리 했습니까?
dsg38

@ dsg38 당신은 모두를 함께 섞을 수 있습니다, 이것은 분명합니다
Reza

10

바벨의 경우 / 흐름 은 다음과 같을 것이다 :

디렉토리 레이아웃

.
├── /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 -주요 수출

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


src/db.js -Postgres 용 Cloud SQL 클라이언트

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 클라이언트

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

firebase.initializeApp(config().firebase);

export default firebase.firestore();


src/someFuncA.js -기능 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 -기능 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 개요는 더 간단한 아키텍처 패턴으로 메소드를 다른 파일로 분리 하고 index.js 내의 한 줄로보냅니다. 파일 .

이 샘플에서 프로젝트의 아키텍처는 다음과 같습니다.

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 { ... }
  });

프로파일 파일 의 removeProfile메소드에 동일한 패턴이 사용 됩니다.


7

간단하게 유지하기 위해 (하지만 작업을 수행) 개인적으로 코드를 다음과 같이 구성했습니다.

나열한 것

├── /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,
};

중첩 레벨의 디렉토리에서 작동합니다. 디렉토리 내부의 패턴도 따르십시오.


Firebase가 현재 ES6 가져 오기 지시문을 지원하지 않는 노드 6.11을 지원하기 때문에 이것이 어떻게 작동하는지 알 수 없습니다.
Aodh

타이프 스크립트를 사용하는 경우 문제가 발생하지 않아야합니다. 최근에 대부분의 코드를 타이프 ​​스크립트로 이식했습니다.
zaidfazil

2
zaidfazil, 당신은 아마 당신의 대답에 전제 조건을 적어 두어야합니다. @ Aodh, Konstantin이 답변에서 설명한 것과 같은 방식으로 Babel을 사용하면 작동합니다. stackoverflow.com/questions/43486278/…
PostureOfLearning

1
감사합니다. 이것은 typescript 및 node 6과 함께 작동했습니다. :)
Ahmad Moussa

4
오히려 수입 및 확산 사업자와 재수출보다, 당신은하지 수 export * from './fooFunctions';export * from './barFunctions';index.ts에서?
whatsthatitspatpat

5

이 형식을 사용하면 진입 점에서 추가 기능 파일을 찾고 각 파일 내에서 각 기능을 자동으로 내보낼 수 있습니다.

기본 진입 점 스크립트

함수 폴더 내에서 모든 .js 파일을 찾아 각 파일에서 내 보낸 각 함수를 내 보냅니다.

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];
    }
  }
});

한 파일에서 여러 함수를 내보내는 예제

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 액세스 가능한 엔드 포인트는 적절하게 이름이 지정됩니다.

✔ 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

하나의 파일

몇 개의 추가 파일 (예 : 하나만)이있는 경우 다음을 사용할 수 있습니다.

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

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


이것이 회전하는 모든 함수 인스턴스에 대해 부팅시 과부하가 발생하지 않습니까?
Ayyappa

4

백그라운드 기능과 http 기능이있는이 프로젝트가 있습니다. 단위 테스트를위한 테스트도 있습니다. 클라우드 기능을 배포 할 때 CI / CD를 사용하면 훨씬 쉽게 생활 할 수 있습니다.

폴더 구조

|-- 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

참고 : utils/ 폴더는 기능 간 공유 코드입니다

함수 /index.js

여기서 필요한 모든 함수를 가져 와서 선언 할 수 있습니다. 여기에 논리가 없어도됩니다. 내 의견으로는 더 깨끗합니다.

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

변경 사항을 리포지토리로 푸시 할 때마다 지속적인 통합 및 배포는 어떻습니까? google google cloud build를 사용하여 사용할 수 있습니다 . 특정 시점까지 무료입니다 :)이 링크를 확인하십시오 .

./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

나는 당신이 말한대로 수출했지만 firebase deploy는 끝에있는 것을 감지합니다. 예 : 코드에 따라 module.exports.stripe = functions.https.onRequest (stripe);
OK200

@ OK200 firebase 명령 줄과 함께 사용하는 명령은 무엇입니까? 당신을 돕기 위해, 나는 약간의 코드를보아야 할 것이다
ajorquera

3

장기적으로 모든 클라우드 기능을 구성하는 좋은 방법이 있습니다. 나는 최근에 이것을했고 완벽하게 작동하고 있습니다.

내가 한 것은 트리거 엔드 포인트를 기반으로 각 클라우드 기능을 별도의 폴더로 구성하는 것이 었습니다. 모든 클라우드 함수 파일 이름은로 끝납니다 *.f.js. 예를 들어, 가지고 onCreate있고 onUpdate트리거 user/{userId}/document/{documentId}하면 두 개의 파일 onCreate.f.jsonUpdate.f.js디렉토리에 파일을 작성 functions/user/document/하면 함수의 이름이 지정 userDocumentOnCreate되고userDocumentOnUpdate 각각. (1)

다음은 샘플 디렉토리 구조입니다.

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

샘플 기능

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) : 원하는 이름을 사용할 수 있습니다. 나에게 onCreate.f.js, onUpdate.f.js 등은 트리거의 종류와 더 관련이있는 것 같습니다.


1
이 방법은 정말 좋습니다. 당신이 예를 들어 서로 다른 API를 버전 (API v1을, API v2를, 등)을 분리 할 수 있도록 함수 이름에서 슬래시를 할 수 있도록하기 위해 조정할 수 있는지 궁금 해서요
알렉스 Sorokoletov

동일한 프로젝트에서 다른 버전의 클라우드 기능을 유지하려는 이유는 무엇입니까? 디렉토리 구조를 약간 변경하여이를 수행 할 수 있지만, 기본적으로 index.js는 선택적으로 배치하거나 index.js에서 if-conditions를 사용하지 않으면 모든 클라우드 기능을 배치하여 결국 코드가 복잡
해질

1
나는 모든 것을 배치하는 것이 좋으며, 내가 넣은 기능 (http 트리거 된 기능)을 버전 화하고 싶습니다.
Alex Sorokoletov

모든 http 트리거가 자체 *.f.js파일 에있을 것으로 기대 합니다. 당신이 할 수있는 최소한 그것이 무엇인가 만들기 위해 접미사를 앞에 붙이는 모든 버전에 해당하는 파일의 이름을 변경한다 *.v1.f.js또는 *.v2.f.js등 (당신의 HTTP 트리거의 모든의 모든 버전을 가정 살고 있습니다). 더 나은 솔루션이 있으면 알려주세요.
krhitesh

1

vanilla JS 부트 로더를 사용하여 사용하려는 모든 기능을 자동으로 포함시킵니다.

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

index.js (부트 로더)

/**
 * 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))
        }
      })
    }
  }
})

이 예제 index.js 파일은 루트 내의 디렉토리 만 자동으로 포함합니다. 디렉토리를 걷고, .gitignore 등을 존중하도록 확장 될 수 있습니다. 이것은 나에게 충분했습니다.

인덱스 파일이 있으면 새 기능을 추가하는 것이 쉽지 않습니다.

/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 수율 :

λ ~/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

이 워크 플로우는 새로운 함수 / 파일이 추가 / 수정 / 제거 될 때마다 index.js 파일을 수정하지 않고도 "쓰기 및 실행"과 거의 비슷합니다.


콜드 스타트하지 않습니까?
Ayyappa

1

typescript를 사용하여 클라우드 함수를 만드는 경우 간단한 대답이 있습니다.

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

상단의 모든 일반 가져 오기 근처에서의 모든 함수를 내보내십시오 foo.ts.

export * from './foo';


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.