Làm cách nào để cấu trúc các Hàm đám mây cho Firebase để triển khai nhiều chức năng từ nhiều tệp?


164

Tôi muốn tạo nhiều Hàm đám mây cho Firebase và triển khai tất cả chúng cùng một lúc từ một dự án. Tôi cũng muốn tách từng chức năng thành một tệp riêng biệt. Hiện tại tôi có thể tạo nhiều hàm nếu tôi đặt cả hai trong index.js, chẳng hạn như:

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

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

Tuy nhiên tôi muốn đặt foo và bar trong các tệp riêng biệt. Tôi đã thử điều này:

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

trong đó foo.js là

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

và bar.js là

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

Có cách nào để thực hiện điều này mà không cần đặt tất cả các hàm trong index.js không?


1
@JPVentura. Thực sự không hiểu bạn lắm. Vui lòng giải thích.
HuyLe

Điều này đã được cập nhật cho v1.0? Tôi đang gặp sự cố: stackoverflow.com/questions/50089807/ từ
tccpg288

2
FYI, ví dụ về các hàm Firebase chính thức này chứa một số .jstệp được nhập thông qua require: github.com/firebase/fifts-samples/tree/master/
mẹo

Điều này có thể hữu ích: stackoverflow.com/questions/43486278/ từ
Ramesh-X

Câu trả lời:


126

À, Chức năng đám mây cho các mô-đun nút tải Firebase bình thường, vì vậy điều này hoạt động

kết cấu:

/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
Tôi có thể ví dụ có một số chức năng trong mô-đun foo? Nếu vậy, làm thế nào là tốt hơn để thực hiện nó?
Alexander Khitev

1
Tôi cho rằng bạn có thể và gán các trình xử lý khác nhau cho các hàm xuất khác nhau từ foo: export.bar = tests.database.ref ('/ foo'). OnWrite (fooModule.barHandler); export.baz = tests.database.ref ('/ bar'). onWrite (fooModule.bazHandler);
jasonsirota

44
Tôi không thích giải pháp này vì nó chuyển thông tin (cụ thể là đường dẫn cơ sở dữ liệu) từ foo.js và bar.js sang index.js, loại nào đánh bại điểm có các tệp riêng biệt đó.
bvs

Tôi đồng ý với @bvs, tôi nghĩ Ced có cách tiếp cận tốt. Tôi sẽ sửa đổi nó một chút bằng cách xuất rõ ràng từng mô-đun để làm cho index.ts siêu rõ ràng, ví dụ như xuất {newUser} từ "./authenticationFifts"
Alan

2
Tôi nghĩ rằng câu hỏi ban đầu của tôi chỉ đơn giản là về việc triển khai nhiều hàm với 1 dự án mà không đưa các hàm vào tệp index.js, nơi bạn chuyển thông tin cơ sở dữ liệu không nằm trong phạm vi. Với tôi, có lẽ tôi sẽ tạo một mô-đun riêng điều khiển truy cập cơ sở dữ liệu và yêu cầu nó trong foo.js và bar.js riêng biệt, nhưng đó là một quyết định theo phong cách.
jasonsirota

75

Câu trả lời của @jasonsirota rất hữu ích. Nhưng nó có thể hữu ích để xem mã chi tiết hơn, đặc biệt là trong trường hợp các hàm được kích hoạt HTTP.

Sử dụng cùng cấu trúc như trong câu trả lời của @ jasonsirota, giả sử bạn muốn có hai hàm kích hoạt HTTP riêng biệt trong hai tệp khác nhau:

Cấu trúc thư mục:

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

Cấu trúc hiện tại trong index.js không phù hợp với tôi. Điều tôi phải làm là trước tiên nhập các mô-đun firebase, sau đó khởi tạo ứng dụng và sau đó nhập các chức năng từ các thư mục khác. Bằng cách đó, ứng dụng của tôi trước tiên khởi tạo, xác thực, bất cứ điều gì và sau đó nhập các chức năng cần ứng dụng được khởi tạo trước.
tonkatata

47

Cập nhật: Tài liệu này sẽ giúp , câu trả lời của tôi cũ hơn tài liệu này.


Đây là cách tôi cá nhân đã làm nó với bản thảo:

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

Hãy để tôi mở đầu điều này bằng cách đưa ra hai cảnh báo để thực hiện công việc này:

  1. thứ tự xuất / nhập vấn đề trong index.ts
  2. db phải là một tệp riêng biệt

Đối với điểm số 2 tôi không chắc tại sao. Secundo bạn nên tôn trọng chính xác cấu hình của tôi về chỉ mục, chính và db (ít nhất là để dùng thử).

index.ts : giao dịch với xuất khẩu. Tôi thấy nó sạch hơn để cho index.ts đối phó với xuất khẩu.

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

main.ts : Thỏa thuận với khởi tạo.

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

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

db.ts : chỉ cần xem lại db để tên của nó ngắn hơndatabase()

import { database } from "firebase-admin";

export const db = database();

http-Hàm.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 của bạn trông như thế nào? làm cách nào tôi có thể biên dịch vào một thư mục dist và cho các hàm gcloud biết index.js của tôi ở đâu? Bạn có mã của bạn trên github? :)
phiền

@ choopage-Jekbao xin lỗi đã lâu rồi, tôi không có dự án nữa. Nếu tôi nhớ chính xác, bạn có thể cung cấp cho cấu hình firebase một thư mục (mặc định là công khai). Tôi có thể sai mặc dù đã hơn một năm
Ced

Hey @ced - tại sao nội dung không thể db.tsvào bên trong main.ts(sau khi khởi tạo quản trị viên?). Hoặc bạn đã tách ra theo cách này cho rõ ràng / đơn giản?
dsg38

1
@ dsg38 điều này đã được đăng cách đây quá lâu, tôi thực sự không hiểu tại sao nó nên ở trong một tệp riêng biệt để xem câu trả lời ngay bây giờ .. Tôi nghĩ rằng nó là cho rõ ràng
Ced

21

Với Node 8 LTS hiện có sẵn với Chức năng Cloud / Firebase, bạn có thể thực hiện các thao tác sau với toán tử trải rộng:

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

Tôi tự hỏi nếu số lượng nhập khẩu ngày càng tăng làm chậm sự khởi đầu lạnh của từng chức năng hoặc nếu có nhiều mô-đun tách biệt hoàn toàn được phát triển riêng biệt?
Simon Fakir

2
tôi nhận được một lỗi chia phần eslint unexpected token ...bên trong index.js.
thomas

Có lẽ bạn không sử dụng Nút 8
Luke Pighetti

@SimonFakir câu hỏi hay. Bạn đã tìm thấy một cái gì đó về nó?
atereshkov

@atereshkov có Tôi đã tìm được cách chỉ tải chức năng được yêu cầu bao gồm cả phụ thuộc của nó bằng cách sử dụng "process.env.FUNCTION_NAME" tương tự như câu trả lời bên dưới. Tôi cũng có thể chia sẻ repo của tôi làm tài liệu tham khảo nếu bạn đang liên lạc với tôi.
Simon Fakir

15

Để được đơn giản (nhưng thực hiện công việc), cá nhân tôi đã cấu trúc mã của mình như thế này.

Bố trí

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

thanh.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();

chỉ số

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

Hoạt động cho các thư mục của bất kỳ cấp độ lồng nhau. Chỉ cần làm theo mô hình bên trong các thư mục quá.

tín dụng cho câu trả lời @zaidfazil


1
Đây là một trong những câu trả lời đơn giản nhất cho Typecript, cảm ơn. Làm thế nào để bạn đối phó với một khởi tạo duy nhất của cơ sở dữ liệu căn cứ hỏa lực chẳng hạn? admin.initializeApp(functions.config().firestore) const db = admin.firestore();Bạn đặt cái này ở đâu và làm thế nào để bạn đề cập đến nó trong foo và bar?
elprl

Hey - tại sao nội dung không thể db.tsvào bên trong index.ts(sau khi khởi tạo quản trị viên?). Hoặc bạn đã tách ra theo cách này cho rõ ràng / đơn giản?
dsg38

@ dsg38 bạn có thể kết hợp tất cả lại với nhau, điều này làm cho nó rõ ràng
Reza

10

Trong trường hợp với Babel / Flow, nó sẽ trông như thế này:

Giao diện thư mục

.
├── /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 - Xuất khẩu chính

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


src/db.js - Ứng dụng khách đám mây SQL cho 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 Client

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

firebase.initializeApp(config().firebase);

export default firebase.firestore();


src/someFuncA.js - Chức năng 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 - Chức năng 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 phác thảo một mẫu kiến ​​trúc đơn giản hơn để có các phương thức được tách thành các tệp khác nhau và được xuất thành một dòng trong index.js .

Kiến trúc cho dự án trong mẫu này là như sau:

dự án

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

Mẫu tương tự sẽ được sử dụng cho removeProfilephương thức trong tệp hồ sơ .


7

Để được đơn giản (nhưng thực hiện công việc), cá nhân tôi đã cấu trúc mã của mình như thế này.

Bố trí

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

thanh.ts

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

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

chỉ số

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

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

Hoạt động cho các thư mục của bất kỳ cấp độ lồng nhau. Chỉ cần làm theo mô hình bên trong các thư mục quá.


Tôi không thể thấy làm thế nào điều này có thể hoạt động vì Firebase hỗ trợ Node 6.11 hiện không hỗ trợ các chỉ thị nhập ES6?
Aodh

Nếu bạn đang sử dụng bản in, vấn đề sẽ không bao giờ phát sinh. Gần đây tôi đã chuyển phần lớn mã của mình thành bản thảo.
zaidfazil

2
zaidfazil, có lẽ bạn nên ghi lại bất kỳ điều kiện tiên quyết nào trong câu trả lời của bạn. @Aodh, nó hoạt động nếu bạn sử dụng Babel giống như cách Konstantin đã nêu trong một câu trả lời. stackoverflow.com/questions/43486278/
Mạnh

1
cảm ơn bạn. cái này hoạt động với bản in và nút 6 :)
Ahmad Moussa

4
Thay vì nhập và tái xuất với các toán tử trải rộng, bạn không thể có export * from './fooFunctions';export * from './barFunctions';trong index.ts?
whatsthatitspat

5

Định dạng này cho phép điểm nhập của bạn tự động tìm các tệp chức năng và xuất từng chức năng trong mỗi tệp.

Kịch bản điểm chính

Tìm tất cả các tệp .js bên trong thư mục hàm và xuất từng hàm được xuất từ ​​mỗi tệp.

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

Ví dụ Xuất nhiều hàm từ một tệp

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 điểm cuối có thể truy cập được đặt tên thích hợp

✔ 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

Một tập tin

Nếu bạn chỉ có một vài tệp bổ sung (ví dụ: chỉ một), bạn có thể sử dụng:

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

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


Điều này có quá tải khi khởi động cho mọi trường hợp chức năng tăng lên không?
Ayyappa

4

Vì vậy, tôi có dự án này có chức năng nền và chức năng http. Tôi cũng có bài kiểm tra để kiểm tra đơn vị. CI / CD sẽ giúp cuộc sống của bạn dễ dàng hơn nhiều khi triển khai các chức năng đám mây

Cấu trúc thư mục

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

Lưu ý: utils/ thư mục dành cho mã chia sẻ giữa các chức năng

Hàm / index.js

Tại đây bạn chỉ có thể nhập tất cả các chức năng bạn cần và khai báo chúng. Không cần phải có logic ở đây. Nó làm cho nó sạch hơn theo ý kiến ​​của tôi.

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

Làm thế nào về việc có liên tục tích hợp và triển khai mỗi khi bạn đẩy các thay đổi của mình lên repo? Bạn có thể có nó bằng cách sử dụng google google cloud build . Nó miễn phí cho đến khi điểm nhất định :) Kiểm tra liên kết này .

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

Tôi đã xuất như bạn đã nói nhưng việc triển khai firebase phát hiện cái cuối cùng, ví dụ: theo mã của bạn, nó chỉ mất module.exports.stripe = Hàm.https.onRequest (sọc);
OK200

@ OK200 Lệnh bạn đang sử dụng với dòng lệnh firebase là gì? Để giúp bạn, tôi sẽ cần xem một số mã
ajorquera

3

Có một cách khá hay để tổ chức tất cả các chức năng đám mây của bạn trong thời gian dài. Tôi đã làm điều này gần đây và nó đang hoạt động hoàn hảo.

Những gì tôi đã làm là tổ chức từng chức năng đám mây trong các thư mục riêng dựa trên điểm cuối kích hoạt của chúng. Mỗi tên tệp hàm đám mây kết thúc bằng *.f.js. Ví dụ: nếu bạn có onCreateonUpdatekích hoạt user/{userId}/document/{documentId}thì tạo hai tệp onCreate.f.jsonUpdate.f.jstrong thư mục functions/user/document/và chức năng của bạn sẽ được đặt tên userDocumentOnCreateuserDocumentOnUpdate tương ứng. (1)

Đây là một cấu trúc thư mục mẫu:

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

Chức năng mẫu

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): Bạn có thể sử dụng bất kỳ tên nào bạn muốn. Đối với tôi, onCreate.f.js, onUpdate.f.js, v.v ... có vẻ phù hợp hơn với loại trình kích hoạt.


1
Cách tiếp cận này thực sự tốt đẹp. Tôi đã tự hỏi liệu có thể điều chỉnh để cho phép dấu gạch chéo trong tên hàm để bạn có thể tách các phiên bản api khác nhau không, ví dụ (api v1, api v2, v.v.)
Alex Sorokoletov

Tại sao bạn muốn giữ các phiên bản khác nhau của chức năng đám mây trong cùng một dự án? Mặc dù bạn có thể làm điều đó bằng cách thay đổi một chút cấu trúc thư mục, theo mặc định index.js sẽ triển khai tất cả các hàm đám mây trừ khi bạn triển khai có chọn lọc hoặc sử dụng if-condition trong index.js cuối cùng sẽ làm lộn xộn mã của bạn
krhitesh

1
Tôi ổn với việc triển khai mọi thứ, tôi chỉ muốn phiên bản các chức năng mà tôi đặt (http kích hoạt các chức năng)
Alex Sorokoletov

Tôi hy vọng rằng mọi trình kích hoạt http đều nằm trong *.f.jstệp riêng của nó . Ít nhất bạn có thể làm là đổi tên tệp cho mọi phiên bản bằng cách thêm vào hậu tố để làm cho nó giống như *.v1.f.jshoặc *.v2.f.jsvv (Giả sử tất cả các phiên bản của tất cả trình kích hoạt http của bạn đều hoạt động). Xin vui lòng cho tôi biết nếu bạn có một giải pháp tốt hơn.
krhitesh

1

Tôi sử dụng bộ tải khởi động JS vanilla để tự động bao gồm tất cả các chức năng tôi muốn sử dụng.

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

index.js (bộ nạp khởi động)

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

Ví dụ này tệp index.js chỉ bao gồm các thư mục tự động trong thư mục gốc. Nó có thể được mở rộng để đi bộ thư mục, Honor .gitignore, vv Điều này là đủ cho tôi mặc dù.

Với tệp chỉ mục tại chỗ, việc thêm các chức năng mới là chuyện nhỏ.

/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 sản lượng:

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

Quy trình công việc này khá nhiều chỉ là "ghi và chạy", mà không phải sửa đổi tệp index.js mỗi khi một chức năng / tệp mới được thêm / sửa đổi / loại bỏ.


Điều này sẽ không có khi bắt đầu lạnh?
Ayyappa

1

Đây là một câu trả lời đơn giản nếu bạn đang tạo các hàm đám mây với bản in.

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

Gần tất cả hàng nhập thường xuyên của bạn ở đầu chỉ cần xuất tất cả các chức năng từ foo.ts.

export * from './foo';


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.