Optimizing Firebase cloud functions structure in node.js - javascript

In this official Firebase example it's described how to structure cloud functions to minimize cold start times.
The main idea seems to be the following in the index.ts file:
export const httpFn =
functions.https.onRequest(async (request, response) => {
await (await import('./fn/httpFn')).default(request, response)
})
In other words using await( await import()). This example is however in typescript. How would this look in node.js? I've found some examples. Eg. this one.
In there the index.js file has:
exports.helloWorld = require('./hello-world').helloWorld
And the individual function files look like:
const functions = require('firebase-functions')
exports.helloWorld = functions.https.onRequest((request, response) => {
const output = {
di: 'is cool',
}
response.send(output)
})
Is this the optimal method to minimize cold start time in node.js? Given I can't use "await import". Will this structure only load the necessary dependencies for each individual function? Or will it still load all dependencies across all required (imported) files?

That blog post you're referring to is not an "official sample". It's a description of my own personal thoughts and opinions.
What you're showing here is not equivalent to what's shown in the blog post. If you want a pure JavaScript implementation of TypeScript's async import, you will have to write code to mimic that. require() is not asynchronous and doesn't achieve the same thing.
I suggest reading other questions on Stack Overflow on this topic:
Node.js - asynchronous module loading
How to async require in nodejs

Related

Export a Monkey Patch library and Import it into a separate file in Javascript

I'm working in WebDriverIO w/Mocha, and there's some monkey patches I've written to make my code easier to read. Things like:
Object.prototype.findEntries(...arr) for getting a subset of Object.entries(),
String.prototype.padding(int), adding spacing to the right of a string,
Array.prototype.sortByKey(key) to sort an array of similar objects by the value of a common key, and
Array.prototype.last(), the classic.
Since I have many spec files with even more tests, I'd like to have a MonkeyPatchLib.js in my project that I can import into my spec files, so I can call these custom functions when needed:
myTest.js:
import { all } from './MonkeyPatchLib.js' // <- line in question
describe('My First Spec File', async() => {
it('First Test', async() => {
let myArr=[1,2,3]
console.log(myArr.last())
})
})
I've screwed around with module.exports=[func1(){...},func2(){...}] to no avail. I'm aware that I can simply create custom classes (a la the solution to this question) and export those, but that would require an annoying refactor of my codebase. How should I format the library, and how would one import said library?

Firebase functions - multiple js files to organize functions

I have a folder named functions, inside there is index.js.
On index.js I have the main function that accept all http :
exports.contentServer = functions.https.onRequest((request, response) => {
Since I have many more functions I need to organize my files, and I want to add another file, say payments.js, so that index.js can call functions inside payments.js, or even onCreate callbacks will be fired from payment.js.
If I just create another js file in functions, it won't work.
What has to be done to be able to have a single Cloud Function in another new js file ?
You can use a standard nodejs require to load code in other files.
index.js
const otherFunctions = require('./other.js');
exports.contentServer = functions.https.onRequest((request, response) => {
otherFunctions.other()
}
other.js
exports.other = function() { ... }
I suggest reading the documentation for more information.

Jest mocking module implementation with .mockImplemetation

Can anyone help here. I am really frustrated with how the mockImplementation works.
So, first of all I am using jest for node testing. I am using the commonjs modules. what I wanna do is that I am trying to mock a module using mockImplementation() and change its implementation between different tests according to this documentation here: https://jestjs.io/docs/en/es6-class-mocks#replacing-the-mock-using-mockimplementation-docs-en-mock-function-api-mockfnmockimplementationfn-or-mockimplementationonce-docs-en-mock-function-api-mockfnmockimplementationoncefn.
My code look like this:
const exportBigQueryTableModule =require('../repository/exportBigQueryTable')
jest.mock('../repository/exportBigQueryTable')
describe('deleting files on table export fail', () => {
mockExportBigQueryTable = jest
.fn(() => Promise.resolve())
.mockResolvedValueOnce()
.mockRejectedValueOnce(new Error('Could not export table'))
exportBigQueryTableModule.mockImplementation(mockExportBigQueryTable)
it(' should do some test', () => {})
})
The problem here is that looks like that this line jest.mock('../repository/exportBigQueryTable') create for me a default mock kind of jest.fn() and the module is always loaded with that default function. So the mock function that I did provide on the test using the mockImplementation never overrides the previous one, I do not get what is the problem here. Why the same exmaple on the official documentation works the only difference is that it uses es6 modules on the doc sample.
I am not sure if I am missing something here.

Getting ReferenceError: fetch is not defined

In my Saga test for my react native application (that does work correctly) I have added the following test that calls a function that perform a POST http call (doScan).
describe('Scan the product and register the scanning action', () => {
const it = sagaHelper(scanProductSaga(scanProductAction(item)));
it('logscan via ASL', (result) => {
expect(result).toEqual(cps(ASLogger.logScan, xxx));
return logScanResult;
});
it('should register the product', (result) => {
expect(result).toEqual(call(doScan, logScanResult));
});
});
Separate file:
const doScan = scanObj =>
toJSON(fetch('https://xxxx.xxxxxx.com/logger/scans', {
method: 'POST',
headers: new Headers(CONTENT_TYPE_HEADERS),
body: JSON.stringify(scanObj),
}));
Note: the fetch function is from 'react-native-interfaces.js' within the react-native library. The test fails and the error is caused by the following exception :
ReferenceError: fetch is not defined
at doScan (/Users/andy/WebstormProjects/ASAP/api/index.js:81:11)....
What can cause such issue? What the solution may be?
react-native has fetch default, but test environment on node.js does not have fetch.
You can import fetch like following at the top of test code.
const fetch = require('node-fetch')
The file react-native-interface.js only declare the type of fetch.
declare var fetch: any;
For some cases, in a universal application for both, client and server the maintainers have to use isomorphic-fetch module to their Node project because of Node does not contain Fetch API yet. For more information read this question and answer
But in this special case, hence, React Native, it is some different, Because, in the mobile device area, there is no V8, SpiderMonkey or Node. There is JavaScriptCore. So, for this new situation should be used react-native-fetch.
It is a little different, install it with below code:
npm install react-native-fetch
And then, use it like a JSX component:
import Fetch from 'react-native-fetch'
...
<Fetch
url="https://jsonplaceholder.typicode.com/posts/1"
retries={3}
timeout={3000}
onResponse={async (res) => {
const json = await res.json()
console.log(json)
}}
onError={console.error}
/>
It's so new, but lovely.

Facebook Messenger Bot: Understanding Syntax

I am trying to learn how to create a facebook Bot.
I found this amazing article on Medium which illustrates how we can create a messenger bot
In this article, The author tells us to create a verification.js. file inside controllers/verification.js. and paste the following code in it.
module.exports = (req, res) => {
const hubChallenge = req.query[‘hub.challenge’];
const hubMode = req.query[‘hub.mode’];
const verifyTokenMatches = (req.query[‘hub.verify_token’] === ‘crowdbotics’);
if (hubMode && verifyTokenMatches) {
res.status(200).send(hubChallenge);
} else {
res.status(403).end();
}
};
Now, before trying to figure out what this code does (which she have explained), I am unable to understand why haven't she included any dependencies (precisely express) in this Node.Js file?
[Update] Can someone also please explain me in length what does the above code do?
Since this code looks like NodeJS code, Shouldn't she add something like
var express = require("express");
var app = express();
and do module.exports after?
To summarise the comments under the question:
You must import modules only if you need it. That chunk of code simply exports a function that can be used in any other module by importing it.
The author's just exporting an anonymous es6 arrow function, which is totally legit. It can be imported as
import * as whateverYouNameIt from 'controllers/verification';
or
let func = require('controllers/verification');
Have a look at arrow functions and node.js module exports

Categories