Апгрейд организации (Google)Firebase Cloud Functions

в 22:04, , рубрики: Google Cloud Platform

Предыстория

Однажды столкнулся с, казалось бы, небольшой проблемой — организация облачных функций Firebase. Уверен многие столкнулись с тем, что при создании некоего приложения мы обязаны создавать каждую функцию отдельно, а это фактически клонирование модулей Node.Js, особенно критично это в условиях большого приложения. Уверен, многим первой пришла мысль, создавать функции в отдельных файлах/каталогах и require`ить их в index.js.

Отличная идея… для медленного сервиса

Дело в том, что таким образом:

// index.js
exports.function1 = require('./function1.js');
exports.function2 = require('./function2.js');
exports.function3 = require('./function3.js');
etc.

Firebase при запуске одной функции будет инициализировать все что находится в index.js включая все зависимости внутри, а все это, естественно, занимает время. Согласитесь, в 2018 году никто не будет ждать загрузку страницы более 5 секунд. А учитывая так называемый "Cold start", инициализация будет проходить достаточно часто, что тоже неприемлемо.

Решение проблемы

Поискав немного информацию по этому вопросу вы наткнетесь на вот такой комментарий в GitHub:

Апгрейд организации (Google)Firebase Cloud Functions - 1

И поверьте, на сегодняшний день этот простой цикл — лучшее решение данной проблемы.

С помощью его и индексовый файл будет чист, и будет единое соглашение об имени файла (camelCase в данном случае), а это особенно полезно при работе в команде. Так же Firebase будет инициализировать только нужную функцию перед её исполнением.

Но есть ещё одна проблема: Google Cloud Platform (GCP) осуществляет запуск кода только в среде Node.Js v6, что лишает нас async/await и подобных, а все таки Node.js v8 уже имеет статус LTS.

Моё решение состоит в использовании транскомпилятора Babel, но код вовсе не обязательно транскомпилировать перед деплоем! Оказалось, что GCP поддерживает транскомпиляцию "на лету". То есть, используя опыт зарубежных коллег, мы чуть изменим этот цикл:

//index.js
const glob = require("glob");
const camelCase = require("camelcase");

// Настройка babel
require("babel-register")({
  ignore: './node_modules',
  extensions: [ ".js"],
  cache: true,
});

const files = glob.sync('./**/*.f.js', { cwd: __dirname, ignore: './node_modules/**' });

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

Вывод

Таким образом мы имеет удобную организацию кода с соглашением об именах и поддержкой функциональных особенностей Node.Js v8 и выше.

Удачи в познаниях.

Автор: Валера

Источник

Поделиться

* - обязательные к заполнению поля