Como estruturo o Cloud Functions for Firebase para implantar várias funções de vários arquivos?


164

Gostaria de criar várias funções de nuvem para o Firebase e implantá-las todas ao mesmo tempo em um projeto. Eu também gostaria de separar cada função em um arquivo separado. Atualmente, posso criar várias funções se colocá-las no index.js, como:

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

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

No entanto, eu gostaria de colocar foo e bar em arquivos separados. Eu tentei isso:

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

onde está foo.js

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

e bar.js é

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

Existe uma maneira de fazer isso sem colocar todas as funções no index.js?


1
@JPVentura. Realmente não te entendo bem. Por favor explique.
— HuyLe

Isso foi atualizado para a v1.0? Estou tendo problemas: stackoverflow.com/questions/50089807/…
— tccpg288

2
FYI, este funções Firebase oficial exemplo contém vários .jsarquivos importados através de require: github.com/firebase/functions-samples/tree/master/...
— xanderiel

Respostas:


126

Ah, o Cloud Functions para Firebase carrega módulos de nó normalmente, então isso funciona

estrutura:

/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
Por exemplo, posso ter várias funções no módulo foo? Se sim, como é melhor implementá-lo?
— Alexander Khitev

1
Suponho que você possa atribuir diferentes manipuladores a diferentes funções exportadas de foo: export.bar = functions.database.ref ('/ foo'). OnWrite (fooModule.barHandler); export.baz = funções.database.ref ('/ bar'). onWrite (fooModule.bazHandler);
— Jasonsirota 19/05

44
Eu não gosto dessa solução porque move as informações (ou seja, os caminhos do banco de dados) de foo.js e bar.js para index.js, o que meio que anula o ponto de ter esses arquivos separados.
— bvs

Concordo com @bvs, acho que Ced tem uma boa abordagem. Eu vou modificá-lo ligeiramente exportando explicitamente cada módulo para fazer a index.ts super claro exemplo de exportação {newuser} de "./authenticationFunctions"
— Alan

2
Acho que minha pergunta original era simplesmente implantar várias funções com um projeto sem colocar as funções no arquivo index.js, onde e como você passa as informações do banco de dados não estão no escopo. Se fosse eu, provavelmente criaria um módulo separado que controlava o acesso ao banco de dados e o exigia em foo.js e bar.js separadamente, mas essa é uma decisão estilística.
— Jasonsirota # 3/17

75

A resposta de @jasonsirota foi muito útil. Mas pode ser útil ver um código mais detalhado, especialmente no caso de funções acionadas por HTTP.

Usando a mesma estrutura da resposta de @ jasonsirota, digamos que você queira ter duas funções de gatilho HTTP separadas em dois arquivos diferentes:

estrutura de diretórios:

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

A estrutura atual no index.js não funcionou bem para mim. O que eu precisava fazer era primeiro importar os módulos do firebase, inicializar o aplicativo e depois importar as funções das outras pastas. Dessa maneira, meu aplicativo inicializa, autentica, seja qual for, e depois importa as funções que precisam que o aplicativo seja inicializado antecipadamente.
— tonkatata

47

Atualização: este documento deve ajudar , minha resposta é mais antiga que este documento.


Aqui está como eu pessoalmente fiz isso com texto datilografado:

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

Permitam-me que anteceda isso, dando dois avisos para que isso funcione:

  1. a ordem de importação / exportação é importante em index.ts
  2. o banco de dados deve ser um arquivo separado

Para o ponto número 2, não sei por que. Secundo, você deve respeitar minha configuração de index, main e db exatamente (pelo menos para testá-lo).

index.ts : trata de exportação. Acho mais fácil deixar o index.ts lidar com as exportações.

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

main.ts : Lida com a inicialização.

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

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

db.ts : basta reexportar o db para que seu nome seja menor quedatabase()

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

como é o seu tsconfig? como posso compilar em uma pasta dist e informar às funções do gcloud onde está o meu index.js? Você tem seu código no github? :)
— bersling

@ choopage-JekBao desculpe, já faz muito tempo, eu não tenho mais o projeto. Se bem me lembro, você pode dar à firebase config um diretório (que é público por padrão). Eu posso estar errado embora desde já faz mais de um ano
— Ced

Hey @ced - por que o conteúdo de não pode db.tsentrar main.ts(após a instanciação do administrador?). Ou você acabou de se separar dessa maneira por clareza / simplicidade?
— dsg38

1
@ dsg38 este foi publicado há muito tempo, eu realmente não vejo por que deveria ser em um arquivo separado olhando para a resposta agora .. eu acho que foi para maior clareza
— Ced

21

Com o Node 8 LTS agora disponível com as funções Cloud / Firebase, você pode fazer o seguinte com operadores espalhados:

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

Gostaria de saber se o número crescente de importações diminui o início a frio de cada função ou se deve haver muitos módulos totalmente separados, desenvolvidos separadamente?
— Simon Fakir

2
Eu recebo um erro de separação eslint unexpected token ...dentro do index.js.
— thomas

Talvez você não estiver usando Nó 8
— Lucas Pighetti

@SimonFakir good question. Você encontrou algo sobre isso?
— atereshkov 9/09/19

@atereshkov sim, encontrei uma maneira de carregar apenas a função solicitada, incluindo suas dependências usando "process.env.FUNCTION_NAME" semelhante à resposta abaixo. Também posso compartilhar meu repo como referência, se você estiver interessado, entre em contato comigo.
— Simon Fakir

15

Para ser simples (mas funciona), eu estruturei pessoalmente meu código assim.

Layout

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

Funciona para diretórios de qualquer nível aninhado. Apenas siga o padrão dentro dos diretórios também.

crédito para @zaidfazil resposta


1
Esta é uma das respostas mais simples para o Typecript, obrigado. Como você lida com uma única instanciação do banco de dados firebase, por exemplo? admin.initializeApp(functions.config().firestore) const db = admin.firestore();Onde você coloca isso e como você se refere a ele em foo e bar?
— Elprl

Ei - por que o conteúdo não pode db.tsentrar index.ts(após a instanciação do administrador?). Ou você acabou de se separar dessa maneira por clareza / simplicidade?
— dsg38 4/09/19

@ dsg38 você pode misturar todos juntos, isso deixa claro
— Reza

10

No caso de Babel / Flow , ficaria assim:

Layout do diretório

.
├── /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 - Principais exportações)

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


src/db.js - Cloud SQL Client para Postgres

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 - Cliente Firestore Firebase

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

firebase.initializeApp(config().firebase);

export default firebase.firestore();


src/someFuncA.js - Função 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 - Função 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

O esboço do bigcodenerd.org é um padrão de arquitetura mais simples para que os métodos sejam separados em arquivos diferentes e exportados em uma linha no index.js arquivo .

A arquitetura do projeto neste exemplo é a seguinte:

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

O mesmo padrão seria usado para o removeProfilemétodo no arquivo de perfil .


7

Para ser simples (mas funciona), eu estruturei pessoalmente meu código assim.

Layout

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

Funciona para diretórios de qualquer nível aninhado. Apenas siga o padrão dentro dos diretórios também.


Não vejo como isso poderia funcionar, pois o Firebase suporta o Nó 6.11 atualmente, que não suporta as diretivas de importação ES6?
— Aodh

Se você estiver usando texto datilografado, o problema nunca deve surgir. Ultimamente, portava a maior parte do meu código para texto datilografado.
— Zaidfazil

2
zaidfazil, você provavelmente deve anotar quaisquer pré-requisitos em sua resposta. @ Ah, funciona se você usar Babel da mesma maneira que Konstantin delineou em uma resposta. stackoverflow.com/questions/43486278/…
— PostureOfLearning

1
obrigado. isso funcionou com texto datilografado e nó 6 :)
— Ahmad Moussa

4
Em vez de importar e reexportar com operadores espalhados, você não poderia apenas ter export * from './fooFunctions';e export * from './barFunctions';no index.ts?
— whatsthatitspat

5

Esse formato permite que seu ponto de entrada encontre arquivos de funções adicionais e exporte cada função dentro de cada arquivo automaticamente.

Script do ponto de entrada principal

Localiza todos os arquivos .js dentro da pasta de funções e exporta cada função exportada de cada arquivo.

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

Exemplo de exportação de várias funções de um arquivo

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
}

pontos de extremidade acessíveis http são nomeados apropriadamente

✔ 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

Um arquivo

Se você tiver apenas alguns arquivos adicionais (por exemplo, apenas um), poderá usar:

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

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


Isso não terá sobrecarga na inicialização para todas as instâncias de função que surgirem?
— 21419 Ayyappa

4

Então, eu tenho esse projeto que tem funções em segundo plano e funções http. Eu também tenho testes para testes de unidade. O CI / CD facilitará sua vida ao implantar funções na nuvem

Estrutura de pastas

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

Nota: utils/ pasta é para compartilhar código entre funções

functions / index.js

Aqui você pode apenas importar todas as funções necessárias e declará-las. Não há necessidade de lógica aqui. Isso torna mais limpo na minha opinião.

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

Que tal ter integração e implantação contínuas toda vez que você envia suas alterações ao repositório? Você pode obtê-lo usando o google google cloud build . É grátis até um certo ponto :) Verifique este link .

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

Eu exportei como você disse, mas a implantação do Firebase detecta a que está no final, ex: conforme seu código, é necessário apenas module.exports.stripe = functions.https.onRequest (stripe);
— precisa saber é o seguinte

@ OK200 qual é o comando que você está usando com a linha de comando do firebase? Para ajudá-lo, eu vou ter de ver algum código
— ajorquera

3

Existe uma maneira muito boa de organizar todas as suas funções de nuvem a longo prazo. Eu fiz isso recentemente e está funcionando perfeitamente.

O que fiz foi organizar cada função da nuvem em pastas separadas com base no ponto de extremidade do acionador. Todo nome de arquivo da função de nuvem termina com *.f.js. Por exemplo, se você tiver ativado onCreatee onUpdateacionado user/{userId}/document/{documentId}, crie dois arquivos onCreate.f.jse onUpdate.f.jsno diretório, functions/user/document/e sua função será nomeada userDocumentOnCreateeuserDocumentOnUpdate respectivamente. (1)

Aqui está uma estrutura de diretório de exemplo:

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

Função de amostra

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): Você pode usar qualquer nome que desejar. Para mim, onCreate.f.js, onUpdate.f.js etc. parecem mais relevantes para o tipo de gatilho que são.


1
Essa abordagem é muito legal. Eu queria saber se é possível ajustar-se para permitir barras nos nomes de função para que você possa separar diferentes versões da API, por exemplo (v1 API, API v2, etc)
— Alex Sorokoletov

Por que você deseja manter versões diferentes de uma função de nuvem no mesmo projeto? Embora você possa fazer isso alterando levemente a estrutura do diretório, por padrão, index.js implementará todas as funções da nuvem, a menos que você implemente seletivamente ou use condições if em seu index.js que acabarão por sobrecarregar seu código
— krhitesh

1
Eu estou bem com a implantação de tudo, eu só quero a versão das funções que eu coloco (http desencadeadas)
— Alex Sorokoletov

Espero que cada gatilho http esteja em seu próprio *.f.jsarquivo. O mínimo que você pode fazer é renomear o arquivo para cada versão, acrescentando o sufixo para torná-lo algo parecido *.v1.f.jsou *.v2.f.jsetc. (Supondo que todas as suas versões de todo o seu gatilho http estejam ativas). Entre em contato se você tiver uma solução melhor.
— Krhitesh

1

Eu uso um carregador de inicialização JS vanilla para incluir automaticamente todas as funções que eu quero usar.

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

index.js (carregador de inicialização)

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

Este arquivo index.js de exemplo inclui apenas diretórios automaticamente na raiz. Poderia ser expandido para procurar diretórios, honrar .gitignore, etc. Isso foi o suficiente para mim.

Com o arquivo de índice no lugar, adicionar novas funções é trivial.

/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 rendimentos:

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

Esse fluxo de trabalho é basicamente "gravação e execução", sem a necessidade de modificar o arquivo index.js sempre que uma nova função / arquivo é adicionada / modificada / removida.


isso não será iniciado a frio?
— 21419 Ayyappa

1

Aqui está uma resposta simples se você estiver criando funções de nuvem com texto datilografado.

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

Perto de todas as suas importações regulares no topo, basta exportar todas as funções de foo.ts.

export * from './foo';


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.