Як структурувати хмарні функції для Firebase для розгортання декількох функцій з декількох файлів?


164

Я хотів би створити декілька хмарних функцій для Firebase і розгорнути їх все одночасно з одного проекту. Я також хотів би розділити кожну функцію в окремий файл. В даний час я можу створювати кілька функцій, якщо розміщувати їх як в 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
FYI, цей офіційний приклад функцій Firebase містить кілька .jsфайлів, імпортованих через require: github.com/firebase/functions-samples/tree/master/…
xanderiel

Це може бути корисно: stackoverflow.com/questions/43486278/…
Ramesh-X

Відповіді:


126

Ах, хмарні функції для модулів вузлів завантаження Firebase, як правило, так це працює

структура:

/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? Якщо так, то як це краще реалізувати?
Олександр Хітев

1
Я думаю, ви могли б і призначити різним обробникам різні експортовані функції від foo: export.bar = функции.database.ref ('/ foo'). OnWrite (fooModule.barHandler); export.baz = функции.database.ref ('/ bar'). onWrite (fooModule.bazHandler);
jasonsirota

44
Мені не подобається це рішення, оскільки воно переміщує інформацію (а саме шляхи до бази даних) з foo.js і bar.js в index.js, який перемагає сенс наявності цих окремих файлів.
bvs

Я погоджуюся з @bvs, я думаю, у Седа хороший підхід. Я збираюся трохи змінити його, явно експортуючи кожен модуль, щоб зробити index.ts надто зрозумілим, наприклад, експортувати {newUser} з "./authenticationFunctions"
Алан

2
Я думаю, що моє первісне питання було просто про розгортання декількох функцій з 1 проектом без розміщення функцій у файлі 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.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-function.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? :)
берслінг

@ selectpage-JekBao Вибачте, це минуло давно, я вже не маю цього проекту. Якщо я пам'ятаю правильно, ви можете надати конфігурації firebase каталог (який за замовчуванням є загальнодоступним). Я можу помилитися, хоча минуло більше року
Ced

Гей @ced - чому вміст не може db.tsзайти всередину main.ts(після інстанції адміністратора?). Або ви просто поділилися таким чином для ясності / простоти?
dsg38

1
@ dsg38 це було розміщено занадто давно, я не дуже розумію, чому це повинно бути в окремому файлі, дивлячись на відповідь зараз .. Я думаю, це було для наочності
Ced

21

З вузлом 8 LTS, який тепер доступний для функцій Cloud / Firebase, ви можете виконати наступні дії з операторами поширення:

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

Цікаво, чи зростаюча кількість імпорту сповільнює холодний початок кожної функції чи має бути багато повністю розрізнених модулів, розроблених окремо?
Саймон Факір

2
я отримую помилку розставання eslint unexpected token ...всередині index.js.
Томас

Можливо, ви не використовуєте Node 8
Luke Pighetti

@SimonFakir гарне запитання. Ви щось про це знайшли?
atereshkov

@atereshkov так. Я знайшов спосіб завантажити лише запитувану функцію, включаючи її залежності, використовуючи "process.env.FUNCTION_NAME", подібний до відповіді нижче. Я також можу поділитися своїм репо-репортажем, якщо ви зацікавлені, зв’яжіться зі мною.
Саймон Факір

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 та bar?
elprl

Гей - чому вміст не може db.tsзайти всередину index.ts(після інстанціїнгу адміністратора?). Або ви просто поділилися таким чином для ясності / простоти?
dsg38

@ dsg38 ви можете змішати все разом, це дає зрозуміти
Реза

10

У випадку з Babel / Flow це виглядатиме так:

Макет каталогу

.
├── /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 - Хмарний клієнт SQL для 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 - Клієнт 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 .

Архітектура проекту в цьому зразку така:

проектДіректорія

  • 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 підтримує Node 6.11, який не підтримує директиви щодо імпорту ES6?
Аод

Якщо ви використовуєте машинопис, проблема ніколи не повинна виникати. Останнім часом я перевів більшу частину свого коду в машинопис.
zaidfazil

2
Зайдфазіл, ймовірно, ви повинні зафіксувати будь-які передумови у своїй відповіді. @Aodh, це працює, якщо ти використовуєш Babel так само, як Константин окреслив у відповіді. stackoverflow.com/questions/43486278 / ...
PostureOfLearning

1
спасибі. це працювало з машинописом та вузлом 6 :)
Ахмад Муса

4
Замість імпорту та реекспорту з розпростертими операторами, не могли б ви просто export * from './fooFunctions';і export * from './barFunctions';в index.ts?
щозхатипат

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 . Це безкоштовно до певного моменту :) Перевірте це посилання .

./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 виявляє той, що знаходиться в підсумку, наприклад: відповідно до вашого коду він приймає лише module.exports.stripe = функции.https.onRequest (смуга);
ОК200

@ OK200, яка команда, яку ви використовуєте в командному рядку firebase? Щоб допомогти вам, мені потрібно переглянути якийсь код
ajorquera

3

Існує досить хороший спосіб організувати всі свої хмарні функції на тривалий термін. Я це робив недавно, і це працює бездоганно.

Що я зробив, було організувати кожну функцію хмари в окремі папки на основі кінцевої точки тригера. Кожне ім'я файлу функції хмари закінчується на *.f.js. Наприклад, якщо у вас були onCreateі onUpdateтригери, user/{userId}/document/{documentId}тоді створіть два файли onCreate.f.jsі onUpdate.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 тощо)
Олексій Сороколетов

Чому ви хочете зберігати різні версії хмарної функції під одним проектом? Хоча ви можете це зробити, змінивши структуру каталогів, за замовчуванням index.js розгорне всі хмарні функції, якщо ви не будете вибірково розгортатись або використовувати if-умови у своєму index.js, що в кінцевому підсумку в результаті завантажує ваш код
krhitesh

1
Я все добре розгортаю, просто хочу версії функцій, які я поставив (http викликали)
Олексій Сороколетов

Я очікую, що кожен тригер http має свій власний *.f.jsфайл. Найменше, що ви можете зробити - це перейменування файлу для кожної версії, попередньо додавши суфікс, щоб зробити його чимось подібним *.v1.f.jsчи *.v2.f.jsіншим. Будь ласка, дайте мені знати, чи є у вас краще рішення.
krhitesh

1

Я використовую завантажувач ванільного 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

Ось простий відповідь, якщо ви створюєте хмарні функції за допомогою typecript.

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

Біля всього вашого звичайного імпорту вгорі просто експортуйте всі функції з foo.ts.

export * from './foo';


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.