george43g / better-firebase-functions

This repo provides functionality for a better way of organising files, imports and function triggers in Firebase Cloud Functions
Mozilla Public License 2.0
179 stars 15 forks source link

In Node 10+ `FUNCTION_NAME` is replaced with` K_SERVICE`? #7

Closed alexpchin closed 4 years ago

alexpchin commented 4 years ago

As per https://stackoverflow.com/questions/42726870/firebase-cloud-functions-is-very-slow

Does this library currently take into consideration:

in Node 10+ FUNCTION_NAME is replaced withK_SERVICE (FUNCTION_TARGET is the function itself, not its name, replacing ENTRY_POINT).

const function_name = process.env.FUNCTION_NAME || process.env.K_SERVICE;

george43g commented 4 years ago

I'm actually very surprised by this. I've tested extensively (developed on even) Node 10.15.3 and never had to use any of those environment variables.

I hope updating this won't break anything older - I believe Node10 is still in beta and opt-in.

I will post again when I have the update published - do you have any other feature requests or suggestions?

alexpchin commented 4 years ago

Hi @george43g

I've been looking into this more today. I "rolled my own":

const glob = require('glob');
const { set } = require('lodash');
const camelCase = require('camelcase');

const functionDirectory = 'api';
const files = glob.sync(`./${functionDirectory}/**/!(*.test).js`, {
  cwd: __dirname,
});
const coldStartMsg = '[Optimized] Load Module (Cold-Start)';

// https://cloud.google.com/functions/docs/env-var
const requestedFuncName = () =>
  process.env.FUNCTION_NAME || process.env.K_SERVICE;
const isDeploying = () => !requestedFuncName();
const isBeingCalled = (f) => f === requestedFuncName();
const extractFunc = (func) => func;

for (const file of files) {
  // Strip off '.js', remove functionDirectory, allow nested and camelCase
  const nameToExport = camelCase(
    file.slice(0, -3).replace(`${functionDirectory}/`, '').split('/').join('_'),
  );

  // When deploying a specific function, i.e. `firebase deploy --only functions:activitiesIndex`
  // `isDeploying()` is be false
  // `isBeingCalled(nameToExport)` is be true
  //
  // When deployig all functions, i.e. `firebase deploy`
  // `isDeploying()` will be false
  // `isBeingCalled(nameToExport)` will be true
  if (isDeploying() || isBeingCalled(nameToExport)) {
    if (!isDeploying()) console.time(coldStartMsg);
    let funcToExport;
    try {
      // Use eval due to webpack
      const funcToRequire = eval('require')(file);
      funcToExport = extractFunc(funcToRequire);
    } catch (e) {
      console.error(e);
      continue;
    }
    if (!isDeploying()) console.timeEnd(coldStartMsg);
    // Logging
    console.log('function name Node 8', process.env.FUNCTION_NAME);
    console.log('function name Node 10', process.env.K_SERVICE);
    console.log('file', file);
    console.log('funcName', requestedFuncName());
    console.log('nameToExport', nameToExport);
    console.log('isDeploying()', String(isDeploying()));
    console.log(
      'isBeingCalled(nameToExport)',
      String(isBeingCalled(nameToExport)),
    );
    set(exports, nameToExport, funcToExport);
  }
}

And it does appear that function name Node 8 does now give undefined.

I also can't see a case where process.env.K_SERVICE is not defined? In your code, you have isDeployment(). When was this originally designed to return true? Do you remember?

Thanks

george43g commented 4 years ago

:tada: This issue has been resolved in version 3.3.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

george43g commented 4 years ago

:tada: This issue has been resolved in version 3.3.2 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

george43g commented 4 years ago

The K_SERVICE or FUNCTION_NAME is not defined when the firebase CLI is deploying the functions. Once on the server, I believe it's always defined.

I really like the extra logging you wrote. I'll hopefully include something like that in a future release.

I also really want to look into more features for users in GCP. Any ideas on how to make this more useful are appreciated.

alexpchin commented 4 years ago

@george43g Nice one. I’ll checkout the new version.

I still face issues with Cold Boots on Cloud Functions, it’s so frustrating... I think it’s the first connection to Firestone so Cold Boot rather than Cold Start. It is doing my head in...

EFFB88CF-C125-44FA-9626-C811D3145CBF